@fjell/cache 4.5.2 → 4.6.1

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 (40) hide show
  1. package/.kodrdriv/config.yaml +10 -0
  2. package/.kodrdriv/context/content.md +1 -0
  3. package/dist/Aggregator.cjs.js +276 -0
  4. package/dist/{src/Aggregator.d.ts → Aggregator.d.ts} +3 -3
  5. package/dist/Aggregator.es.js +271 -0
  6. package/dist/Cache.cjs.js +279 -0
  7. package/dist/{src/Cache.d.ts → Cache.d.ts} +4 -4
  8. package/dist/{src/Cache.js → Cache.es.js} +129 -77
  9. package/dist/CacheMap.cjs.js +108 -0
  10. package/dist/{src/CacheMap.d.ts → CacheMap.d.ts} +1 -1
  11. package/dist/{src/CacheMap.js → CacheMap.es.js} +42 -23
  12. package/dist/CacheRegistry.cjs.js +66 -0
  13. package/dist/{src/CacheRegistry.d.ts → CacheRegistry.d.ts} +4 -7
  14. package/dist/CacheRegistry.es.js +62 -0
  15. package/dist/index.cjs +708 -0
  16. package/dist/index.cjs.js +17 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.es.js +5 -0
  20. package/dist/logger.cjs.js +10 -0
  21. package/dist/logger.d.ts +2 -0
  22. package/dist/logger.es.js +6 -0
  23. package/package.json +31 -18
  24. package/src/Aggregator.ts +12 -4
  25. package/src/Cache.ts +5 -5
  26. package/src/CacheRegistry.ts +37 -25
  27. package/src/index.ts +4 -0
  28. package/src/logger.ts +1 -1
  29. package/vitest.config.ts +34 -0
  30. package/dist/src/Aggregator.js +0 -182
  31. package/dist/src/Aggregator.js.map +0 -1
  32. package/dist/src/Cache.js.map +0 -1
  33. package/dist/src/CacheMap.js.map +0 -1
  34. package/dist/src/CacheRegistry.js +0 -34
  35. package/dist/src/CacheRegistry.js.map +0 -1
  36. package/dist/src/logger.d.ts +0 -2
  37. package/dist/src/logger.js +0 -4
  38. package/dist/src/logger.js.map +0 -1
  39. package/dist/tsconfig.tsbuildinfo +0 -1
  40. package/eslint.config.mjs +0 -70
@@ -0,0 +1,10 @@
1
+ verbose: false
2
+ model: gpt-4.1
3
+ contextDirectories:
4
+ - .kodrdriv/context
5
+ commit:
6
+ cached: true
7
+ sendit: true
8
+ release:
9
+ from: main
10
+ to: HEAD
@@ -0,0 +1 @@
1
+ This is the Fjell Library for Client-side Caches
@@ -0,0 +1,276 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const logger$1 = require('./logger.cjs.js');
6
+
7
+ const logger = logger$1.default.get('ItemAggregator');
8
+ const toCacheConfig = (config)=>{
9
+ let cacheConfig;
10
+ if (config.optional === undefined) {
11
+ cacheConfig = {
12
+ cache: config,
13
+ optional: false
14
+ };
15
+ } else {
16
+ cacheConfig = config;
17
+ }
18
+ return cacheConfig;
19
+ };
20
+ const createAggregator = async (cache, { aggregates = {}, events = {} })=>{
21
+ const populate = async (item)=>{
22
+ logger.default('populate', {
23
+ item
24
+ });
25
+ for(const key in aggregates){
26
+ await populateAggregate(key, item);
27
+ }
28
+ for(const key in events){
29
+ await populateEvent(key, item);
30
+ }
31
+ logger.default('populate done', {
32
+ item
33
+ });
34
+ return item;
35
+ };
36
+ const populateAggregate = async (key, item)=>{
37
+ logger.default('populate aggregate key', {
38
+ key
39
+ });
40
+ const cacheConfig = toCacheConfig(aggregates[key]);
41
+ if (item.refs === undefined) {
42
+ if (cacheConfig.optional === false) {
43
+ logger.error('Item does not have refs an is not optional ' + JSON.stringify(item));
44
+ throw new Error('Item does not have refs an is not optional ' + JSON.stringify(item));
45
+ } else {
46
+ if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
47
+ delete item.events[key];
48
+ }
49
+ }
50
+ } else if (item.refs[key] === undefined) {
51
+ if (cacheConfig.optional === false) {
52
+ logger.error('Item does not have mandatory ref with key, not optional ' + key + ' ' + JSON.stringify(item));
53
+ throw new Error('Item does not have mandatory ref with key, not optional ' + key + ' ' + JSON.stringify(item));
54
+ } else {
55
+ if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
56
+ delete item.events[key];
57
+ }
58
+ }
59
+ } else {
60
+ const ref = item.refs[key];
61
+ logger.default('AGG Retrieving Item in Populate', {
62
+ key: ref
63
+ });
64
+ const [, newItem] = await cacheConfig.cache.retrieve(ref);
65
+ if (newItem) {
66
+ if (item.aggs === undefined) {
67
+ item.aggs = {};
68
+ }
69
+ item.aggs[key] = {
70
+ key: ref,
71
+ item: newItem
72
+ };
73
+ }
74
+ }
75
+ };
76
+ // TODO: I'm not a big fan that this just "automatically" assumes that the "by" key in event is a ref.
77
+ const populateEvent = async (key, item)=>{
78
+ logger.default('populate event key', {
79
+ key
80
+ });
81
+ const cacheConfig = toCacheConfig(events[key]);
82
+ if (item.events === undefined) {
83
+ throw new Error('Item does not have events ' + JSON.stringify(item));
84
+ } else if (item.events[key] === undefined) {
85
+ if (cacheConfig.optional === false) {
86
+ logger.error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));
87
+ throw new Error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));
88
+ }
89
+ } else {
90
+ const event = item.events[key];
91
+ if (event.by === undefined) {
92
+ logger.error('populateEvent with an Event that does not have by', {
93
+ event,
94
+ ik: item.key,
95
+ eventKey: key
96
+ });
97
+ throw new Error('populateEvent with an Event that does not have by: ' + JSON.stringify({
98
+ key,
99
+ event
100
+ }));
101
+ }
102
+ logger.default('EVENT Retrieving Item in Populate', {
103
+ key: event.by
104
+ });
105
+ const [, newItem] = await cacheConfig.cache.retrieve(event.by);
106
+ if (newItem) {
107
+ event.agg = newItem;
108
+ }
109
+ }
110
+ };
111
+ const all = async (query = {}, locations = [])=>{
112
+ logger.default('all', {
113
+ query,
114
+ locations
115
+ });
116
+ const [cacheMap, items] = await cache.all(query, locations);
117
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
118
+ return [
119
+ cacheMap,
120
+ populatedItems
121
+ ];
122
+ };
123
+ const one = async (query = {}, locations = [])=>{
124
+ logger.default('one', {
125
+ query,
126
+ locations
127
+ });
128
+ const [cacheMap, item] = await cache.one(query, locations);
129
+ let populatedItem = null;
130
+ if (item) {
131
+ populatedItem = await populate(item);
132
+ }
133
+ return [
134
+ cacheMap,
135
+ populatedItem
136
+ ];
137
+ };
138
+ const action = async (key, action, body = {})=>{
139
+ logger.default('action', {
140
+ key,
141
+ action,
142
+ body
143
+ });
144
+ const [cacheMap, item] = await cache.action(key, action, body);
145
+ const populatedItem = await populate(item);
146
+ return [
147
+ cacheMap,
148
+ populatedItem
149
+ ];
150
+ };
151
+ const allAction = async (action, body = {}, locations = [])=>{
152
+ logger.default('action', {
153
+ action,
154
+ body,
155
+ locations
156
+ });
157
+ const [cacheMap, items] = await cache.allAction(action, body, locations);
158
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
159
+ return [
160
+ cacheMap,
161
+ populatedItems
162
+ ];
163
+ };
164
+ const create = async (v, locations = [])=>{
165
+ logger.default('create', {
166
+ v,
167
+ locations
168
+ });
169
+ const [cacheMap, item] = await cache.create(v, locations);
170
+ const populatedItem = await populate(item);
171
+ return [
172
+ cacheMap,
173
+ populatedItem
174
+ ];
175
+ };
176
+ const get = async (key)=>{
177
+ logger.default('get', {
178
+ key
179
+ });
180
+ const [cacheMap, item] = await cache.get(key);
181
+ let populatedItem = null;
182
+ if (item) {
183
+ populatedItem = await populate(item);
184
+ }
185
+ return [
186
+ cacheMap,
187
+ populatedItem
188
+ ];
189
+ };
190
+ const retrieve = async (key)=>{
191
+ logger.default('retrieve', {
192
+ key
193
+ });
194
+ const [cacheMap, item] = await cache.retrieve(key);
195
+ let populatedItem = null;
196
+ if (item) {
197
+ populatedItem = await populate(item);
198
+ }
199
+ return [
200
+ cacheMap,
201
+ populatedItem
202
+ ];
203
+ };
204
+ const remove = async (key)=>{
205
+ logger.default('remove', {
206
+ key
207
+ });
208
+ const cacheMap = await cache.remove(key);
209
+ return cacheMap;
210
+ };
211
+ const update = async (key, v)=>{
212
+ logger.default('update', {
213
+ key,
214
+ v
215
+ });
216
+ const [cacheMap, item] = await cache.update(key, v);
217
+ const populatedItem = await populate(item);
218
+ return [
219
+ cacheMap,
220
+ populatedItem
221
+ ];
222
+ };
223
+ const find = async (finder, finderParams, locations = [])=>{
224
+ logger.default('find', {
225
+ finder,
226
+ finderParams,
227
+ locations
228
+ });
229
+ const [cacheMap, items] = await cache.find(finder, finderParams, locations);
230
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
231
+ return [
232
+ cacheMap,
233
+ populatedItems
234
+ ];
235
+ };
236
+ const set = async (key, v)=>{
237
+ logger.default('set', {
238
+ key,
239
+ v
240
+ });
241
+ // TODO: There should be some input validation here to ensure a valid item.
242
+ const [cacheMap, item] = await cache.set(key, v);
243
+ const populatedItem = await populate(item);
244
+ return [
245
+ cacheMap,
246
+ populatedItem
247
+ ];
248
+ };
249
+ const reset = async ()=>{
250
+ const cacheMap = await cache.reset();
251
+ return cacheMap;
252
+ };
253
+ return {
254
+ all,
255
+ one,
256
+ action,
257
+ allAction,
258
+ create,
259
+ get,
260
+ retrieve,
261
+ remove,
262
+ update,
263
+ find,
264
+ reset,
265
+ set,
266
+ pkTypes: cache.pkTypes,
267
+ cacheMap: cache.cacheMap,
268
+ populate,
269
+ populateAggregate,
270
+ populateEvent
271
+ };
272
+ };
273
+
274
+ exports.createAggregator = createAggregator;
275
+ exports.toCacheConfig = toCacheConfig;
276
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdncmVnYXRvci5janMuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
@@ -1,5 +1,5 @@
1
- import { Item } from "@fjell/core";
2
- import { Cache } from "./Cache";
1
+ import { Item } from '@fjell/core';
2
+ import { Cache } from './Cache';
3
3
  export interface Aggregator<V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends Cache<V, S, L1, L2, L3, L4, L5> {
4
4
  populate: (item: V) => Promise<V>;
5
5
  populateAggregate: (key: string, item: V) => Promise<void>;
@@ -16,4 +16,4 @@ export declare const toCacheConfig: <V extends Item<S, L1, L2, L3, L4, L5>, S ex
16
16
  export declare const createAggregator: <V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(cache: Cache<V, S, L1, L2, L3, L4, L5>, { aggregates, events }: {
17
17
  aggregates?: AggregateConfig;
18
18
  events?: AggregateConfig;
19
- }) => Aggregator<V, S, L1, L2, L3, L4, L5>;
19
+ }) => Promise<Aggregator<V, S, L1, L2, L3, L4, L5>>;
@@ -0,0 +1,271 @@
1
+ import LibLogger from './logger.es.js';
2
+
3
+ const logger = LibLogger.get('ItemAggregator');
4
+ const toCacheConfig = (config)=>{
5
+ let cacheConfig;
6
+ if (config.optional === undefined) {
7
+ cacheConfig = {
8
+ cache: config,
9
+ optional: false
10
+ };
11
+ } else {
12
+ cacheConfig = config;
13
+ }
14
+ return cacheConfig;
15
+ };
16
+ const createAggregator = async (cache, { aggregates = {}, events = {} })=>{
17
+ const populate = async (item)=>{
18
+ logger.default('populate', {
19
+ item
20
+ });
21
+ for(const key in aggregates){
22
+ await populateAggregate(key, item);
23
+ }
24
+ for(const key in events){
25
+ await populateEvent(key, item);
26
+ }
27
+ logger.default('populate done', {
28
+ item
29
+ });
30
+ return item;
31
+ };
32
+ const populateAggregate = async (key, item)=>{
33
+ logger.default('populate aggregate key', {
34
+ key
35
+ });
36
+ const cacheConfig = toCacheConfig(aggregates[key]);
37
+ if (item.refs === undefined) {
38
+ if (cacheConfig.optional === false) {
39
+ logger.error('Item does not have refs an is not optional ' + JSON.stringify(item));
40
+ throw new Error('Item does not have refs an is not optional ' + JSON.stringify(item));
41
+ } else {
42
+ if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
43
+ delete item.events[key];
44
+ }
45
+ }
46
+ } else if (item.refs[key] === undefined) {
47
+ if (cacheConfig.optional === false) {
48
+ logger.error('Item does not have mandatory ref with key, not optional ' + key + ' ' + JSON.stringify(item));
49
+ throw new Error('Item does not have mandatory ref with key, not optional ' + key + ' ' + JSON.stringify(item));
50
+ } else {
51
+ if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
52
+ delete item.events[key];
53
+ }
54
+ }
55
+ } else {
56
+ const ref = item.refs[key];
57
+ logger.default('AGG Retrieving Item in Populate', {
58
+ key: ref
59
+ });
60
+ const [, newItem] = await cacheConfig.cache.retrieve(ref);
61
+ if (newItem) {
62
+ if (item.aggs === undefined) {
63
+ item.aggs = {};
64
+ }
65
+ item.aggs[key] = {
66
+ key: ref,
67
+ item: newItem
68
+ };
69
+ }
70
+ }
71
+ };
72
+ // TODO: I'm not a big fan that this just "automatically" assumes that the "by" key in event is a ref.
73
+ const populateEvent = async (key, item)=>{
74
+ logger.default('populate event key', {
75
+ key
76
+ });
77
+ const cacheConfig = toCacheConfig(events[key]);
78
+ if (item.events === undefined) {
79
+ throw new Error('Item does not have events ' + JSON.stringify(item));
80
+ } else if (item.events[key] === undefined) {
81
+ if (cacheConfig.optional === false) {
82
+ logger.error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));
83
+ throw new Error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));
84
+ }
85
+ } else {
86
+ const event = item.events[key];
87
+ if (event.by === undefined) {
88
+ logger.error('populateEvent with an Event that does not have by', {
89
+ event,
90
+ ik: item.key,
91
+ eventKey: key
92
+ });
93
+ throw new Error('populateEvent with an Event that does not have by: ' + JSON.stringify({
94
+ key,
95
+ event
96
+ }));
97
+ }
98
+ logger.default('EVENT Retrieving Item in Populate', {
99
+ key: event.by
100
+ });
101
+ const [, newItem] = await cacheConfig.cache.retrieve(event.by);
102
+ if (newItem) {
103
+ event.agg = newItem;
104
+ }
105
+ }
106
+ };
107
+ const all = async (query = {}, locations = [])=>{
108
+ logger.default('all', {
109
+ query,
110
+ locations
111
+ });
112
+ const [cacheMap, items] = await cache.all(query, locations);
113
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
114
+ return [
115
+ cacheMap,
116
+ populatedItems
117
+ ];
118
+ };
119
+ const one = async (query = {}, locations = [])=>{
120
+ logger.default('one', {
121
+ query,
122
+ locations
123
+ });
124
+ const [cacheMap, item] = await cache.one(query, locations);
125
+ let populatedItem = null;
126
+ if (item) {
127
+ populatedItem = await populate(item);
128
+ }
129
+ return [
130
+ cacheMap,
131
+ populatedItem
132
+ ];
133
+ };
134
+ const action = async (key, action, body = {})=>{
135
+ logger.default('action', {
136
+ key,
137
+ action,
138
+ body
139
+ });
140
+ const [cacheMap, item] = await cache.action(key, action, body);
141
+ const populatedItem = await populate(item);
142
+ return [
143
+ cacheMap,
144
+ populatedItem
145
+ ];
146
+ };
147
+ const allAction = async (action, body = {}, locations = [])=>{
148
+ logger.default('action', {
149
+ action,
150
+ body,
151
+ locations
152
+ });
153
+ const [cacheMap, items] = await cache.allAction(action, body, locations);
154
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
155
+ return [
156
+ cacheMap,
157
+ populatedItems
158
+ ];
159
+ };
160
+ const create = async (v, locations = [])=>{
161
+ logger.default('create', {
162
+ v,
163
+ locations
164
+ });
165
+ const [cacheMap, item] = await cache.create(v, locations);
166
+ const populatedItem = await populate(item);
167
+ return [
168
+ cacheMap,
169
+ populatedItem
170
+ ];
171
+ };
172
+ const get = async (key)=>{
173
+ logger.default('get', {
174
+ key
175
+ });
176
+ const [cacheMap, item] = await cache.get(key);
177
+ let populatedItem = null;
178
+ if (item) {
179
+ populatedItem = await populate(item);
180
+ }
181
+ return [
182
+ cacheMap,
183
+ populatedItem
184
+ ];
185
+ };
186
+ const retrieve = async (key)=>{
187
+ logger.default('retrieve', {
188
+ key
189
+ });
190
+ const [cacheMap, item] = await cache.retrieve(key);
191
+ let populatedItem = null;
192
+ if (item) {
193
+ populatedItem = await populate(item);
194
+ }
195
+ return [
196
+ cacheMap,
197
+ populatedItem
198
+ ];
199
+ };
200
+ const remove = async (key)=>{
201
+ logger.default('remove', {
202
+ key
203
+ });
204
+ const cacheMap = await cache.remove(key);
205
+ return cacheMap;
206
+ };
207
+ const update = async (key, v)=>{
208
+ logger.default('update', {
209
+ key,
210
+ v
211
+ });
212
+ const [cacheMap, item] = await cache.update(key, v);
213
+ const populatedItem = await populate(item);
214
+ return [
215
+ cacheMap,
216
+ populatedItem
217
+ ];
218
+ };
219
+ const find = async (finder, finderParams, locations = [])=>{
220
+ logger.default('find', {
221
+ finder,
222
+ finderParams,
223
+ locations
224
+ });
225
+ const [cacheMap, items] = await cache.find(finder, finderParams, locations);
226
+ const populatedItems = await Promise.all(items.map(async (item)=>populate(item)));
227
+ return [
228
+ cacheMap,
229
+ populatedItems
230
+ ];
231
+ };
232
+ const set = async (key, v)=>{
233
+ logger.default('set', {
234
+ key,
235
+ v
236
+ });
237
+ // TODO: There should be some input validation here to ensure a valid item.
238
+ const [cacheMap, item] = await cache.set(key, v);
239
+ const populatedItem = await populate(item);
240
+ return [
241
+ cacheMap,
242
+ populatedItem
243
+ ];
244
+ };
245
+ const reset = async ()=>{
246
+ const cacheMap = await cache.reset();
247
+ return cacheMap;
248
+ };
249
+ return {
250
+ all,
251
+ one,
252
+ action,
253
+ allAction,
254
+ create,
255
+ get,
256
+ retrieve,
257
+ remove,
258
+ update,
259
+ find,
260
+ reset,
261
+ set,
262
+ pkTypes: cache.pkTypes,
263
+ cacheMap: cache.cacheMap,
264
+ populate,
265
+ populateAggregate,
266
+ populateEvent
267
+ };
268
+ };
269
+
270
+ export { createAggregator, toCacheConfig };
271
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdncmVnYXRvci5lcy5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=