@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/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
- switch (rawBody.kind) {
211
+ const body = rawBody;
212
+ switch (body.kind) {
228
213
  case "form":
229
214
  return {
230
- body: objectToFormData(rawBody.value)
215
+ body: objectToFormData(body.value)
231
216
  };
232
217
  case "json":
233
218
  return {
234
- body: JSON.stringify(rawBody.value),
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(rawBody.value),
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
- const middlewares = defaultOptions.middlewares ?? [];
396
- let context = {
380
+ return executeCoreFetch({
397
381
  baseUrl,
398
382
  path,
399
383
  method,
400
384
  defaultOptions,
401
385
  requestOptions,
402
- metadata: {}
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?.join("/");
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 client for making requests.
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(config) {
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: optionsWithMiddlewares,
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
- requestOptions: { ...initialRequestOptions, ...requestOptions },
1244
- state,
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 context = createContext(opts, currentRequestTimestamp);
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.requestOptions.signal = abortController.signal;
1246
+ context.request.signal = abortController.signal;
1285
1247
  const fetchPromise = (async () => {
1286
1248
  try {
1287
- const response = await fetchFn(context.requestOptions);
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
- requestOptions: {},
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.10.0",
3
+ "version": "0.11.0",
4
4
  "license": "MIT",
5
- "description": "Type-safe API client with plugin middleware system",
5
+ "description": "Type-safe API toolkit with plugin middleware system",
6
6
  "keywords": [
7
7
  "spoosh",
8
- "api-client",
8
+ "api-toolkit",
9
9
  "fetch",
10
10
  "typescript",
11
11
  "middleware",