@duplojs/http 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.
Files changed (82) hide show
  1. package/dist/client/clientCache.cjs +84 -0
  2. package/dist/client/clientCache.d.ts +4 -0
  3. package/dist/client/clientCache.mjs +80 -0
  4. package/dist/client/getBody.cjs +0 -3
  5. package/dist/client/getBody.mjs +0 -3
  6. package/dist/client/hooks.cjs +36 -0
  7. package/dist/client/hooks.d.ts +5 -1
  8. package/dist/client/hooks.mjs +33 -1
  9. package/dist/client/httpClient.cjs +26 -1
  10. package/dist/client/httpClient.d.ts +8 -1
  11. package/dist/client/httpClient.mjs +26 -1
  12. package/dist/client/index.cjs +12 -0
  13. package/dist/client/index.d.ts +2 -0
  14. package/dist/client/index.mjs +4 -2
  15. package/dist/client/promiseRequest.cjs +33 -8
  16. package/dist/client/promiseRequest.d.ts +2 -1
  17. package/dist/client/promiseRequest.mjs +34 -9
  18. package/dist/client/serverSentEvents.cjs +18 -12
  19. package/dist/client/serverSentEvents.d.ts +2 -1
  20. package/dist/client/serverSentEvents.mjs +18 -13
  21. package/dist/client/stream.cjs +117 -0
  22. package/dist/client/stream.d.ts +3 -0
  23. package/dist/client/stream.mjs +95 -0
  24. package/dist/client/types/clientCache.cjs +2 -0
  25. package/dist/client/types/clientCache.d.ts +27 -0
  26. package/dist/client/types/clientCache.mjs +1 -0
  27. package/dist/client/types/clientRequestParams.d.ts +8 -1
  28. package/dist/client/types/clientResponse.d.ts +24 -6
  29. package/dist/client/types/hooks.d.ts +10 -1
  30. package/dist/client/types/index.cjs +1 -0
  31. package/dist/client/types/index.d.ts +1 -0
  32. package/dist/client/types/index.mjs +1 -0
  33. package/dist/client/types/promiseRequestParams.d.ts +3 -0
  34. package/dist/client/types/serverRoute.d.ts +2 -0
  35. package/dist/core/builders/route/handler.d.ts +5 -5
  36. package/dist/core/defaultHooks/index.cjs +14 -0
  37. package/dist/core/defaultHooks/index.mjs +14 -0
  38. package/dist/core/functionsBuilders/steps/defaults/extractStep.mjs +1 -1
  39. package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +33 -0
  40. package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +33 -0
  41. package/dist/core/hub/defaultMalformedUrlHandler.d.ts +1 -1
  42. package/dist/core/hub/defaultNotfoundHandler.d.ts +1 -1
  43. package/dist/core/index.cjs +143 -134
  44. package/dist/core/index.d.ts +1 -0
  45. package/dist/core/index.mjs +42 -39
  46. package/dist/core/response/contract.cjs +21 -0
  47. package/dist/core/response/contract.d.ts +33 -5
  48. package/dist/core/response/contract.mjs +21 -0
  49. package/dist/core/response/index.cjs +4 -0
  50. package/dist/core/response/index.d.ts +7 -0
  51. package/dist/core/response/index.mjs +2 -0
  52. package/dist/core/response/streamPredicted.cjs +23 -0
  53. package/dist/core/response/streamPredicted.d.ts +14 -0
  54. package/dist/core/response/streamPredicted.mjs +21 -0
  55. package/dist/core/response/streamTextPredicted.cjs +23 -0
  56. package/dist/core/response/streamTextPredicted.d.ts +14 -0
  57. package/dist/core/response/streamTextPredicted.mjs +21 -0
  58. package/dist/core/serverSentEvents.cjs +25 -77
  59. package/dist/core/serverSentEvents.d.ts +4 -16
  60. package/dist/core/serverSentEvents.mjs +25 -77
  61. package/dist/core/steps/handler.d.ts +15 -5
  62. package/dist/core/stream.cjs +73 -0
  63. package/dist/core/stream.d.ts +19 -0
  64. package/dist/core/stream.mjs +73 -0
  65. package/dist/interfaces/node/bodyReaders/formData/index.cjs +1 -1
  66. package/dist/interfaces/node/bodyReaders/formData/index.mjs +1 -1
  67. package/dist/interfaces/node/hooks/index.cjs +21 -1
  68. package/dist/interfaces/node/hooks/index.mjs +21 -1
  69. package/dist/interfaces/node/index.cjs +6 -6
  70. package/dist/interfaces/node/index.mjs +2 -2
  71. package/dist/plugins/codeGenerator/aggregateStepContract.cjs +12 -0
  72. package/dist/plugins/codeGenerator/aggregateStepContract.mjs +13 -1
  73. package/dist/plugins/cookie/index.cjs +2 -2
  74. package/dist/plugins/cookie/index.mjs +1 -1
  75. package/dist/plugins/openApiGenerator/aggregateStepContract.d.ts +1 -1
  76. package/dist/plugins/openApiGenerator/makeOpenApiRoute.d.ts +1 -1
  77. package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +55 -2
  78. package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +55 -2
  79. package/dist/plugins/openApiGenerator/types/endpointResponse.d.ts +4 -1
  80. package/dist/plugins/static/makeRouteFile.d.ts +1 -1
  81. package/dist/plugins/static/makeRouteFolder.d.ts +1 -1
  82. package/package.json +3 -3
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ var insertParamsInPath = require('./insertParamsInPath.cjs');
4
+
5
+ function autoCreateCacheKey(params) {
6
+ try {
7
+ return JSON.stringify({
8
+ method: params.method,
9
+ path: insertParamsInPath.insertParamsInPath(params.path, params.params),
10
+ query: params.query
11
+ ? Object.entries(params.query).sort((entryA, entryB) => entryA[0].localeCompare(entryB[0]))
12
+ : undefined,
13
+ body: params.body,
14
+ });
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ function findResponseFromCacheStore(requestParams) {
21
+ if (!requestParams.clientCache
22
+ || requestParams.bypassClientCache === true
23
+ || requestParams.refreshClientCache === true) {
24
+ return null;
25
+ }
26
+ const key = requestParams.clientCache({
27
+ method: requestParams.method,
28
+ path: requestParams.path,
29
+ body: requestParams.body,
30
+ headers: requestParams.headers,
31
+ hookParams: requestParams.hookParams,
32
+ params: requestParams.params,
33
+ query: requestParams.query,
34
+ });
35
+ if (key === null) {
36
+ return null;
37
+ }
38
+ const cachedResponse = requestParams.cacheStore.get(key);
39
+ if (!cachedResponse) {
40
+ return null;
41
+ }
42
+ const rawResponse = new Response(undefined, { headers: cachedResponse.headers });
43
+ return {
44
+ ...cachedResponse,
45
+ information: cachedResponse.information,
46
+ headers: rawResponse.headers,
47
+ raw: rawResponse,
48
+ requestParams,
49
+ fromCache: true,
50
+ };
51
+ }
52
+ function saveResponseInCacheStore(requestParams, clientResponse) {
53
+ if (!requestParams.clientCache
54
+ || requestParams.bypassClientCache === true) {
55
+ return;
56
+ }
57
+ const key = requestParams.clientCache({
58
+ method: requestParams.method,
59
+ path: requestParams.path,
60
+ body: requestParams.body,
61
+ headers: requestParams.headers,
62
+ hookParams: requestParams.hookParams,
63
+ params: requestParams.params,
64
+ query: requestParams.query,
65
+ });
66
+ if (key === null) {
67
+ return;
68
+ }
69
+ requestParams.cacheStore.set(key, {
70
+ body: clientResponse.body,
71
+ code: clientResponse.code,
72
+ headers: Object.fromEntries(clientResponse.headers.entries()),
73
+ information: clientResponse.information,
74
+ ok: clientResponse.ok,
75
+ predicted: clientResponse.predicted,
76
+ redirected: clientResponse.redirected,
77
+ type: clientResponse.type,
78
+ url: clientResponse.url,
79
+ });
80
+ }
81
+
82
+ exports.autoCreateCacheKey = autoCreateCacheKey;
83
+ exports.findResponseFromCacheStore = findResponseFromCacheStore;
84
+ exports.saveResponseInCacheStore = saveResponseInCacheStore;
@@ -0,0 +1,4 @@
1
+ import { type PromiseRequestParams, type ClientResponse, type CreateClientCacheKeyParams } from "./types";
2
+ export declare function autoCreateCacheKey(params: CreateClientCacheKeyParams): string | null;
3
+ export declare function findResponseFromCacheStore(requestParams: PromiseRequestParams): null | ClientResponse;
4
+ export declare function saveResponseInCacheStore(requestParams: PromiseRequestParams, clientResponse: ClientResponse): void;
@@ -0,0 +1,80 @@
1
+ import { insertParamsInPath } from './insertParamsInPath.mjs';
2
+
3
+ function autoCreateCacheKey(params) {
4
+ try {
5
+ return JSON.stringify({
6
+ method: params.method,
7
+ path: insertParamsInPath(params.path, params.params),
8
+ query: params.query
9
+ ? Object.entries(params.query).sort((entryA, entryB) => entryA[0].localeCompare(entryB[0]))
10
+ : undefined,
11
+ body: params.body,
12
+ });
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ function findResponseFromCacheStore(requestParams) {
19
+ if (!requestParams.clientCache
20
+ || requestParams.bypassClientCache === true
21
+ || requestParams.refreshClientCache === true) {
22
+ return null;
23
+ }
24
+ const key = requestParams.clientCache({
25
+ method: requestParams.method,
26
+ path: requestParams.path,
27
+ body: requestParams.body,
28
+ headers: requestParams.headers,
29
+ hookParams: requestParams.hookParams,
30
+ params: requestParams.params,
31
+ query: requestParams.query,
32
+ });
33
+ if (key === null) {
34
+ return null;
35
+ }
36
+ const cachedResponse = requestParams.cacheStore.get(key);
37
+ if (!cachedResponse) {
38
+ return null;
39
+ }
40
+ const rawResponse = new Response(undefined, { headers: cachedResponse.headers });
41
+ return {
42
+ ...cachedResponse,
43
+ information: cachedResponse.information,
44
+ headers: rawResponse.headers,
45
+ raw: rawResponse,
46
+ requestParams,
47
+ fromCache: true,
48
+ };
49
+ }
50
+ function saveResponseInCacheStore(requestParams, clientResponse) {
51
+ if (!requestParams.clientCache
52
+ || requestParams.bypassClientCache === true) {
53
+ return;
54
+ }
55
+ const key = requestParams.clientCache({
56
+ method: requestParams.method,
57
+ path: requestParams.path,
58
+ body: requestParams.body,
59
+ headers: requestParams.headers,
60
+ hookParams: requestParams.hookParams,
61
+ params: requestParams.params,
62
+ query: requestParams.query,
63
+ });
64
+ if (key === null) {
65
+ return;
66
+ }
67
+ requestParams.cacheStore.set(key, {
68
+ body: clientResponse.body,
69
+ code: clientResponse.code,
70
+ headers: Object.fromEntries(clientResponse.headers.entries()),
71
+ information: clientResponse.information,
72
+ ok: clientResponse.ok,
73
+ predicted: clientResponse.predicted,
74
+ redirected: clientResponse.redirected,
75
+ type: clientResponse.type,
76
+ url: clientResponse.url,
77
+ });
78
+ }
79
+
80
+ export { autoCreateCacheKey, findResponseFromCacheStore, saveResponseInCacheStore };
@@ -5,9 +5,6 @@ function getBody(response) {
5
5
  if (!responseContentType) {
6
6
  return Promise.resolve(undefined);
7
7
  }
8
- else if (responseContentType.includes("text/event-stream")) {
9
- return Promise.resolve(undefined);
10
- }
11
8
  else if (responseContentType.includes("json")) {
12
9
  return response.json();
13
10
  }
@@ -3,9 +3,6 @@ function getBody(response) {
3
3
  if (!responseContentType) {
4
4
  return Promise.resolve(undefined);
5
5
  }
6
- else if (responseContentType.includes("text/event-stream")) {
7
- return Promise.resolve(undefined);
8
- }
9
6
  else if (responseContentType.includes("json")) {
10
7
  return response.json();
11
8
  }
@@ -108,17 +108,53 @@ async function launchReceiveEventServerEventHook(clientHook, promiseRequestHook,
108
108
  await clientHook[index](event, response);
109
109
  }
110
110
  }
111
+ async function launchCloseStreamHook(clientHook, promiseRequestHook, response) {
112
+ for (let index = 0; index < promiseRequestHook.length; index++) {
113
+ await promiseRequestHook[index](response);
114
+ }
115
+ for (let index = 0; index < clientHook.length; index++) {
116
+ await clientHook[index](response);
117
+ }
118
+ }
119
+ async function launchReceiveDataStreamHook(clientHook, promiseRequestHook, data, response) {
120
+ for (let index = 0; index < promiseRequestHook.length; index++) {
121
+ await promiseRequestHook[index](data, response);
122
+ }
123
+ for (let index = 0; index < clientHook.length; index++) {
124
+ await clientHook[index](data, response);
125
+ }
126
+ }
127
+ async function launchErrorStreamHook(clientHook, promiseRequestHook, error, response) {
128
+ for (let index = 0; index < promiseRequestHook.length; index++) {
129
+ await promiseRequestHook[index](error, response);
130
+ }
131
+ for (let index = 0; index < clientHook.length; index++) {
132
+ await clientHook[index](error, response);
133
+ }
134
+ }
135
+ async function launchStartStreamHook(clientHook, promiseRequestHook, response) {
136
+ for (let index = 0; index < promiseRequestHook.length; index++) {
137
+ await promiseRequestHook[index](response);
138
+ }
139
+ for (let index = 0; index < clientHook.length; index++) {
140
+ await clientHook[index](response);
141
+ }
142
+ }
111
143
 
112
144
  exports.launchBeforeRetryServerEventHook = launchBeforeRetryServerEventHook;
113
145
  exports.launchCloseServerEventHook = launchCloseServerEventHook;
146
+ exports.launchCloseStreamHook = launchCloseStreamHook;
114
147
  exports.launchCodeHook = launchCodeHook;
115
148
  exports.launchErrorHook = launchErrorHook;
116
149
  exports.launchErrorServerEventHook = launchErrorServerEventHook;
150
+ exports.launchErrorStreamHook = launchErrorStreamHook;
117
151
  exports.launchExpectedResponseHook = launchExpectedResponseHook;
118
152
  exports.launchInformationHook = launchInformationHook;
119
153
  exports.launchNotPredictedHook = launchNotPredictedHook;
154
+ exports.launchReceiveDataStreamHook = launchReceiveDataStreamHook;
120
155
  exports.launchReceiveEventServerEventHook = launchReceiveEventServerEventHook;
121
156
  exports.launchRequestHook = launchRequestHook;
122
157
  exports.launchResponseHook = launchResponseHook;
123
158
  exports.launchResponseTypeHook = launchResponseTypeHook;
124
159
  exports.launchStartServerEventHook = launchStartServerEventHook;
160
+ exports.launchStartStreamHook = launchStartStreamHook;
@@ -1,4 +1,4 @@
1
- import { type CodeHook, type ErrorHook, type InformationHook, type NotPredictedResponseHook, type RequestHook, type ResponseHook, type ResponseTypeHook, type PromiseRequestParams, type NotPredictedClientResponse, type ClientResponse, type CloseServerEventHook, type ClientEventsResponse, type BeforeRetryServerEventHook, type ErrorServerEventHook, type StartServerEventHook, type ServerEvent, type ReceiveEventServerEventHook } from "./types";
1
+ import { type CodeHook, type ErrorHook, type InformationHook, type NotPredictedResponseHook, type RequestHook, type ResponseHook, type ResponseTypeHook, type PromiseRequestParams, type NotPredictedClientResponse, type ClientResponse, type CloseServerEventHook, type ClientEventsResponse, type BeforeRetryServerEventHook, type ErrorServerEventHook, type StartServerEventHook, type ServerEvent, type ReceiveEventServerEventHook, type CloseStreamHook, type ClientStreamResponse, type ReceiveDataStreamHook, type ErrorStreamHook, type StartStreamHook, type ServerRouteResponseFlux } from "./types";
2
2
  export declare function launchRequestHook(clientHook: readonly RequestHook[], promiseRequestHook: readonly RequestHook[], requestParams: PromiseRequestParams): Promise<PromiseRequestParams>;
3
3
  export declare function launchResponseHook(clientHook: readonly ResponseHook[], promiseRequestHook: readonly ResponseHook[], response: ClientResponse): Promise<ClientResponse>;
4
4
  export declare function launchInformationHook(clientHook: readonly InformationHook[], promiseRequestHook: readonly InformationHook[], response: ClientResponse): Promise<void>;
@@ -12,3 +12,7 @@ export declare function launchBeforeRetryServerEventHook(clientHook: readonly Be
12
12
  export declare function launchErrorServerEventHook(clientHook: readonly ErrorServerEventHook[], promiseRequestHook: readonly ErrorServerEventHook[], error: unknown, response: ClientEventsResponse): Promise<void>;
13
13
  export declare function launchStartServerEventHook(clientHook: readonly StartServerEventHook[], promiseRequestHook: readonly StartServerEventHook[], response: ClientEventsResponse): Promise<void>;
14
14
  export declare function launchReceiveEventServerEventHook(clientHook: readonly ReceiveEventServerEventHook[], promiseRequestHook: readonly ReceiveEventServerEventHook[], event: ServerEvent, response: ClientEventsResponse): Promise<void>;
15
+ export declare function launchCloseStreamHook(clientHook: readonly CloseStreamHook[], promiseRequestHook: readonly CloseStreamHook[], response: ClientStreamResponse): Promise<void>;
16
+ export declare function launchReceiveDataStreamHook(clientHook: readonly ReceiveDataStreamHook[], promiseRequestHook: readonly ReceiveDataStreamHook[], data: ServerRouteResponseFlux, response: ClientStreamResponse): Promise<void>;
17
+ export declare function launchErrorStreamHook(clientHook: readonly ErrorStreamHook[], promiseRequestHook: readonly ErrorStreamHook[], error: unknown, response: ClientStreamResponse): Promise<void>;
18
+ export declare function launchStartStreamHook(clientHook: readonly StartStreamHook[], promiseRequestHook: readonly StartStreamHook[], response: ClientStreamResponse): Promise<void>;
@@ -106,5 +106,37 @@ async function launchReceiveEventServerEventHook(clientHook, promiseRequestHook,
106
106
  await clientHook[index](event, response);
107
107
  }
108
108
  }
109
+ async function launchCloseStreamHook(clientHook, promiseRequestHook, response) {
110
+ for (let index = 0; index < promiseRequestHook.length; index++) {
111
+ await promiseRequestHook[index](response);
112
+ }
113
+ for (let index = 0; index < clientHook.length; index++) {
114
+ await clientHook[index](response);
115
+ }
116
+ }
117
+ async function launchReceiveDataStreamHook(clientHook, promiseRequestHook, data, response) {
118
+ for (let index = 0; index < promiseRequestHook.length; index++) {
119
+ await promiseRequestHook[index](data, response);
120
+ }
121
+ for (let index = 0; index < clientHook.length; index++) {
122
+ await clientHook[index](data, response);
123
+ }
124
+ }
125
+ async function launchErrorStreamHook(clientHook, promiseRequestHook, error, response) {
126
+ for (let index = 0; index < promiseRequestHook.length; index++) {
127
+ await promiseRequestHook[index](error, response);
128
+ }
129
+ for (let index = 0; index < clientHook.length; index++) {
130
+ await clientHook[index](error, response);
131
+ }
132
+ }
133
+ async function launchStartStreamHook(clientHook, promiseRequestHook, response) {
134
+ for (let index = 0; index < promiseRequestHook.length; index++) {
135
+ await promiseRequestHook[index](response);
136
+ }
137
+ for (let index = 0; index < clientHook.length; index++) {
138
+ await clientHook[index](response);
139
+ }
140
+ }
109
141
 
110
- export { launchBeforeRetryServerEventHook, launchCloseServerEventHook, launchCodeHook, launchErrorHook, launchErrorServerEventHook, launchExpectedResponseHook, launchInformationHook, launchNotPredictedHook, launchReceiveEventServerEventHook, launchRequestHook, launchResponseHook, launchResponseTypeHook, launchStartServerEventHook };
142
+ export { launchBeforeRetryServerEventHook, launchCloseServerEventHook, launchCloseStreamHook, launchCodeHook, launchErrorHook, launchErrorServerEventHook, launchErrorStreamHook, launchExpectedResponseHook, launchInformationHook, launchNotPredictedHook, launchReceiveDataStreamHook, launchReceiveEventServerEventHook, launchRequestHook, launchResponseHook, launchResponseTypeHook, launchStartServerEventHook, launchStartStreamHook };
@@ -4,6 +4,7 @@ var OO = require('@duplojs/utils/object');
4
4
  var GG = require('@duplojs/utils/generator');
5
5
  var kind = require('./kind.cjs');
6
6
  var promiseRequest = require('./promiseRequest.cjs');
7
+ var clientCache = require('./clientCache.cjs');
7
8
 
8
9
  function _interopNamespaceDefault(e) {
9
10
  var n = Object.create(null);
@@ -27,6 +28,9 @@ var GG__namespace = /*#__PURE__*/_interopNamespaceDefault(GG);
27
28
 
28
29
  const httpClientKind = kind.createClientKind("http-client");
29
30
  function createHttpClient(clientParams) {
31
+ const cacheStore = new Map(clientParams.clientCacheInitialValues
32
+ ? OO__namespace.entries(clientParams.clientCacheInitialValues)
33
+ : []);
30
34
  const hooks = OO__namespace.override({
31
35
  request: [],
32
36
  response: [],
@@ -45,6 +49,10 @@ function createHttpClient(clientParams) {
45
49
  errorServerEvent: [],
46
50
  receiveEventServerEvent: [],
47
51
  startServerEvent: [],
52
+ closeStream: [],
53
+ errorStream: [],
54
+ receiveDataStream: [],
55
+ startStream: [],
48
56
  }, clientParams.hooks ?? {});
49
57
  const config = {
50
58
  baseUrl: clientParams.baseUrl,
@@ -59,6 +67,7 @@ function createHttpClient(clientParams) {
59
67
  config,
60
68
  hooks,
61
69
  defaultHeaders,
70
+ cacheStore,
62
71
  addDefaultHeader(headerName, headerValue) {
63
72
  defaultHeaders.set(headerName, typeof headerValue === "function"
64
73
  ? headerValue
@@ -122,6 +131,18 @@ function createHttpClient(clientParams) {
122
131
  addStartServerEventHook(hook) {
123
132
  hooks.startServerEvent.push(hook);
124
133
  },
134
+ addCloseStreamHook(hook) {
135
+ hooks.closeStream.push(hook);
136
+ },
137
+ addReceiveDataStreamHook(hook) {
138
+ hooks.receiveDataStream.push(hook);
139
+ },
140
+ addErrorStreamHook(hook) {
141
+ hooks.errorStream.push(hook);
142
+ },
143
+ addStartStreamHook(hook) {
144
+ hooks.startStream.push(hook);
145
+ },
125
146
  request(params) {
126
147
  const headers = GG__namespace.reduce(defaultHeaders.entries(), GG__namespace.reduceFrom({}), ({ element, lastValue, next }) => {
127
148
  const value = element[1]();
@@ -135,8 +156,8 @@ function createHttpClient(clientParams) {
135
156
  baseUrl: config.baseUrl,
136
157
  ...params,
137
158
  headers: {
138
- ...params.headers,
139
159
  ...headers,
160
+ ...params.headers,
140
161
  },
141
162
  initParams: {
142
163
  ...params.initParams,
@@ -147,6 +168,10 @@ function createHttpClient(clientParams) {
147
168
  informationHeaderKey: config.informationHeaderKey,
148
169
  disabledPredicateMode: config.disabledPredictedMode,
149
170
  abortController: params.abortController ?? new AbortController(),
171
+ cacheStore: cacheStore,
172
+ clientCache: params.clientCache === "auto"
173
+ ? clientCache.autoCreateCacheKey
174
+ : params.clientCache,
150
175
  });
151
176
  },
152
177
  get: ((path, params) => self.request({
@@ -1,5 +1,5 @@
1
1
  import { type Kind, type MayBeGetter, type SimplifyTopLevel, type IsEqual } from "@duplojs/utils";
2
- import { type ClientRequestInitParams, type ServerRoute, type ServerRouteToClientRequestParams, type ServerRouteToClientResponse, type ClientRequestParams, type Hooks, type RequestHook, type ResponseHook, type InformationHook, type CodeHook, type ResponseTypeHook, type ExpectedResponseHook, type NotPredictedResponseHook, type ErrorHook, type GetServerRoutePath, type AllClientResponse, type BeforeRetryServerEventHook, type CloseServerEventHook, type ErrorServerEventHook, type StartServerEventHook, type ReceiveEventServerEventHook } from "./types";
2
+ import { type ClientRequestInitParams, type ServerRoute, type ServerRouteToClientRequestParams, type ServerRouteToClientResponse, type ClientRequestParams, type Hooks, type RequestHook, type ResponseHook, type InformationHook, type CodeHook, type ResponseTypeHook, type ExpectedResponseHook, type NotPredictedResponseHook, type ErrorHook, type GetServerRoutePath, type AllClientResponse, type BeforeRetryServerEventHook, type CloseServerEventHook, type ErrorServerEventHook, type StartServerEventHook, type ReceiveEventServerEventHook, type ClientCacheInitialValues, type ClientCacheStore, type CloseStreamHook, type ReceiveDataStreamHook, type ErrorStreamHook, type StartStreamHook } from "./types";
3
3
  import { PromiseRequest } from "./promiseRequest";
4
4
  export declare const httpClientKind: import("@duplojs/utils").KindHandler<import("@duplojs/utils").KindDefinition<"@DuplojsHttpClient/http-client", unknown>>;
5
5
  type MaybeRequestParams<GenericRequestParams extends object> = {} extends GenericRequestParams ? [params?: GenericRequestParams] : [params: GenericRequestParams];
@@ -21,11 +21,13 @@ export interface HttpClientConfig {
21
21
  readonly disabledPredictedMode: boolean;
22
22
  readonly credentials?: ClientRequestInitParams["credentials"];
23
23
  readonly cache?: ClientRequestInitParams["cache"];
24
+ readonly clientCacheInitialValues?: ClientCacheInitialValues;
24
25
  }
25
26
  export interface HttpClient<GenericServerRoute extends ServerRoute = ServerRoute, GenericHookParams extends Record<string, unknown> = Record<string, unknown>> extends Kind<typeof httpClientKind.definition> {
26
27
  readonly config: HttpClientConfig;
27
28
  readonly hooks: Hooks;
28
29
  readonly defaultHeaders: Map<string, () => (string | undefined | null)>;
30
+ readonly cacheStore: ClientCacheStore;
29
31
  addDefaultHeader(headerName: string, headerValue: MayBeGetter<string | undefined | null>): void;
30
32
  addDefaultHeaders(headers: Record<string, MayBeGetter<string | undefined | null>>): void;
31
33
  addRequestHook(hook: RequestHook<GenericHookParams>): void;
@@ -45,6 +47,10 @@ export interface HttpClient<GenericServerRoute extends ServerRoute = ServerRoute
45
47
  addErrorServerEventHook(hook: ErrorServerEventHook<GenericHookParams>): void;
46
48
  addStartServerEventHook(hook: StartServerEventHook<GenericHookParams>): void;
47
49
  addReceiveEventServerEventHook(hook: ReceiveEventServerEventHook<GenericHookParams>): void;
50
+ addCloseStreamHook(hook: CloseStreamHook<GenericHookParams>): void;
51
+ addReceiveDataStreamHook(hook: ReceiveDataStreamHook<GenericHookParams>): void;
52
+ addErrorStreamHook(hook: ErrorStreamHook<GenericHookParams>): void;
53
+ addStartStreamHook(hook: StartStreamHook<GenericHookParams>): void;
48
54
  request<GenericClientRequestParams extends ServerRouteToClientRequestParams<GenericServerRoute, GenericHookParams>, GenericMatchedPath extends GetServerRoutePath<Extract<GenericServerRoute, {
49
55
  method: GenericClientRequestParams["method"];
50
56
  }>, GenericClientRequestParams["path"]>>(params: GenericClientRequestParams): PromiseRequest<GenericHookParams, IsEqual<GenericServerRoute, ServerRoute> extends true ? AllClientResponse<GenericHookParams> : ServerRouteToClientResponse<Extract<GenericServerRoute, {
@@ -65,6 +71,7 @@ export interface CreateHttpClientParams {
65
71
  readonly informationHeaderKey?: string;
66
72
  readonly predictedHeaderKey?: string;
67
73
  readonly disabledPredictedMode?: boolean;
74
+ readonly clientCacheInitialValues?: ClientCacheInitialValues;
68
75
  }
69
76
  export declare function createHttpClient<GenericServerRoute extends ServerRoute = ServerRoute, GenericHookParams extends Record<string, unknown> = Record<string, unknown>>(clientParams: CreateHttpClientParams): HttpClient<GenericServerRoute, GenericHookParams>;
70
77
  export {};
@@ -2,9 +2,13 @@ import * as OO from '@duplojs/utils/object';
2
2
  import * as GG from '@duplojs/utils/generator';
3
3
  import { createClientKind } from './kind.mjs';
4
4
  import { PromiseRequest } from './promiseRequest.mjs';
5
+ import { autoCreateCacheKey } from './clientCache.mjs';
5
6
 
6
7
  const httpClientKind = createClientKind("http-client");
7
8
  function createHttpClient(clientParams) {
9
+ const cacheStore = new Map(clientParams.clientCacheInitialValues
10
+ ? OO.entries(clientParams.clientCacheInitialValues)
11
+ : []);
8
12
  const hooks = OO.override({
9
13
  request: [],
10
14
  response: [],
@@ -23,6 +27,10 @@ function createHttpClient(clientParams) {
23
27
  errorServerEvent: [],
24
28
  receiveEventServerEvent: [],
25
29
  startServerEvent: [],
30
+ closeStream: [],
31
+ errorStream: [],
32
+ receiveDataStream: [],
33
+ startStream: [],
26
34
  }, clientParams.hooks ?? {});
27
35
  const config = {
28
36
  baseUrl: clientParams.baseUrl,
@@ -37,6 +45,7 @@ function createHttpClient(clientParams) {
37
45
  config,
38
46
  hooks,
39
47
  defaultHeaders,
48
+ cacheStore,
40
49
  addDefaultHeader(headerName, headerValue) {
41
50
  defaultHeaders.set(headerName, typeof headerValue === "function"
42
51
  ? headerValue
@@ -100,6 +109,18 @@ function createHttpClient(clientParams) {
100
109
  addStartServerEventHook(hook) {
101
110
  hooks.startServerEvent.push(hook);
102
111
  },
112
+ addCloseStreamHook(hook) {
113
+ hooks.closeStream.push(hook);
114
+ },
115
+ addReceiveDataStreamHook(hook) {
116
+ hooks.receiveDataStream.push(hook);
117
+ },
118
+ addErrorStreamHook(hook) {
119
+ hooks.errorStream.push(hook);
120
+ },
121
+ addStartStreamHook(hook) {
122
+ hooks.startStream.push(hook);
123
+ },
103
124
  request(params) {
104
125
  const headers = GG.reduce(defaultHeaders.entries(), GG.reduceFrom({}), ({ element, lastValue, next }) => {
105
126
  const value = element[1]();
@@ -113,8 +134,8 @@ function createHttpClient(clientParams) {
113
134
  baseUrl: config.baseUrl,
114
135
  ...params,
115
136
  headers: {
116
- ...params.headers,
117
137
  ...headers,
138
+ ...params.headers,
118
139
  },
119
140
  initParams: {
120
141
  ...params.initParams,
@@ -125,6 +146,10 @@ function createHttpClient(clientParams) {
125
146
  informationHeaderKey: config.informationHeaderKey,
126
147
  disabledPredicateMode: config.disabledPredictedMode,
127
148
  abortController: params.abortController ?? new AbortController(),
149
+ cacheStore: cacheStore,
150
+ clientCache: params.clientCache === "auto"
151
+ ? autoCreateCacheKey
152
+ : params.clientCache,
128
153
  });
129
154
  },
130
155
  get: ((path, params) => self.request({
@@ -10,6 +10,8 @@ var queryToString = require('./queryToString.cjs');
10
10
  var promiseRequest = require('./promiseRequest.cjs');
11
11
  var unexpectedResponseError = require('./unexpectedResponseError.cjs');
12
12
  var serverSentEvents = require('./serverSentEvents.cjs');
13
+ var stream = require('./stream.cjs');
14
+ var clientCache = require('./clientCache.cjs');
13
15
 
14
16
 
15
17
 
@@ -18,17 +20,21 @@ exports.createHttpClient = httpClient.createHttpClient;
18
20
  exports.httpClientKind = httpClient.httpClientKind;
19
21
  exports.launchBeforeRetryServerEventHook = hooks.launchBeforeRetryServerEventHook;
20
22
  exports.launchCloseServerEventHook = hooks.launchCloseServerEventHook;
23
+ exports.launchCloseStreamHook = hooks.launchCloseStreamHook;
21
24
  exports.launchCodeHook = hooks.launchCodeHook;
22
25
  exports.launchErrorHook = hooks.launchErrorHook;
23
26
  exports.launchErrorServerEventHook = hooks.launchErrorServerEventHook;
27
+ exports.launchErrorStreamHook = hooks.launchErrorStreamHook;
24
28
  exports.launchExpectedResponseHook = hooks.launchExpectedResponseHook;
25
29
  exports.launchInformationHook = hooks.launchInformationHook;
26
30
  exports.launchNotPredictedHook = hooks.launchNotPredictedHook;
31
+ exports.launchReceiveDataStreamHook = hooks.launchReceiveDataStreamHook;
27
32
  exports.launchReceiveEventServerEventHook = hooks.launchReceiveEventServerEventHook;
28
33
  exports.launchRequestHook = hooks.launchRequestHook;
29
34
  exports.launchResponseHook = hooks.launchResponseHook;
30
35
  exports.launchResponseTypeHook = hooks.launchResponseTypeHook;
31
36
  exports.launchStartServerEventHook = hooks.launchStartServerEventHook;
37
+ exports.launchStartStreamHook = hooks.launchStartStreamHook;
32
38
  exports.getBody = getBody.getBody;
33
39
  exports.insertParamsInPath = insertParamsInPath.insertParamsInPath;
34
40
  exports.queryToString = queryToString.queryToString;
@@ -37,4 +43,10 @@ exports.UnexpectedCodeResponseError = unexpectedResponseError.UnexpectedCodeResp
37
43
  exports.UnexpectedInformationResponseError = unexpectedResponseError.UnexpectedInformationResponseError;
38
44
  exports.UnexpectedResponseError = unexpectedResponseError.UnexpectedResponseError;
39
45
  exports.UnexpectedResponseTypeError = unexpectedResponseError.UnexpectedResponseTypeError;
46
+ exports.isClientEventsResponse = serverSentEvents.isClientEventsResponse;
40
47
  exports.makeClientEventsResponse = serverSentEvents.makeClientEventsResponse;
48
+ exports.isClientStreamResponse = stream.isClientStreamResponse;
49
+ exports.makeClientStreamResponse = stream.makeClientStreamResponse;
50
+ exports.autoCreateCacheKey = clientCache.autoCreateCacheKey;
51
+ exports.findResponseFromCacheStore = clientCache.findResponseFromCacheStore;
52
+ exports.saveResponseInCacheStore = clientCache.saveResponseInCacheStore;
@@ -8,3 +8,5 @@ export * from "./queryToString";
8
8
  export * from "./promiseRequest";
9
9
  export * from "./unexpectedResponseError";
10
10
  export * from "./serverSentEvents";
11
+ export * from "./stream";
12
+ export * from "./clientCache";
@@ -1,10 +1,12 @@
1
1
  import './types/index.mjs';
2
2
  export { createClientKind } from './kind.mjs';
3
3
  export { createHttpClient, httpClientKind } from './httpClient.mjs';
4
- export { launchBeforeRetryServerEventHook, launchCloseServerEventHook, launchCodeHook, launchErrorHook, launchErrorServerEventHook, launchExpectedResponseHook, launchInformationHook, launchNotPredictedHook, launchReceiveEventServerEventHook, launchRequestHook, launchResponseHook, launchResponseTypeHook, launchStartServerEventHook } from './hooks.mjs';
4
+ export { launchBeforeRetryServerEventHook, launchCloseServerEventHook, launchCloseStreamHook, launchCodeHook, launchErrorHook, launchErrorServerEventHook, launchErrorStreamHook, launchExpectedResponseHook, launchInformationHook, launchNotPredictedHook, launchReceiveDataStreamHook, launchReceiveEventServerEventHook, launchRequestHook, launchResponseHook, launchResponseTypeHook, launchStartServerEventHook, launchStartStreamHook } from './hooks.mjs';
5
5
  export { getBody } from './getBody.mjs';
6
6
  export { insertParamsInPath } from './insertParamsInPath.mjs';
7
7
  export { queryToString } from './queryToString.mjs';
8
8
  export { PromiseRequest } from './promiseRequest.mjs';
9
9
  export { UnexpectedCodeResponseError, UnexpectedInformationResponseError, UnexpectedResponseError, UnexpectedResponseTypeError } from './unexpectedResponseError.mjs';
10
- export { makeClientEventsResponse } from './serverSentEvents.mjs';
10
+ export { isClientEventsResponse, makeClientEventsResponse } from './serverSentEvents.mjs';
11
+ export { isClientStreamResponse, makeClientStreamResponse } from './stream.mjs';
12
+ export { autoCreateCacheKey, findResponseFromCacheStore, saveResponseInCacheStore } from './clientCache.mjs';
@@ -10,6 +10,8 @@ var SS = require('@duplojs/utils/string');
10
10
  var AA = require('@duplojs/utils/array');
11
11
  var unexpectedResponseError = require('./unexpectedResponseError.cjs');
12
12
  var serverSentEvents = require('./serverSentEvents.cjs');
13
+ var clientCache = require('./clientCache.cjs');
14
+ var stream = require('./stream.cjs');
13
15
 
14
16
  function _interopNamespaceDefault(e) {
15
17
  var n = Object.create(null);
@@ -151,12 +153,22 @@ class PromiseRequest extends Promise {
151
153
  void this.then(EE__namespace.whenIsRight((response) => {
152
154
  if ((response.predicted === true
153
155
  || response.requestParams.disabledPredicateMode === true)
154
- && Symbol.asyncIterator in response) {
156
+ && serverSentEvents.isClientEventsResponse(response)) {
155
157
  response.onReceiveEvent(eventName, callback);
156
158
  }
157
159
  }));
158
160
  return this;
159
161
  }
162
+ whenReceiveDataStream(callback) {
163
+ void this.then(EE__namespace.whenIsRight((response) => {
164
+ if ((response.predicted === true
165
+ || response.requestParams.disabledPredicateMode === true)
166
+ && stream.isClientStreamResponse(response)) {
167
+ response.onStream("receiveData", callback);
168
+ }
169
+ }));
170
+ return this;
171
+ }
160
172
  iWantInformation(information) {
161
173
  const formattedInformation = AA__namespace.coalescing(information);
162
174
  return this.then(EE__namespace.whenIsRight((response) => {
@@ -318,7 +330,7 @@ class PromiseRequest extends Promise {
318
330
  if (EE__namespace.isRight(maybeResponse)) {
319
331
  return utils.unwrap(maybeResponse);
320
332
  }
321
- throw new unexpectedResponseError.UnexpectedResponseTypeError("informational", utils.unwrap(maybeResponse));
333
+ throw new unexpectedResponseError.UnexpectedResponseTypeError("serverError", utils.unwrap(maybeResponse));
322
334
  });
323
335
  }
324
336
  iWantExpectedResponseOrThrow() {
@@ -345,6 +357,10 @@ class PromiseRequest extends Promise {
345
357
  return Promise;
346
358
  }
347
359
  static fetch(requestParams) {
360
+ const cachedResponse = clientCache.findResponseFromCacheStore(requestParams);
361
+ if (cachedResponse) {
362
+ return Promise.resolve(EE__namespace.right("response", cachedResponse));
363
+ }
348
364
  const path = insertParamsInPath.insertParamsInPath(requestParams.path, requestParams.params);
349
365
  const query = queryToString.queryToString(requestParams.query);
350
366
  const url = query
@@ -359,7 +375,7 @@ class PromiseRequest extends Promise {
359
375
  body = body.toString();
360
376
  }
361
377
  else if (body instanceof utils.TheFormData) {
362
- headers["content-type-options"] = "advanced";
378
+ headers["x-duplojs-body-options"] = "advanced";
363
379
  }
364
380
  else if ((body
365
381
  && typeof body === "object"
@@ -383,10 +399,9 @@ class PromiseRequest extends Promise {
383
399
  signal: requestParams.abortController.signal,
384
400
  };
385
401
  return fetch(fetchUrl, fetchInitParams)
386
- .then((response) => getBody.getBody(response)
387
- .then((body) => {
402
+ .then((response) => {
388
403
  const clientResponse = {
389
- body,
404
+ body: undefined,
390
405
  information: response.headers.get(requestParams.informationHeaderKey) ?? undefined,
391
406
  code: response.status.toString(),
392
407
  ok: (response.status < 500)
@@ -403,8 +418,18 @@ class PromiseRequest extends Promise {
403
418
  if (response.headers.get("content-type")?.includes("text/event-stream")) {
404
419
  return EE__namespace.right("response", serverSentEvents.makeClientEventsResponse(clientResponse, fetchUrl, fetchInitParams));
405
420
  }
406
- return EE__namespace.right("response", clientResponse);
407
- }))
421
+ if (response.headers.get("x-duplojs-body-options")?.includes("stream")) {
422
+ return EE__namespace.right("response", stream.makeClientStreamResponse(clientResponse));
423
+ }
424
+ return getBody.getBody(response)
425
+ .then((body) => {
426
+ clientResponse.body = body;
427
+ if (clientResponse.code.startsWith("2")) {
428
+ clientCache.saveResponseInCacheStore(requestParams, clientResponse);
429
+ }
430
+ return EE__namespace.right("response", clientResponse);
431
+ });
432
+ })
408
433
  .catch((error) => EE__namespace.left("request-error", {
409
434
  error,
410
435
  requestParams,