electrodb 2.4.1 → 2.5.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.
@@ -0,0 +1,179 @@
1
+ const { TableIndex, TransactionMethods } = require('./types');
2
+ const { getEntityIdentifiers, matchToEntityAlias } = require('./entity');
3
+
4
+ function cleanseCanceledData(index = TableIndex, entities, data = {}, config = {}) {
5
+ if (config.raw) {
6
+ return data;
7
+ }
8
+ const identifiers = getEntityIdentifiers(entities);
9
+ const canceled = data.canceled || [];
10
+ const paramItems = config._paramItems || [];
11
+ const results = [];
12
+ for (let i = 0; i < canceled.length; i++) {
13
+ const { Item, Code, Message } = canceled[i] || {};
14
+ const paramItem = paramItems[i];
15
+ const code = Code || 'None';
16
+ const rejected = code !== 'None';
17
+ const result = {
18
+ rejected,
19
+ code,
20
+ message: Message,
21
+ }
22
+
23
+ if (Item) {
24
+ const entityAlias = matchToEntityAlias({
25
+ record: Item,
26
+ paramItem,
27
+ identifiers
28
+ });
29
+ result.item = entities[entityAlias].formatResponse({Item}, index, {
30
+ ...config,
31
+ pager: false,
32
+ parse: undefined,
33
+ }).data;
34
+ } else {
35
+ result.item = null;
36
+ }
37
+
38
+ results.push(result);
39
+ }
40
+
41
+ return results;
42
+ }
43
+
44
+ function cleanseTransactionData(index = TableIndex, entities, data = {}, config = {}) {
45
+ if (config.raw) {
46
+ return data;
47
+ }
48
+ const identifiers = getEntityIdentifiers(entities);
49
+ data.Items = data.Items || [];
50
+ const paramItems = config._paramItems || [];
51
+ const results = [];
52
+ for (let i = 0; i < data.Items.length; i++) {
53
+ const record = data.Items[i];
54
+ if (!record) {
55
+ results.push(null);
56
+ continue;
57
+ }
58
+
59
+ const paramItem = paramItems[i];
60
+ const entityAlias = matchToEntityAlias({paramItem, identifiers, record});
61
+ if (!entityAlias) {
62
+ continue;
63
+ }
64
+
65
+ // pager=false because we don't want the entity trying to parse the lastEvaluatedKey
66
+ let formatted = entities[entityAlias].formatResponse({ Item: record }, index, {
67
+ ...config,
68
+ pager: false,
69
+ parse: undefined
70
+ });
71
+
72
+ results.push(formatted.data);
73
+ }
74
+
75
+ return results.map(item => ({
76
+ rejected: false,
77
+ item,
78
+ }));
79
+ }
80
+
81
+ function createTransaction(options) {
82
+ const { fn, method, getEntities } = options;
83
+ const operations = {
84
+ params: (options = {}) => {
85
+ const paramItems = fn(getEntities());
86
+ const params = {
87
+ TransactItems: paramItems,
88
+ };
89
+
90
+ if (typeof options.token === 'string' && options.token.length) {
91
+ params['ClientRequestToken'] = options.token;
92
+ }
93
+ if (options._returnParamItems) {
94
+ return { params, paramItems };
95
+ }
96
+ return params;
97
+ },
98
+ go: async (options) => {
99
+ const driver = Object.values(getEntities())[0];
100
+
101
+ if (!driver) {
102
+ throw new Error('At least one entity must exist to perform a transaction');
103
+ }
104
+
105
+ const { params, paramItems } = operations.params({
106
+ ...options,
107
+ _returnParamItems: true
108
+ });
109
+
110
+ let canceled = false;
111
+ if (paramItems.length === 0) {
112
+ return {
113
+ canceled,
114
+ data: [],
115
+ }
116
+ }
117
+
118
+ const response = await driver.go(method, params, {
119
+ ...options,
120
+ parse: (options, data) => {
121
+ if (options.raw) {
122
+ return data;
123
+ } else if (data.canceled) {
124
+ canceled = true;
125
+ return cleanseCanceledData(TableIndex, getEntities(), data, {
126
+ ...options,
127
+ _isTransaction: true,
128
+ _paramItems: paramItems,
129
+ });
130
+ } else if (data.Responses) {
131
+ return cleanseTransactionData(TableIndex, getEntities(), {
132
+ Items: data.Responses.map(response => response.Item)
133
+ }, {
134
+ ...options,
135
+ _isTransaction: true,
136
+ _paramItems: paramItems,
137
+ });
138
+ } else {
139
+ return new Array(paramItems ? paramItems.length : 0).fill({
140
+ item: null,
141
+ code: 'None',
142
+ rejected: false,
143
+ message: undefined,
144
+ });
145
+ }
146
+ }
147
+ });
148
+
149
+ return {
150
+ ...response,
151
+ canceled,
152
+ }
153
+ }
154
+ }
155
+
156
+ return operations;
157
+ }
158
+
159
+ function createWriteTransaction(entities, fn) {
160
+ return createTransaction({
161
+ fn,
162
+ method: TransactionMethods.transactWrite,
163
+ getEntities: () => entities,
164
+ });
165
+ }
166
+
167
+ function createGetTransaction(entities, fn) {
168
+ return createTransaction({
169
+ fn,
170
+ method: TransactionMethods.transactGet,
171
+ getEntities: () => entities,
172
+ });
173
+ }
174
+
175
+ module.exports = {
176
+ createTransaction,
177
+ createWriteTransaction,
178
+ createGetTransaction,
179
+ }
package/src/types.js CHANGED
@@ -23,6 +23,7 @@ const QueryTypes = {
23
23
  };
24
24
 
25
25
  const MethodTypes = {
26
+ check: "check",
26
27
  put: "put",
27
28
  get: "get",
28
29
  query: "query",
@@ -35,8 +36,27 @@ const MethodTypes = {
35
36
  batchGet: "batchGet",
36
37
  batchWrite: "batchWrite",
37
38
  upsert: "upsert",
39
+ transactWrite: "transactWrite",
40
+ transactGet: "transactGet",
38
41
  };
39
42
 
43
+ const TransactionMethods = {
44
+ transactWrite: MethodTypes.transactWrite,
45
+ transactGet: MethodTypes.transactGet,
46
+ }
47
+
48
+ const TransactionOperations = {
49
+ [MethodTypes.get]: "Get",
50
+ [MethodTypes.check]: "ConditionCheck",
51
+ [MethodTypes.put]: "Put",
52
+ [MethodTypes.create]: "Put",
53
+ [MethodTypes.upsert]: "Update",
54
+ [MethodTypes.update]: "Update",
55
+ [MethodTypes.patch]: "Update",
56
+ [MethodTypes.remove]: "Delete",
57
+ [MethodTypes.delete]: "Delete",
58
+ }
59
+
40
60
  const MethodTypeTranslation = {
41
61
  put: "put",
42
62
  get: "get",
@@ -50,6 +70,8 @@ const MethodTypeTranslation = {
50
70
  batchGet: "batchGet",
51
71
  batchWrite: "batchWrite",
52
72
  upsert: "update",
73
+ transactWrite: 'transactWrite',
74
+ transactGet: 'transactGet',
53
75
  }
54
76
 
55
77
  const IndexTypes = {
@@ -198,6 +220,7 @@ const ItemOperations = {
198
220
  };
199
221
 
200
222
  const AttributeProxySymbol = Symbol("attribute_proxy");
223
+ const TransactionCommitSymbol = Symbol('transaction_commit');
201
224
 
202
225
  const BuilderTypes = {
203
226
  update: "update",
@@ -325,4 +348,7 @@ module.exports = {
325
348
  AllPages,
326
349
  ResultOrderOption,
327
350
  ResultOrderParam,
351
+ TransactionCommitSymbol,
352
+ TransactionOperations,
353
+ TransactionMethods,
328
354
  };
package/src/where.js CHANGED
@@ -76,6 +76,7 @@ class WhereFactory {
76
76
  case MethodTypes.remove:
77
77
  case MethodTypes.upsert:
78
78
  case MethodTypes.get:
79
+ case MethodTypes.check:
79
80
  return ExpressionTypes.ConditionExpression
80
81
  default:
81
82
  return ExpressionTypes.FilterExpression
@@ -108,7 +109,7 @@ class WhereFactory {
108
109
  let filterParents = Object.entries(injected)
109
110
  .filter(clause => {
110
111
  let [name, { children }] = clause;
111
- return children.includes("go");
112
+ return children.find(child => ['go', 'commit'].includes(child));
112
113
  })
113
114
  .map(([name]) => name);
114
115
  let modelFilters = Object.keys(filters);
@@ -118,7 +119,7 @@ class WhereFactory {
118
119
  injected[name] = {
119
120
  name,
120
121
  action: this.buildClause(filter),
121
- children: ["params", "go", "where", ...modelFilters],
122
+ children: ["params", "go", "commit", "where", ...modelFilters],
122
123
  };
123
124
  }
124
125
  filterChildren.push("where");
@@ -127,7 +128,7 @@ class WhereFactory {
127
128
  action: (entity, state, fn) => {
128
129
  return this.buildClause(fn)(entity, state);
129
130
  },
130
- children: ["params", "go", "where", ...modelFilters],
131
+ children: ["params", "go", "commit", "where", ...modelFilters],
131
132
  };
132
133
  for (let parent of filterParents) {
133
134
  injected[parent] = { ...injected[parent] };
package/notes DELETED
@@ -1,8 +0,0 @@
1
- - add hydrate option to query
2
- - add hydrate option to collection
3
- - implement hydrate on entity query
4
- - implement hydrate on collection query
5
- - add index property to signify only keys are present
6
- - skip for match/find
7
- - do not apply automatic filters on queries
8
- - validate