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