@spoosh/core 0.10.0 → 0.11.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 +21 -62
- package/dist/index.d.mts +67 -87
- package/dist/index.d.ts +67 -87
- package/dist/index.js +35 -87
- package/dist/index.mjs +35 -87
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
// src/middleware.ts
|
|
2
|
-
function createMiddleware(name, phase, handler) {
|
|
3
|
-
return { name, phase, handler };
|
|
4
|
-
}
|
|
5
|
-
async function applyMiddlewares(context, middlewares, phase) {
|
|
6
|
-
const phaseMiddlewares = middlewares.filter((m) => m.phase === phase);
|
|
7
|
-
let ctx = context;
|
|
8
|
-
for (const middleware of phaseMiddlewares) {
|
|
9
|
-
ctx = await middleware.handler(ctx);
|
|
10
|
-
}
|
|
11
|
-
return ctx;
|
|
12
|
-
}
|
|
13
|
-
function composeMiddlewares(...middlewareLists) {
|
|
14
|
-
return middlewareLists.flat().filter(Boolean);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
1
|
// src/utils/buildUrl.ts
|
|
18
2
|
function stringifyQuery(query) {
|
|
19
3
|
const parts = [];
|
|
@@ -224,19 +208,20 @@ function resolveRequestBody(rawBody) {
|
|
|
224
208
|
return void 0;
|
|
225
209
|
}
|
|
226
210
|
if (isSpooshBody(rawBody)) {
|
|
227
|
-
|
|
211
|
+
const body = rawBody;
|
|
212
|
+
switch (body.kind) {
|
|
228
213
|
case "form":
|
|
229
214
|
return {
|
|
230
|
-
body: objectToFormData(
|
|
215
|
+
body: objectToFormData(body.value)
|
|
231
216
|
};
|
|
232
217
|
case "json":
|
|
233
218
|
return {
|
|
234
|
-
body: JSON.stringify(
|
|
219
|
+
body: JSON.stringify(body.value),
|
|
235
220
|
headers: { "Content-Type": "application/json" }
|
|
236
221
|
};
|
|
237
222
|
case "urlencoded":
|
|
238
223
|
return {
|
|
239
|
-
body: objectToUrlEncoded(
|
|
224
|
+
body: objectToUrlEncoded(body.value),
|
|
240
225
|
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
241
226
|
};
|
|
242
227
|
}
|
|
@@ -392,32 +377,15 @@ var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
392
377
|
var isNetworkError = (err) => err instanceof TypeError;
|
|
393
378
|
var isAbortError = (err) => err instanceof DOMException && err.name === "AbortError";
|
|
394
379
|
async function executeFetch(baseUrl, path, method, defaultOptions, requestOptions, nextTags) {
|
|
395
|
-
|
|
396
|
-
let context = {
|
|
380
|
+
return executeCoreFetch({
|
|
397
381
|
baseUrl,
|
|
398
382
|
path,
|
|
399
383
|
method,
|
|
400
384
|
defaultOptions,
|
|
401
385
|
requestOptions,
|
|
402
|
-
|
|
403
|
-
};
|
|
404
|
-
if (middlewares.length > 0) {
|
|
405
|
-
context = await applyMiddlewares(context, middlewares, "before");
|
|
406
|
-
}
|
|
407
|
-
const response = await executeCoreFetch({
|
|
408
|
-
baseUrl: context.baseUrl,
|
|
409
|
-
path: context.path,
|
|
410
|
-
method: context.method,
|
|
411
|
-
defaultOptions: context.defaultOptions,
|
|
412
|
-
requestOptions: context.requestOptions,
|
|
413
|
-
middlewareFetchInit: context.fetchInit,
|
|
386
|
+
middlewareFetchInit: void 0,
|
|
414
387
|
nextTags
|
|
415
388
|
});
|
|
416
|
-
context.response = response;
|
|
417
|
-
if (middlewares.length > 0) {
|
|
418
|
-
context = await applyMiddlewares(context, middlewares, "after");
|
|
419
|
-
}
|
|
420
|
-
return context.response;
|
|
421
389
|
}
|
|
422
390
|
function buildInputFields(requestOptions) {
|
|
423
391
|
const fields = {};
|
|
@@ -452,12 +420,10 @@ async function executeCoreFetch(config) {
|
|
|
452
420
|
nextTags
|
|
453
421
|
} = config;
|
|
454
422
|
const {
|
|
455
|
-
middlewares: _,
|
|
456
423
|
headers: defaultHeaders,
|
|
457
424
|
transport: defaultTransport,
|
|
458
425
|
...fetchDefaults
|
|
459
426
|
} = defaultOptions;
|
|
460
|
-
void _;
|
|
461
427
|
const inputFields = buildInputFields(requestOptions);
|
|
462
428
|
const maxRetries = requestOptions?.retries ?? 3;
|
|
463
429
|
const baseDelay = requestOptions?.retryDelay ?? 1e3;
|
|
@@ -648,7 +614,7 @@ function createInitialState() {
|
|
|
648
614
|
function generateSelfTagFromKey(key) {
|
|
649
615
|
try {
|
|
650
616
|
const parsed = JSON.parse(key);
|
|
651
|
-
return parsed.path
|
|
617
|
+
return parsed.path;
|
|
652
618
|
} catch {
|
|
653
619
|
return void 0;
|
|
654
620
|
}
|
|
@@ -790,6 +756,9 @@ function createStateManager() {
|
|
|
790
756
|
getSize() {
|
|
791
757
|
return cache.size;
|
|
792
758
|
},
|
|
759
|
+
getSubscribersCount(key) {
|
|
760
|
+
return subscribers.get(key)?.size ?? 0;
|
|
761
|
+
},
|
|
793
762
|
setPendingPromise(key, promise) {
|
|
794
763
|
if (promise === void 0) {
|
|
795
764
|
pendingPromises.delete(key);
|
|
@@ -903,10 +872,7 @@ function createPluginExecutor(initialPlugins = []) {
|
|
|
903
872
|
if (!handler) {
|
|
904
873
|
continue;
|
|
905
874
|
}
|
|
906
|
-
await handler(
|
|
907
|
-
context,
|
|
908
|
-
previousContext
|
|
909
|
-
);
|
|
875
|
+
await handler(context, previousContext);
|
|
910
876
|
}
|
|
911
877
|
};
|
|
912
878
|
return {
|
|
@@ -926,6 +892,7 @@ function createPluginExecutor(initialPlugins = []) {
|
|
|
926
892
|
return () => middleware(
|
|
927
893
|
context,
|
|
928
894
|
next
|
|
895
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
929
896
|
);
|
|
930
897
|
},
|
|
931
898
|
coreFetch
|
|
@@ -951,11 +918,6 @@ function createPluginExecutor(initialPlugins = []) {
|
|
|
951
918
|
createContext(input) {
|
|
952
919
|
const ctx = input;
|
|
953
920
|
ctx.plugins = createPluginAccessor(ctx);
|
|
954
|
-
ctx.headers = {};
|
|
955
|
-
ctx.setHeaders = (newHeaders) => {
|
|
956
|
-
ctx.headers = { ...ctx.headers, ...newHeaders };
|
|
957
|
-
ctx.requestOptions.headers = ctx.headers;
|
|
958
|
-
};
|
|
959
921
|
return ctx;
|
|
960
922
|
}
|
|
961
923
|
};
|
|
@@ -1083,7 +1045,7 @@ var Spoosh = class _Spoosh {
|
|
|
1083
1045
|
return this._instance;
|
|
1084
1046
|
}
|
|
1085
1047
|
/**
|
|
1086
|
-
* The type-safe API
|
|
1048
|
+
* The type-safe API interface for making requests.
|
|
1087
1049
|
*
|
|
1088
1050
|
* Provides a proxy-based interface for accessing endpoints defined in your schema.
|
|
1089
1051
|
*
|
|
@@ -1189,15 +1151,10 @@ var Spoosh = class _Spoosh {
|
|
|
1189
1151
|
};
|
|
1190
1152
|
|
|
1191
1153
|
// src/createClient.ts
|
|
1192
|
-
function createClient(
|
|
1193
|
-
const { baseUrl, defaultOptions = {}, middlewares = [] } = config;
|
|
1194
|
-
const optionsWithMiddlewares = {
|
|
1195
|
-
...defaultOptions,
|
|
1196
|
-
middlewares
|
|
1197
|
-
};
|
|
1154
|
+
function createClient(baseUrl, defaultOptions) {
|
|
1198
1155
|
return createProxyHandler({
|
|
1199
1156
|
baseUrl,
|
|
1200
|
-
defaultOptions:
|
|
1157
|
+
defaultOptions: defaultOptions || {},
|
|
1201
1158
|
nextTags: true
|
|
1202
1159
|
});
|
|
1203
1160
|
}
|
|
@@ -1228,9 +1185,7 @@ function createOperationController(options) {
|
|
|
1228
1185
|
let cachedState = initialState;
|
|
1229
1186
|
let currentRequestTimestamp = Date.now();
|
|
1230
1187
|
let isFirstExecute = true;
|
|
1231
|
-
const createContext = (requestOptions = {}, requestTimestamp = Date.now()) => {
|
|
1232
|
-
const cached = stateManager.getCache(queryKey);
|
|
1233
|
-
const state = cached?.state ?? createInitialState();
|
|
1188
|
+
const createContext = (requestOptions = {}, requestTimestamp = Date.now(), resolvedHeaders) => {
|
|
1234
1189
|
const resolvedTags = pluginOptions?.tags ?? tags;
|
|
1235
1190
|
return pluginExecutor.createContext({
|
|
1236
1191
|
operationType,
|
|
@@ -1240,11 +1195,13 @@ function createOperationController(options) {
|
|
|
1240
1195
|
tags: resolvedTags,
|
|
1241
1196
|
requestTimestamp,
|
|
1242
1197
|
hookId,
|
|
1243
|
-
|
|
1244
|
-
|
|
1198
|
+
request: {
|
|
1199
|
+
...initialRequestOptions,
|
|
1200
|
+
...requestOptions,
|
|
1201
|
+
headers: resolvedHeaders ?? {}
|
|
1202
|
+
},
|
|
1245
1203
|
metadata,
|
|
1246
1204
|
pluginOptions,
|
|
1247
|
-
abort: () => abortController?.abort(),
|
|
1248
1205
|
stateManager,
|
|
1249
1206
|
eventEmitter
|
|
1250
1207
|
});
|
|
@@ -1254,6 +1211,7 @@ function createOperationController(options) {
|
|
|
1254
1211
|
if (cached) {
|
|
1255
1212
|
stateManager.setCache(queryKey, {
|
|
1256
1213
|
state: { ...cached.state, ...updater },
|
|
1214
|
+
tags,
|
|
1257
1215
|
stale: false
|
|
1258
1216
|
});
|
|
1259
1217
|
} else {
|
|
@@ -1271,21 +1229,24 @@ function createOperationController(options) {
|
|
|
1271
1229
|
currentRequestTimestamp = Date.now();
|
|
1272
1230
|
}
|
|
1273
1231
|
isFirstExecute = false;
|
|
1274
|
-
const
|
|
1232
|
+
const mergedOptions = { ...initialRequestOptions, ...opts };
|
|
1233
|
+
const resolvedHeaders = await resolveHeadersToRecord(
|
|
1234
|
+
mergedOptions.headers
|
|
1235
|
+
);
|
|
1236
|
+
const context = createContext(
|
|
1237
|
+
opts,
|
|
1238
|
+
currentRequestTimestamp,
|
|
1239
|
+
resolvedHeaders
|
|
1240
|
+
);
|
|
1275
1241
|
if (force) {
|
|
1276
1242
|
context.forceRefetch = true;
|
|
1277
1243
|
}
|
|
1278
|
-
context.headers = await resolveHeadersToRecord(
|
|
1279
|
-
context.requestOptions.headers
|
|
1280
|
-
);
|
|
1281
|
-
context.requestOptions.headers = context.headers;
|
|
1282
1244
|
const coreFetch = async () => {
|
|
1283
1245
|
abortController = new AbortController();
|
|
1284
|
-
context.
|
|
1246
|
+
context.request.signal = abortController.signal;
|
|
1285
1247
|
const fetchPromise = (async () => {
|
|
1286
1248
|
try {
|
|
1287
|
-
const response = await fetchFn(context.
|
|
1288
|
-
context.response = response;
|
|
1249
|
+
const response = await fetchFn(context.request);
|
|
1289
1250
|
return response;
|
|
1290
1251
|
} catch (err) {
|
|
1291
1252
|
const errorResponse = {
|
|
@@ -1293,7 +1254,6 @@ function createOperationController(options) {
|
|
|
1293
1254
|
error: err,
|
|
1294
1255
|
data: void 0
|
|
1295
1256
|
};
|
|
1296
|
-
context.response = errorResponse;
|
|
1297
1257
|
return errorResponse;
|
|
1298
1258
|
}
|
|
1299
1259
|
})();
|
|
@@ -1522,11 +1482,6 @@ function createInfiniteReadController(options) {
|
|
|
1522
1482
|
);
|
|
1523
1483
|
};
|
|
1524
1484
|
const createContext = (pageKey) => {
|
|
1525
|
-
const initialState = {
|
|
1526
|
-
data: void 0,
|
|
1527
|
-
error: void 0,
|
|
1528
|
-
timestamp: 0
|
|
1529
|
-
};
|
|
1530
1485
|
return pluginExecutor.createContext({
|
|
1531
1486
|
operationType: "infiniteRead",
|
|
1532
1487
|
path,
|
|
@@ -1535,11 +1490,9 @@ function createInfiniteReadController(options) {
|
|
|
1535
1490
|
tags,
|
|
1536
1491
|
requestTimestamp: Date.now(),
|
|
1537
1492
|
hookId,
|
|
1538
|
-
|
|
1539
|
-
state: initialState,
|
|
1493
|
+
request: { headers: {} },
|
|
1540
1494
|
metadata: /* @__PURE__ */ new Map(),
|
|
1541
1495
|
pluginOptions,
|
|
1542
|
-
abort: () => abortController?.abort(),
|
|
1543
1496
|
stateManager,
|
|
1544
1497
|
eventEmitter
|
|
1545
1498
|
});
|
|
@@ -1566,7 +1519,6 @@ function createInfiniteReadController(options) {
|
|
|
1566
1519
|
const fetchPromise = (async () => {
|
|
1567
1520
|
try {
|
|
1568
1521
|
const response = await fetchFn(mergedRequest, signal);
|
|
1569
|
-
context.response = response;
|
|
1570
1522
|
if (signal.aborted) {
|
|
1571
1523
|
return {
|
|
1572
1524
|
status: 0,
|
|
@@ -1588,7 +1540,6 @@ function createInfiniteReadController(options) {
|
|
|
1588
1540
|
error: err,
|
|
1589
1541
|
data: void 0
|
|
1590
1542
|
};
|
|
1591
|
-
context.response = errorResponse;
|
|
1592
1543
|
latestError = err;
|
|
1593
1544
|
return errorResponse;
|
|
1594
1545
|
} finally {
|
|
@@ -1763,15 +1714,12 @@ export {
|
|
|
1763
1714
|
HTTP_METHODS,
|
|
1764
1715
|
Spoosh,
|
|
1765
1716
|
__DEV__,
|
|
1766
|
-
applyMiddlewares,
|
|
1767
1717
|
buildUrl,
|
|
1768
|
-
composeMiddlewares,
|
|
1769
1718
|
containsFile,
|
|
1770
1719
|
createClient,
|
|
1771
1720
|
createEventEmitter,
|
|
1772
1721
|
createInfiniteReadController,
|
|
1773
1722
|
createInitialState,
|
|
1774
|
-
createMiddleware,
|
|
1775
1723
|
createOperationController,
|
|
1776
1724
|
createPluginExecutor,
|
|
1777
1725
|
createPluginRegistry,
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "Type-safe API
|
|
5
|
+
"description": "Type-safe API toolkit with plugin middleware system",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"spoosh",
|
|
8
|
-
"api-
|
|
8
|
+
"api-toolkit",
|
|
9
9
|
"fetch",
|
|
10
10
|
"typescript",
|
|
11
11
|
"middleware",
|