@resistdesign/voltra 3.0.0-alpha.51 → 3.0.0-alpha.53
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.
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
*
|
|
4
|
-
* DynamoDB-backed data item driver for TypeInfo ORM. Supports CRUD and
|
|
5
|
-
*
|
|
4
|
+
* DynamoDB-backed data item driver for TypeInfo ORM. Supports CRUD and list
|
|
5
|
+
* operations using scans by default, or GSI-backed queries when a sort field is
|
|
6
|
+
* supplied.
|
|
6
7
|
*/
|
|
7
8
|
import { DataItemDBDriver, DataItemDBDriverConfig, SupportedDataItemDBDriverEntry } from "./common/Types";
|
|
8
9
|
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
package/api/index.js
CHANGED
|
@@ -5964,6 +5964,8 @@ var DynamoDBDataItemDBDriver = class {
|
|
|
5964
5964
|
ExpressionAttributeNames,
|
|
5965
5965
|
ExpressionAttributeValues
|
|
5966
5966
|
} = createFilterExpression(fieldCriteria, logicalOperator);
|
|
5967
|
+
const primarySortField = sortFields?.[0];
|
|
5968
|
+
const indexName = primarySortField?.field;
|
|
5967
5969
|
const params = {
|
|
5968
5970
|
TableName: tableName,
|
|
5969
5971
|
Select: selectedFields && selectedFields.length > 0 ? "SPECIFIC_ATTRIBUTES" : "ALL_ATTRIBUTES",
|
|
@@ -5998,14 +6000,24 @@ var DynamoDBDataItemDBDriver = class {
|
|
|
5998
6000
|
};
|
|
5999
6001
|
}
|
|
6000
6002
|
}
|
|
6001
|
-
const
|
|
6003
|
+
const commandInput = indexName ? {
|
|
6004
|
+
...params,
|
|
6005
|
+
IndexName: indexName,
|
|
6006
|
+
KeyConditionExpression: FilterExpression,
|
|
6007
|
+
ExclusiveStartKey: structuredCursor,
|
|
6008
|
+
Limit: itemsPerPage,
|
|
6009
|
+
ScanIndexForward: !primarySortField?.reverse
|
|
6010
|
+
} : {
|
|
6002
6011
|
...params,
|
|
6003
6012
|
ExclusiveStartKey: structuredCursor,
|
|
6004
6013
|
Limit: itemsPerPage
|
|
6005
|
-
}
|
|
6006
|
-
const
|
|
6014
|
+
};
|
|
6015
|
+
const command = indexName ? new QueryCommand(commandInput) : new ScanCommand(commandInput);
|
|
6016
|
+
const { Items = [], LastEvaluatedKey } = await this.dynamoDBClient.send(
|
|
6017
|
+
command
|
|
6018
|
+
);
|
|
6007
6019
|
const unmarshalledItems = Items.map((item) => unmarshall(item));
|
|
6008
|
-
const sortedItems = getSortedItems(sortFields, unmarshalledItems);
|
|
6020
|
+
const sortedItems = indexName ? unmarshalledItems : getSortedItems(sortFields, unmarshalledItems);
|
|
6009
6021
|
return {
|
|
6010
6022
|
items: sortedItems,
|
|
6011
6023
|
cursor: LastEvaluatedKey ? JSON.stringify(unmarshall(LastEvaluatedKey)) : void 0
|
package/app/index.js
CHANGED
|
@@ -98,6 +98,7 @@ var ApplicationStateProvider = ({
|
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
// src/app/utils/Service.ts
|
|
101
|
+
var activeRequestControllers = /* @__PURE__ */ new Map();
|
|
101
102
|
var getFullUrl = (protocol, domain, basePath = "", path = "", port) => {
|
|
102
103
|
const normalizedProtocol = protocol.endsWith(":") ? protocol.slice(0, -1) : protocol;
|
|
103
104
|
const normalizedDomain = domain.replace(/\/+$/, "");
|
|
@@ -113,39 +114,56 @@ var getFullUrl = (protocol, domain, basePath = "", path = "", port) => {
|
|
|
113
114
|
const normalizedPath = fullPath ? fullPath.startsWith(PATH_DELIMITER) ? fullPath : `${PATH_DELIMITER}${fullPath}` : PATH_DELIMITER;
|
|
114
115
|
return `${normalizedProtocol}://${normalizedDomain}${portString}${normalizedPath}`;
|
|
115
116
|
};
|
|
116
|
-
var sendServiceRequest = async (config, path = "", args = []) => {
|
|
117
|
+
var sendServiceRequest = async (config, path = "", args = [], requestConfig = {}) => {
|
|
117
118
|
const { protocol, domain, port, basePath = "", authorization = "" } = config;
|
|
119
|
+
const { cancelPendingOnNewRequest = false } = requestConfig;
|
|
118
120
|
const fullUrl = getFullUrl(protocol, domain, basePath, path, port);
|
|
121
|
+
const abortController = new AbortController();
|
|
122
|
+
const previousRequestController = activeRequestControllers.get(fullUrl);
|
|
123
|
+
if (cancelPendingOnNewRequest) {
|
|
124
|
+
previousRequestController?.abort();
|
|
125
|
+
activeRequestControllers.set(fullUrl, abortController);
|
|
126
|
+
}
|
|
119
127
|
const requestHeaders = {
|
|
120
128
|
"Content-Type": "application/json",
|
|
121
129
|
...!!authorization ? {
|
|
122
130
|
Authorization: `Bearer ${authorization}`
|
|
123
131
|
} : {}
|
|
124
132
|
};
|
|
125
|
-
const response = await fetch(fullUrl, {
|
|
126
|
-
headers: requestHeaders,
|
|
127
|
-
credentials: "same-origin",
|
|
128
|
-
method: "POST",
|
|
129
|
-
body: JSON.stringify(args)
|
|
130
|
-
});
|
|
131
|
-
const { ok: responseIsOk } = response;
|
|
132
|
-
const textData = await response.text();
|
|
133
|
-
let data = textData;
|
|
134
133
|
try {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
134
|
+
const response = await fetch(fullUrl, {
|
|
135
|
+
headers: requestHeaders,
|
|
136
|
+
credentials: "same-origin",
|
|
137
|
+
method: "POST",
|
|
138
|
+
body: JSON.stringify(args),
|
|
139
|
+
signal: abortController.signal
|
|
140
|
+
});
|
|
141
|
+
const { ok: responseIsOk } = response;
|
|
142
|
+
const textData = await response.text();
|
|
143
|
+
let data = textData;
|
|
144
|
+
try {
|
|
145
|
+
data = JSON.parse(textData);
|
|
146
|
+
} catch (error) {
|
|
143
147
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
if (typeof data === "object") {
|
|
149
|
+
if (responseIsOk) {
|
|
150
|
+
return data;
|
|
151
|
+
} else {
|
|
152
|
+
throw data;
|
|
153
|
+
}
|
|
147
154
|
} else {
|
|
148
|
-
|
|
155
|
+
if (responseIsOk) {
|
|
156
|
+
return { data };
|
|
157
|
+
} else {
|
|
158
|
+
throw { message: data };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} finally {
|
|
162
|
+
if (cancelPendingOnNewRequest) {
|
|
163
|
+
const activeRequestController = activeRequestControllers.get(fullUrl);
|
|
164
|
+
if (activeRequestController === abortController) {
|
|
165
|
+
activeRequestControllers.delete(fullUrl);
|
|
166
|
+
}
|
|
149
167
|
}
|
|
150
168
|
}
|
|
151
169
|
};
|
|
@@ -155,10 +173,12 @@ var useApplicationStateLoader = (config) => {
|
|
|
155
173
|
remoteProcedureCall,
|
|
156
174
|
resetOnError = false,
|
|
157
175
|
onLoadComplete,
|
|
158
|
-
manual = false
|
|
176
|
+
manual = false,
|
|
177
|
+
cancelPendingOnNewRequest = false
|
|
159
178
|
} = config;
|
|
160
179
|
const { args = [] } = remoteProcedureCall;
|
|
161
180
|
const argsRef = useRef(args);
|
|
181
|
+
const requestSequenceRef = useRef(0);
|
|
162
182
|
argsRef.current = args;
|
|
163
183
|
const [cacheValidity, setCacheValidity] = useState({});
|
|
164
184
|
const [loading, setLoading] = useState(false);
|
|
@@ -170,6 +190,7 @@ var useApplicationStateLoader = (config) => {
|
|
|
170
190
|
}, []);
|
|
171
191
|
const makeRemoteProcedureCall = useCallback(
|
|
172
192
|
async (...directArgs) => {
|
|
193
|
+
const requestSequence = ++requestSequenceRef.current;
|
|
173
194
|
let success = false;
|
|
174
195
|
setLoading(true);
|
|
175
196
|
setLatestError(void 0);
|
|
@@ -178,23 +199,43 @@ var useApplicationStateLoader = (config) => {
|
|
|
178
199
|
const result = await sendServiceRequest(
|
|
179
200
|
serviceConfig,
|
|
180
201
|
path,
|
|
181
|
-
directArgs
|
|
202
|
+
directArgs,
|
|
203
|
+
{
|
|
204
|
+
cancelPendingOnNewRequest
|
|
205
|
+
}
|
|
182
206
|
);
|
|
207
|
+
if (requestSequence !== requestSequenceRef.current) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
183
210
|
success = true;
|
|
184
211
|
onChange(result);
|
|
185
212
|
setModified(false);
|
|
186
213
|
} catch (error) {
|
|
214
|
+
if (requestSequence !== requestSequenceRef.current) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
187
217
|
success = false;
|
|
188
218
|
setLatestError(error);
|
|
189
219
|
if (resetOnError) {
|
|
190
220
|
onChange(void 0);
|
|
191
221
|
setModified(false);
|
|
192
222
|
}
|
|
223
|
+
} finally {
|
|
224
|
+
if (requestSequence !== requestSequenceRef.current) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
setLoading(false);
|
|
228
|
+
onLoadComplete?.(success);
|
|
193
229
|
}
|
|
194
|
-
setLoading(false);
|
|
195
|
-
onLoadComplete?.(success);
|
|
196
230
|
},
|
|
197
|
-
[
|
|
231
|
+
[
|
|
232
|
+
remoteProcedureCall,
|
|
233
|
+
onChange,
|
|
234
|
+
setModified,
|
|
235
|
+
resetOnError,
|
|
236
|
+
onLoadComplete,
|
|
237
|
+
cancelPendingOnNewRequest
|
|
238
|
+
]
|
|
198
239
|
);
|
|
199
240
|
const appStateLoader = useMemo(
|
|
200
241
|
() => ({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* tracks loading/error state, and populates ApplicationState via identifiers.
|
|
6
6
|
*/
|
|
7
7
|
import { ApplicationStateIdentifier, type ApplicationStateValue, type ApplicationStateValueController } from "./ApplicationState";
|
|
8
|
-
import { ServiceConfig } from "./Service";
|
|
8
|
+
import { type ServiceConfig, type ServiceRequestConfig } from "./Service";
|
|
9
9
|
/**
|
|
10
10
|
* Access and track the loading of an application state value.
|
|
11
11
|
* */
|
|
@@ -49,7 +49,7 @@ export type RemoteProcedureCall<ArgsType extends any[] = any[]> = {
|
|
|
49
49
|
/**
|
|
50
50
|
* The configuration for an application state loader.
|
|
51
51
|
* */
|
|
52
|
-
export type ApplicationStateLoaderConfig<ValueType = ApplicationStateValue, ArgsType extends any[] = any[]> = {
|
|
52
|
+
export type ApplicationStateLoaderConfig<ValueType = ApplicationStateValue, ArgsType extends any[] = any[]> = ServiceRequestConfig & {
|
|
53
53
|
/**
|
|
54
54
|
* Identifier for the value to update in application state.
|
|
55
55
|
* */
|
package/app/utils/Service.d.ts
CHANGED
|
@@ -23,6 +23,17 @@ export type ServiceConfig = {
|
|
|
23
23
|
* */
|
|
24
24
|
authorization?: string;
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Additional request behavior for a service call.
|
|
28
|
+
* */
|
|
29
|
+
export type ServiceRequestConfig = {
|
|
30
|
+
/**
|
|
31
|
+
* Abort the prior in-flight request for the same service URL before starting a new one.
|
|
32
|
+
*
|
|
33
|
+
* @default false
|
|
34
|
+
* */
|
|
35
|
+
cancelPendingOnNewRequest?: boolean;
|
|
36
|
+
};
|
|
26
37
|
/**
|
|
27
38
|
* Build the full URL for a service call from config pieces.
|
|
28
39
|
*
|
|
@@ -40,6 +51,7 @@ export declare const getFullUrl: (protocol: string, domain: string, basePath?: s
|
|
|
40
51
|
* @param config - Service configuration for the request.
|
|
41
52
|
* @param path - Endpoint path to call.
|
|
42
53
|
* @param args - JSON-serializable arguments to send.
|
|
54
|
+
* @param requestConfig - Additional request behavior configuration.
|
|
43
55
|
* @returns Parsed JSON response.
|
|
44
56
|
*/
|
|
45
|
-
export declare const sendServiceRequest: (config: ServiceConfig, path?: string, args?: any[]) => Promise<any>;
|
|
57
|
+
export declare const sendServiceRequest: (config: ServiceConfig, path?: string, args?: any[], requestConfig?: ServiceRequestConfig) => Promise<any>;
|