shuttlepro-shared 1.2.6 → 1.2.8
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.
|
@@ -92,7 +92,6 @@ const {
|
|
|
92
92
|
deleteRedisData,
|
|
93
93
|
} = require("../../config/redis");
|
|
94
94
|
|
|
95
|
-
// Configuration as a pure function
|
|
96
95
|
const createConfig = (env) => ({
|
|
97
96
|
cache: {
|
|
98
97
|
keys: {
|
|
@@ -106,20 +105,13 @@ const createConfig = (env) => ({
|
|
|
106
105
|
(labelId) => `labels:details:${labelId}`
|
|
107
106
|
),
|
|
108
107
|
},
|
|
109
|
-
expiry: 60 * 60,
|
|
108
|
+
expiry: 60 * 60,
|
|
110
109
|
},
|
|
111
110
|
});
|
|
112
111
|
|
|
113
|
-
// Pure query construction function
|
|
114
|
-
const constructQuery = R.curry((baseQuery, additionalQuery) =>
|
|
115
|
-
R.mergeDeepRight(baseQuery, additionalQuery)
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
// Functional label repository
|
|
119
112
|
const createLabelRepository = (dependencies) => {
|
|
120
113
|
const { Label, redisConfig } = dependencies;
|
|
121
114
|
|
|
122
|
-
// Pure function for generating cache key
|
|
123
115
|
const generateCacheKey = R.pipe(
|
|
124
116
|
R.toPairs,
|
|
125
117
|
R.map(([key, value]) => `${key}:${JSON.stringify(value)}`),
|
|
@@ -127,7 +119,6 @@ const createLabelRepository = (dependencies) => {
|
|
|
127
119
|
R.concat("labels:query:")
|
|
128
120
|
);
|
|
129
121
|
|
|
130
|
-
// Caching Higher-Order Function
|
|
131
122
|
const withCache = R.curry(async (cacheKey, fetchFn, forceFresh = false) => {
|
|
132
123
|
if (!forceFresh) {
|
|
133
124
|
const cachedData = await getRedisData(cacheKey);
|
|
@@ -143,7 +134,6 @@ const createLabelRepository = (dependencies) => {
|
|
|
143
134
|
return data;
|
|
144
135
|
});
|
|
145
136
|
|
|
146
|
-
// Pure validation function
|
|
147
137
|
const validateLabel = R.curry((existingLabels, newLabel) => {
|
|
148
138
|
const isDuplicate = R.any(
|
|
149
139
|
(label) =>
|
|
@@ -158,9 +148,7 @@ const createLabelRepository = (dependencies) => {
|
|
|
158
148
|
return newLabel;
|
|
159
149
|
});
|
|
160
150
|
|
|
161
|
-
// Functional CRUD Operations
|
|
162
151
|
const createLabel = async (labelData) => {
|
|
163
|
-
// Compose validation and creation
|
|
164
152
|
const create = R.pipe(
|
|
165
153
|
(label) => label.save(),
|
|
166
154
|
validateLabel(await Label.find()),
|
|
@@ -170,7 +158,6 @@ const createLabelRepository = (dependencies) => {
|
|
|
170
158
|
return create(labelData);
|
|
171
159
|
};
|
|
172
160
|
|
|
173
|
-
// Advanced finding with functional composition
|
|
174
161
|
const findLabels = R.curry(async (options = {}, query = {}) => {
|
|
175
162
|
const {
|
|
176
163
|
lean = true,
|
|
@@ -179,7 +166,6 @@ const createLabelRepository = (dependencies) => {
|
|
|
179
166
|
limit = 100,
|
|
180
167
|
} = options;
|
|
181
168
|
|
|
182
|
-
// Compose query construction and execution
|
|
183
169
|
const executeQuery = R.pipe(
|
|
184
170
|
R.when(R.always(lean), R.map(R.prop("toObject"))),
|
|
185
171
|
(labels) => (populate.length ? Label.populate(labels, populate) : labels),
|
|
@@ -188,21 +174,26 @@ const createLabelRepository = (dependencies) => {
|
|
|
188
174
|
R.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt), labels)
|
|
189
175
|
);
|
|
190
176
|
|
|
191
|
-
|
|
192
|
-
const cachedFind = withCache(
|
|
177
|
+
const cachedFind = await withCache(
|
|
193
178
|
generateCacheKey(query),
|
|
194
179
|
() => Label.find(query).exec(),
|
|
195
180
|
false
|
|
196
181
|
);
|
|
197
182
|
|
|
198
|
-
return executeQuery(
|
|
183
|
+
return executeQuery(cachedFind);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const findAllLabels = R.curry(async (query = {}) => {
|
|
187
|
+
return await withCache(
|
|
188
|
+
generateCacheKey(query),
|
|
189
|
+
() => Label.find(query).exec(),
|
|
190
|
+
false
|
|
191
|
+
);
|
|
199
192
|
});
|
|
200
193
|
|
|
201
|
-
// Functional update with immutable updates
|
|
202
194
|
const updateLabel = R.curry(async (labelId, updateData) => {
|
|
203
195
|
const update = R.pipe(
|
|
204
196
|
R.tap(async (updatedLabel) => {
|
|
205
|
-
// Update cache atomically
|
|
206
197
|
await setRedisData(
|
|
207
198
|
redisConfig.cache.keys.LABEL_DETAILS(labelId),
|
|
208
199
|
updatedLabel.toObject()
|
|
@@ -210,7 +201,6 @@ const createLabelRepository = (dependencies) => {
|
|
|
210
201
|
}),
|
|
211
202
|
(label) => label.save(),
|
|
212
203
|
(label) => {
|
|
213
|
-
// Immutable update
|
|
214
204
|
const updatedFields = R.mergeDeepRight(label.toObject(), updateData);
|
|
215
205
|
return Label.hydrate(updatedFields);
|
|
216
206
|
},
|
|
@@ -220,11 +210,9 @@ const createLabelRepository = (dependencies) => {
|
|
|
220
210
|
return update();
|
|
221
211
|
});
|
|
222
212
|
|
|
223
|
-
// Functional delete with side effect management
|
|
224
213
|
const deleteLabel = async (labelId) => {
|
|
225
214
|
const performDelete = R.pipe(
|
|
226
215
|
R.tap(async () => {
|
|
227
|
-
// Clear all related caches
|
|
228
216
|
await deleteRedisData(redisConfig.cache.keys.LABEL_DETAILS(labelId));
|
|
229
217
|
}),
|
|
230
218
|
(label) => label.remove(),
|
|
@@ -234,22 +222,20 @@ const createLabelRepository = (dependencies) => {
|
|
|
234
222
|
return performDelete();
|
|
235
223
|
};
|
|
236
224
|
|
|
237
|
-
// Advanced filtering with functional transformations
|
|
238
225
|
const filterLabels = R.curry((filterFn, labels) =>
|
|
239
226
|
R.filter(filterFn, labels)
|
|
240
227
|
);
|
|
241
228
|
|
|
242
|
-
// Public API
|
|
243
229
|
return {
|
|
244
230
|
createLabel,
|
|
245
231
|
findLabels,
|
|
232
|
+
findAllLabels,
|
|
246
233
|
updateLabel,
|
|
247
234
|
deleteLabel,
|
|
248
235
|
filterLabels,
|
|
249
236
|
};
|
|
250
237
|
};
|
|
251
238
|
|
|
252
|
-
// Dependency Injection
|
|
253
239
|
const dependencies = {
|
|
254
240
|
Label,
|
|
255
241
|
redisConfig: createConfig(process.env),
|