@spoosh/core 0.4.3 → 0.6.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/README.md +41 -47
- package/dist/index.d.mts +389 -255
- package/dist/index.d.ts +389 -255
- package/dist/index.js +90 -114
- package/dist/index.mjs +90 -114
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
HTTP_METHODS: () =>
|
|
23
|
+
HTTP_METHODS: () => HTTP_METHODS,
|
|
24
24
|
Spoosh: () => Spoosh,
|
|
25
25
|
applyMiddlewares: () => applyMiddlewares,
|
|
26
26
|
buildUrl: () => buildUrl,
|
|
@@ -41,6 +41,7 @@ __export(src_exports, {
|
|
|
41
41
|
extractMethodFromSelector: () => extractMethodFromSelector,
|
|
42
42
|
extractPathFromSelector: () => extractPathFromSelector,
|
|
43
43
|
generateTags: () => generateTags,
|
|
44
|
+
getContentType: () => getContentType,
|
|
44
45
|
isJsonBody: () => isJsonBody,
|
|
45
46
|
mergeHeaders: () => mergeHeaders,
|
|
46
47
|
objectToFormData: () => objectToFormData,
|
|
@@ -167,6 +168,11 @@ function setHeaders(requestOptions, newHeaders) {
|
|
|
167
168
|
};
|
|
168
169
|
}
|
|
169
170
|
}
|
|
171
|
+
function getContentType(headers) {
|
|
172
|
+
if (!headers) return void 0;
|
|
173
|
+
const headersObj = new Headers(headers);
|
|
174
|
+
return headersObj.get("content-type") ?? void 0;
|
|
175
|
+
}
|
|
170
176
|
|
|
171
177
|
// src/utils/objectToFormData.ts
|
|
172
178
|
function objectToFormData(obj) {
|
|
@@ -302,12 +308,6 @@ function buildInputFields(requestOptions) {
|
|
|
302
308
|
if (requestOptions?.body !== void 0) {
|
|
303
309
|
fields.body = requestOptions.body;
|
|
304
310
|
}
|
|
305
|
-
if (requestOptions?.formData !== void 0) {
|
|
306
|
-
fields.formData = requestOptions.formData;
|
|
307
|
-
}
|
|
308
|
-
if (requestOptions?.urlEncoded !== void 0) {
|
|
309
|
-
fields.urlEncoded = requestOptions.urlEncoded;
|
|
310
|
-
}
|
|
311
311
|
if (requestOptions?.params !== void 0) {
|
|
312
312
|
fields.params = requestOptions.params;
|
|
313
313
|
}
|
|
@@ -336,7 +336,7 @@ async function executeCoreFetch(config) {
|
|
|
336
336
|
const maxRetries = requestOptions?.retries ?? 3;
|
|
337
337
|
const baseDelay = requestOptions?.retryDelay ?? 1e3;
|
|
338
338
|
const retryCount = maxRetries === false ? 0 : maxRetries;
|
|
339
|
-
const finalPath =
|
|
339
|
+
const finalPath = path;
|
|
340
340
|
const url = buildUrl(baseUrl, finalPath, requestOptions?.query);
|
|
341
341
|
let headers = await mergeHeaders(defaultHeaders, requestOptions?.headers);
|
|
342
342
|
const fetchInit = {
|
|
@@ -361,22 +361,17 @@ async function executeCoreFetch(config) {
|
|
|
361
361
|
if (requestOptions?.signal) {
|
|
362
362
|
fetchInit.signal = requestOptions.signal;
|
|
363
363
|
}
|
|
364
|
-
if (requestOptions?.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
})
|
|
375
|
-
if (headers) {
|
|
376
|
-
fetchInit.headers = headers;
|
|
377
|
-
}
|
|
378
|
-
} else if (requestOptions?.body !== void 0) {
|
|
379
|
-
if (isJsonBody(requestOptions.body)) {
|
|
364
|
+
if (requestOptions?.body !== void 0) {
|
|
365
|
+
const contentType = getContentType(headers);
|
|
366
|
+
if (contentType?.includes("application/x-www-form-urlencoded")) {
|
|
367
|
+
fetchInit.body = objectToUrlEncoded(
|
|
368
|
+
requestOptions.body
|
|
369
|
+
);
|
|
370
|
+
} else if (contentType?.includes("multipart/form-data") || containsFile(requestOptions.body)) {
|
|
371
|
+
fetchInit.body = objectToFormData(
|
|
372
|
+
requestOptions.body
|
|
373
|
+
);
|
|
374
|
+
} else if (isJsonBody(requestOptions.body)) {
|
|
380
375
|
fetchInit.body = JSON.stringify(requestOptions.body);
|
|
381
376
|
headers = await mergeHeaders(headers, {
|
|
382
377
|
"Content-Type": "application/json"
|
|
@@ -384,10 +379,6 @@ async function executeCoreFetch(config) {
|
|
|
384
379
|
if (headers) {
|
|
385
380
|
fetchInit.headers = headers;
|
|
386
381
|
}
|
|
387
|
-
} else if (containsFile(requestOptions.body)) {
|
|
388
|
-
fetchInit.body = objectToFormData(
|
|
389
|
-
requestOptions.body
|
|
390
|
-
);
|
|
391
382
|
} else {
|
|
392
383
|
fetchInit.body = requestOptions.body;
|
|
393
384
|
}
|
|
@@ -440,104 +431,89 @@ async function executeCoreFetch(config) {
|
|
|
440
431
|
}
|
|
441
432
|
|
|
442
433
|
// src/proxy/handler.ts
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
434
|
+
function resolvePath2(path, params) {
|
|
435
|
+
const segments = path.split("/").filter(Boolean);
|
|
436
|
+
if (!params) {
|
|
437
|
+
return segments;
|
|
438
|
+
}
|
|
439
|
+
return segments.map((segment) => {
|
|
440
|
+
if (segment.startsWith(":")) {
|
|
441
|
+
const paramName = segment.slice(1);
|
|
442
|
+
const value = params[paramName];
|
|
443
|
+
return value !== void 0 ? String(value) : segment;
|
|
444
|
+
}
|
|
445
|
+
return segment;
|
|
446
|
+
});
|
|
447
|
+
}
|
|
450
448
|
function createProxyHandler(config) {
|
|
451
449
|
const {
|
|
452
450
|
baseUrl,
|
|
453
451
|
defaultOptions,
|
|
454
|
-
path = [],
|
|
455
452
|
fetchExecutor = executeFetch,
|
|
456
453
|
nextTags
|
|
457
454
|
} = config;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
options
|
|
469
|
-
|
|
470
|
-
|
|
455
|
+
return ((path) => {
|
|
456
|
+
return new Proxy(
|
|
457
|
+
{},
|
|
458
|
+
{
|
|
459
|
+
get(_target, prop) {
|
|
460
|
+
if (typeof prop === "symbol") return void 0;
|
|
461
|
+
const method = prop;
|
|
462
|
+
if (!["GET", "POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
463
|
+
return void 0;
|
|
464
|
+
}
|
|
465
|
+
return (options) => {
|
|
466
|
+
const resolvedPath = resolvePath2(path, options?.params);
|
|
467
|
+
return fetchExecutor(
|
|
468
|
+
baseUrl,
|
|
469
|
+
resolvedPath,
|
|
470
|
+
method,
|
|
471
|
+
defaultOptions,
|
|
472
|
+
options,
|
|
473
|
+
nextTags
|
|
474
|
+
);
|
|
475
|
+
};
|
|
476
|
+
}
|
|
471
477
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
defaultOptions,
|
|
475
|
-
path: [...path, prop],
|
|
476
|
-
fetchExecutor,
|
|
477
|
-
nextTags
|
|
478
|
-
});
|
|
479
|
-
},
|
|
480
|
-
// Handles function call syntax for dynamic segments: api.posts(123), api.posts(":id"), api.users(userId)
|
|
481
|
-
// This is the only way to access dynamic segments in Spoosh.
|
|
482
|
-
// The function call syntax allows TypeScript to capture the literal type, enabling params: { id: string } inference.
|
|
483
|
-
apply(_target, _thisArg, args) {
|
|
484
|
-
const [segment] = args;
|
|
485
|
-
return createProxyHandler({
|
|
486
|
-
baseUrl,
|
|
487
|
-
defaultOptions,
|
|
488
|
-
path: [...path, segment],
|
|
489
|
-
fetchExecutor,
|
|
490
|
-
nextTags
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
};
|
|
494
|
-
const noop = () => {
|
|
495
|
-
};
|
|
496
|
-
return new Proxy(noop, handler);
|
|
478
|
+
);
|
|
479
|
+
});
|
|
497
480
|
}
|
|
498
481
|
|
|
499
482
|
// src/proxy/selector-proxy.ts
|
|
500
|
-
var
|
|
501
|
-
"$get",
|
|
502
|
-
"$post",
|
|
503
|
-
"$put",
|
|
504
|
-
"$patch",
|
|
505
|
-
"$delete"
|
|
506
|
-
];
|
|
483
|
+
var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
507
484
|
function createSelectorProxy(onCapture) {
|
|
508
|
-
const
|
|
509
|
-
return new Proxy(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
485
|
+
const createMethodsProxy = (path) => {
|
|
486
|
+
return new Proxy(
|
|
487
|
+
{},
|
|
488
|
+
{
|
|
489
|
+
get(_, prop) {
|
|
490
|
+
if (HTTP_METHODS.includes(prop)) {
|
|
491
|
+
const selectorFn = (options) => {
|
|
492
|
+
onCapture?.({
|
|
493
|
+
call: { path, method: prop, options },
|
|
494
|
+
selector: null
|
|
495
|
+
});
|
|
496
|
+
return Promise.resolve({ data: void 0 });
|
|
497
|
+
};
|
|
498
|
+
selectorFn.__selectorPath = path;
|
|
499
|
+
selectorFn.__selectorMethod = prop;
|
|
514
500
|
onCapture?.({
|
|
515
|
-
call:
|
|
516
|
-
selector:
|
|
501
|
+
call: null,
|
|
502
|
+
selector: { path, method: prop }
|
|
517
503
|
});
|
|
518
|
-
return
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
selectorFn.__selectorMethod = prop;
|
|
522
|
-
onCapture?.({
|
|
523
|
-
call: null,
|
|
524
|
-
selector: { path, method: prop }
|
|
525
|
-
});
|
|
526
|
-
return selectorFn;
|
|
504
|
+
return selectorFn;
|
|
505
|
+
}
|
|
506
|
+
return void 0;
|
|
527
507
|
}
|
|
528
|
-
return createProxy([...path, prop]);
|
|
529
|
-
},
|
|
530
|
-
// Handles function call syntax for dynamic segments: api.posts("123"), api.users(userId)
|
|
531
|
-
apply(_, __, args) {
|
|
532
|
-
const [segment] = args;
|
|
533
|
-
return createProxy([...path, String(segment)]);
|
|
534
508
|
}
|
|
535
|
-
|
|
509
|
+
);
|
|
536
510
|
};
|
|
537
|
-
return
|
|
511
|
+
return ((path) => {
|
|
512
|
+
return createMethodsProxy(path);
|
|
513
|
+
});
|
|
538
514
|
}
|
|
539
515
|
function extractPathFromSelector(fn) {
|
|
540
|
-
return fn.__selectorPath ??
|
|
516
|
+
return fn.__selectorPath ?? "";
|
|
541
517
|
}
|
|
542
518
|
function extractMethodFromSelector(fn) {
|
|
543
519
|
return fn.__selectorMethod;
|
|
@@ -598,7 +574,7 @@ function createStateManager() {
|
|
|
598
574
|
const newEntry = {
|
|
599
575
|
state: entry.state ?? createInitialState(),
|
|
600
576
|
tags: entry.tags ?? [],
|
|
601
|
-
|
|
577
|
+
meta: /* @__PURE__ */ new Map(),
|
|
602
578
|
selfTag: generateSelfTagFromKey(key),
|
|
603
579
|
previousData: entry.previousData,
|
|
604
580
|
stale: entry.stale
|
|
@@ -658,11 +634,11 @@ function createStateManager() {
|
|
|
658
634
|
});
|
|
659
635
|
return entries;
|
|
660
636
|
},
|
|
661
|
-
|
|
637
|
+
setMeta(key, data) {
|
|
662
638
|
const entry = cache.get(key);
|
|
663
639
|
if (entry) {
|
|
664
640
|
for (const [name, value] of Object.entries(data)) {
|
|
665
|
-
entry.
|
|
641
|
+
entry.meta.set(name, value);
|
|
666
642
|
}
|
|
667
643
|
notifySubscribers(key);
|
|
668
644
|
}
|
|
@@ -982,13 +958,13 @@ var Spoosh = class _Spoosh {
|
|
|
982
958
|
* const { api } = client;
|
|
983
959
|
*
|
|
984
960
|
* // GET request
|
|
985
|
-
* const { data } = await api.
|
|
961
|
+
* const { data } = await api("posts").GET();
|
|
986
962
|
*
|
|
987
963
|
* // POST request with body
|
|
988
|
-
* const { data } = await api.
|
|
964
|
+
* const { data } = await api("posts").POST({ body: { title: 'Hello' } });
|
|
989
965
|
*
|
|
990
966
|
* // Dynamic path parameters
|
|
991
|
-
* const { data } = await api.
|
|
967
|
+
* const { data } = await api("posts/:id").GET({ params: { id: postId } });
|
|
992
968
|
* ```
|
|
993
969
|
*/
|
|
994
970
|
get api() {
|
|
@@ -1004,7 +980,7 @@ var Spoosh = class _Spoosh {
|
|
|
1004
980
|
* const { stateManager } = client;
|
|
1005
981
|
*
|
|
1006
982
|
* // Get cached data
|
|
1007
|
-
* const cache = stateManager.getCache('posts
|
|
983
|
+
* const cache = stateManager.getCache('posts.GET');
|
|
1008
984
|
*
|
|
1009
985
|
* // Invalidate cache by tag
|
|
1010
986
|
* stateManager.invalidate(['posts']);
|
package/dist/index.mjs
CHANGED
|
@@ -112,6 +112,11 @@ function setHeaders(requestOptions, newHeaders) {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
function getContentType(headers) {
|
|
116
|
+
if (!headers) return void 0;
|
|
117
|
+
const headersObj = new Headers(headers);
|
|
118
|
+
return headersObj.get("content-type") ?? void 0;
|
|
119
|
+
}
|
|
115
120
|
|
|
116
121
|
// src/utils/objectToFormData.ts
|
|
117
122
|
function objectToFormData(obj) {
|
|
@@ -247,12 +252,6 @@ function buildInputFields(requestOptions) {
|
|
|
247
252
|
if (requestOptions?.body !== void 0) {
|
|
248
253
|
fields.body = requestOptions.body;
|
|
249
254
|
}
|
|
250
|
-
if (requestOptions?.formData !== void 0) {
|
|
251
|
-
fields.formData = requestOptions.formData;
|
|
252
|
-
}
|
|
253
|
-
if (requestOptions?.urlEncoded !== void 0) {
|
|
254
|
-
fields.urlEncoded = requestOptions.urlEncoded;
|
|
255
|
-
}
|
|
256
255
|
if (requestOptions?.params !== void 0) {
|
|
257
256
|
fields.params = requestOptions.params;
|
|
258
257
|
}
|
|
@@ -281,7 +280,7 @@ async function executeCoreFetch(config) {
|
|
|
281
280
|
const maxRetries = requestOptions?.retries ?? 3;
|
|
282
281
|
const baseDelay = requestOptions?.retryDelay ?? 1e3;
|
|
283
282
|
const retryCount = maxRetries === false ? 0 : maxRetries;
|
|
284
|
-
const finalPath =
|
|
283
|
+
const finalPath = path;
|
|
285
284
|
const url = buildUrl(baseUrl, finalPath, requestOptions?.query);
|
|
286
285
|
let headers = await mergeHeaders(defaultHeaders, requestOptions?.headers);
|
|
287
286
|
const fetchInit = {
|
|
@@ -306,22 +305,17 @@ async function executeCoreFetch(config) {
|
|
|
306
305
|
if (requestOptions?.signal) {
|
|
307
306
|
fetchInit.signal = requestOptions.signal;
|
|
308
307
|
}
|
|
309
|
-
if (requestOptions?.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
})
|
|
320
|
-
if (headers) {
|
|
321
|
-
fetchInit.headers = headers;
|
|
322
|
-
}
|
|
323
|
-
} else if (requestOptions?.body !== void 0) {
|
|
324
|
-
if (isJsonBody(requestOptions.body)) {
|
|
308
|
+
if (requestOptions?.body !== void 0) {
|
|
309
|
+
const contentType = getContentType(headers);
|
|
310
|
+
if (contentType?.includes("application/x-www-form-urlencoded")) {
|
|
311
|
+
fetchInit.body = objectToUrlEncoded(
|
|
312
|
+
requestOptions.body
|
|
313
|
+
);
|
|
314
|
+
} else if (contentType?.includes("multipart/form-data") || containsFile(requestOptions.body)) {
|
|
315
|
+
fetchInit.body = objectToFormData(
|
|
316
|
+
requestOptions.body
|
|
317
|
+
);
|
|
318
|
+
} else if (isJsonBody(requestOptions.body)) {
|
|
325
319
|
fetchInit.body = JSON.stringify(requestOptions.body);
|
|
326
320
|
headers = await mergeHeaders(headers, {
|
|
327
321
|
"Content-Type": "application/json"
|
|
@@ -329,10 +323,6 @@ async function executeCoreFetch(config) {
|
|
|
329
323
|
if (headers) {
|
|
330
324
|
fetchInit.headers = headers;
|
|
331
325
|
}
|
|
332
|
-
} else if (containsFile(requestOptions.body)) {
|
|
333
|
-
fetchInit.body = objectToFormData(
|
|
334
|
-
requestOptions.body
|
|
335
|
-
);
|
|
336
326
|
} else {
|
|
337
327
|
fetchInit.body = requestOptions.body;
|
|
338
328
|
}
|
|
@@ -385,104 +375,89 @@ async function executeCoreFetch(config) {
|
|
|
385
375
|
}
|
|
386
376
|
|
|
387
377
|
// src/proxy/handler.ts
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
378
|
+
function resolvePath2(path, params) {
|
|
379
|
+
const segments = path.split("/").filter(Boolean);
|
|
380
|
+
if (!params) {
|
|
381
|
+
return segments;
|
|
382
|
+
}
|
|
383
|
+
return segments.map((segment) => {
|
|
384
|
+
if (segment.startsWith(":")) {
|
|
385
|
+
const paramName = segment.slice(1);
|
|
386
|
+
const value = params[paramName];
|
|
387
|
+
return value !== void 0 ? String(value) : segment;
|
|
388
|
+
}
|
|
389
|
+
return segment;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
395
392
|
function createProxyHandler(config) {
|
|
396
393
|
const {
|
|
397
394
|
baseUrl,
|
|
398
395
|
defaultOptions,
|
|
399
|
-
path = [],
|
|
400
396
|
fetchExecutor = executeFetch,
|
|
401
397
|
nextTags
|
|
402
398
|
} = config;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
options
|
|
414
|
-
|
|
415
|
-
|
|
399
|
+
return ((path) => {
|
|
400
|
+
return new Proxy(
|
|
401
|
+
{},
|
|
402
|
+
{
|
|
403
|
+
get(_target, prop) {
|
|
404
|
+
if (typeof prop === "symbol") return void 0;
|
|
405
|
+
const method = prop;
|
|
406
|
+
if (!["GET", "POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
407
|
+
return void 0;
|
|
408
|
+
}
|
|
409
|
+
return (options) => {
|
|
410
|
+
const resolvedPath = resolvePath2(path, options?.params);
|
|
411
|
+
return fetchExecutor(
|
|
412
|
+
baseUrl,
|
|
413
|
+
resolvedPath,
|
|
414
|
+
method,
|
|
415
|
+
defaultOptions,
|
|
416
|
+
options,
|
|
417
|
+
nextTags
|
|
418
|
+
);
|
|
419
|
+
};
|
|
420
|
+
}
|
|
416
421
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
defaultOptions,
|
|
420
|
-
path: [...path, prop],
|
|
421
|
-
fetchExecutor,
|
|
422
|
-
nextTags
|
|
423
|
-
});
|
|
424
|
-
},
|
|
425
|
-
// Handles function call syntax for dynamic segments: api.posts(123), api.posts(":id"), api.users(userId)
|
|
426
|
-
// This is the only way to access dynamic segments in Spoosh.
|
|
427
|
-
// The function call syntax allows TypeScript to capture the literal type, enabling params: { id: string } inference.
|
|
428
|
-
apply(_target, _thisArg, args) {
|
|
429
|
-
const [segment] = args;
|
|
430
|
-
return createProxyHandler({
|
|
431
|
-
baseUrl,
|
|
432
|
-
defaultOptions,
|
|
433
|
-
path: [...path, segment],
|
|
434
|
-
fetchExecutor,
|
|
435
|
-
nextTags
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
};
|
|
439
|
-
const noop = () => {
|
|
440
|
-
};
|
|
441
|
-
return new Proxy(noop, handler);
|
|
422
|
+
);
|
|
423
|
+
});
|
|
442
424
|
}
|
|
443
425
|
|
|
444
426
|
// src/proxy/selector-proxy.ts
|
|
445
|
-
var
|
|
446
|
-
"$get",
|
|
447
|
-
"$post",
|
|
448
|
-
"$put",
|
|
449
|
-
"$patch",
|
|
450
|
-
"$delete"
|
|
451
|
-
];
|
|
427
|
+
var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
452
428
|
function createSelectorProxy(onCapture) {
|
|
453
|
-
const
|
|
454
|
-
return new Proxy(
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
429
|
+
const createMethodsProxy = (path) => {
|
|
430
|
+
return new Proxy(
|
|
431
|
+
{},
|
|
432
|
+
{
|
|
433
|
+
get(_, prop) {
|
|
434
|
+
if (HTTP_METHODS.includes(prop)) {
|
|
435
|
+
const selectorFn = (options) => {
|
|
436
|
+
onCapture?.({
|
|
437
|
+
call: { path, method: prop, options },
|
|
438
|
+
selector: null
|
|
439
|
+
});
|
|
440
|
+
return Promise.resolve({ data: void 0 });
|
|
441
|
+
};
|
|
442
|
+
selectorFn.__selectorPath = path;
|
|
443
|
+
selectorFn.__selectorMethod = prop;
|
|
459
444
|
onCapture?.({
|
|
460
|
-
call:
|
|
461
|
-
selector:
|
|
445
|
+
call: null,
|
|
446
|
+
selector: { path, method: prop }
|
|
462
447
|
});
|
|
463
|
-
return
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
selectorFn.__selectorMethod = prop;
|
|
467
|
-
onCapture?.({
|
|
468
|
-
call: null,
|
|
469
|
-
selector: { path, method: prop }
|
|
470
|
-
});
|
|
471
|
-
return selectorFn;
|
|
448
|
+
return selectorFn;
|
|
449
|
+
}
|
|
450
|
+
return void 0;
|
|
472
451
|
}
|
|
473
|
-
return createProxy([...path, prop]);
|
|
474
|
-
},
|
|
475
|
-
// Handles function call syntax for dynamic segments: api.posts("123"), api.users(userId)
|
|
476
|
-
apply(_, __, args) {
|
|
477
|
-
const [segment] = args;
|
|
478
|
-
return createProxy([...path, String(segment)]);
|
|
479
452
|
}
|
|
480
|
-
|
|
453
|
+
);
|
|
481
454
|
};
|
|
482
|
-
return
|
|
455
|
+
return ((path) => {
|
|
456
|
+
return createMethodsProxy(path);
|
|
457
|
+
});
|
|
483
458
|
}
|
|
484
459
|
function extractPathFromSelector(fn) {
|
|
485
|
-
return fn.__selectorPath ??
|
|
460
|
+
return fn.__selectorPath ?? "";
|
|
486
461
|
}
|
|
487
462
|
function extractMethodFromSelector(fn) {
|
|
488
463
|
return fn.__selectorMethod;
|
|
@@ -543,7 +518,7 @@ function createStateManager() {
|
|
|
543
518
|
const newEntry = {
|
|
544
519
|
state: entry.state ?? createInitialState(),
|
|
545
520
|
tags: entry.tags ?? [],
|
|
546
|
-
|
|
521
|
+
meta: /* @__PURE__ */ new Map(),
|
|
547
522
|
selfTag: generateSelfTagFromKey(key),
|
|
548
523
|
previousData: entry.previousData,
|
|
549
524
|
stale: entry.stale
|
|
@@ -603,11 +578,11 @@ function createStateManager() {
|
|
|
603
578
|
});
|
|
604
579
|
return entries;
|
|
605
580
|
},
|
|
606
|
-
|
|
581
|
+
setMeta(key, data) {
|
|
607
582
|
const entry = cache.get(key);
|
|
608
583
|
if (entry) {
|
|
609
584
|
for (const [name, value] of Object.entries(data)) {
|
|
610
|
-
entry.
|
|
585
|
+
entry.meta.set(name, value);
|
|
611
586
|
}
|
|
612
587
|
notifySubscribers(key);
|
|
613
588
|
}
|
|
@@ -927,13 +902,13 @@ var Spoosh = class _Spoosh {
|
|
|
927
902
|
* const { api } = client;
|
|
928
903
|
*
|
|
929
904
|
* // GET request
|
|
930
|
-
* const { data } = await api.
|
|
905
|
+
* const { data } = await api("posts").GET();
|
|
931
906
|
*
|
|
932
907
|
* // POST request with body
|
|
933
|
-
* const { data } = await api.
|
|
908
|
+
* const { data } = await api("posts").POST({ body: { title: 'Hello' } });
|
|
934
909
|
*
|
|
935
910
|
* // Dynamic path parameters
|
|
936
|
-
* const { data } = await api.
|
|
911
|
+
* const { data } = await api("posts/:id").GET({ params: { id: postId } });
|
|
937
912
|
* ```
|
|
938
913
|
*/
|
|
939
914
|
get api() {
|
|
@@ -949,7 +924,7 @@ var Spoosh = class _Spoosh {
|
|
|
949
924
|
* const { stateManager } = client;
|
|
950
925
|
*
|
|
951
926
|
* // Get cached data
|
|
952
|
-
* const cache = stateManager.getCache('posts
|
|
927
|
+
* const cache = stateManager.getCache('posts.GET');
|
|
953
928
|
*
|
|
954
929
|
* // Invalidate cache by tag
|
|
955
930
|
* stateManager.invalidate(['posts']);
|
|
@@ -1586,7 +1561,7 @@ function createInfiniteReadController(options) {
|
|
|
1586
1561
|
return controller;
|
|
1587
1562
|
}
|
|
1588
1563
|
export {
|
|
1589
|
-
|
|
1564
|
+
HTTP_METHODS,
|
|
1590
1565
|
Spoosh,
|
|
1591
1566
|
applyMiddlewares,
|
|
1592
1567
|
buildUrl,
|
|
@@ -1607,6 +1582,7 @@ export {
|
|
|
1607
1582
|
extractMethodFromSelector,
|
|
1608
1583
|
extractPathFromSelector,
|
|
1609
1584
|
generateTags,
|
|
1585
|
+
getContentType,
|
|
1610
1586
|
isJsonBody,
|
|
1611
1587
|
mergeHeaders,
|
|
1612
1588
|
objectToFormData,
|