@oimdb/core 1.2.2 → 1.3.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.
- package/README.md +116 -27
- package/dist/index.cjs +341 -29
- package/dist/index.d.cts +225 -38
- package/dist/index.d.ts +225 -38
- package/dist/index.js +329 -25
- package/package.json +13 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
var OIMCollectionStore = class {
|
|
3
3
|
};
|
|
4
4
|
|
|
5
|
+
// src/abstract/OIMIndexStoreSetBased.ts
|
|
6
|
+
var OIMIndexStoreSetBased = class {
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// src/abstract/OIMIndexStoreArrayBased.ts
|
|
10
|
+
var OIMIndexStoreArrayBased = class {
|
|
11
|
+
};
|
|
12
|
+
|
|
5
13
|
// src/core/OIMEventEmitter.ts
|
|
6
14
|
var OIMEventEmitter = class {
|
|
7
15
|
constructor() {
|
|
@@ -45,10 +53,14 @@ var OIMEventEmitter = class {
|
|
|
45
53
|
}
|
|
46
54
|
on(event, handler) {
|
|
47
55
|
const bucket = this.getOrCreateBucket(event);
|
|
48
|
-
if (bucket.indexByHandler.has(handler))
|
|
56
|
+
if (bucket.indexByHandler.has(handler))
|
|
57
|
+
return;
|
|
49
58
|
const index = bucket.handlers.length;
|
|
50
59
|
bucket.handlers.push(handler);
|
|
51
|
-
bucket.indexByHandler.set(
|
|
60
|
+
bucket.indexByHandler.set(
|
|
61
|
+
handler,
|
|
62
|
+
index
|
|
63
|
+
);
|
|
52
64
|
}
|
|
53
65
|
emit(event, payload) {
|
|
54
66
|
const bucket = this.buckets[event];
|
|
@@ -127,12 +139,8 @@ var EOIMIndexEventType = /* @__PURE__ */ ((EOIMIndexEventType2) => {
|
|
|
127
139
|
return EOIMIndexEventType2;
|
|
128
140
|
})(EOIMIndexEventType || {});
|
|
129
141
|
|
|
130
|
-
// src/
|
|
131
|
-
var
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// src/core/OIMIndexStoreMapDriven.ts
|
|
135
|
-
var OIMIndexStoreMapDriven = class extends OIMIndexStore {
|
|
142
|
+
// src/core/OIMIndexStoreMapDrivenSetBased.ts
|
|
143
|
+
var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
136
144
|
constructor() {
|
|
137
145
|
super(...arguments);
|
|
138
146
|
this.pks = /* @__PURE__ */ new Map();
|
|
@@ -175,12 +183,12 @@ var OIMIndexStoreMapDriven = class extends OIMIndexStore {
|
|
|
175
183
|
}
|
|
176
184
|
};
|
|
177
185
|
|
|
178
|
-
// src/abstract/
|
|
179
|
-
var
|
|
186
|
+
// src/abstract/OIMIndexSetBased.ts
|
|
187
|
+
var OIMIndexSetBased = class {
|
|
180
188
|
constructor(options = {}) {
|
|
181
189
|
this.emitter = new OIMEventEmitter();
|
|
182
190
|
this.comparePks = options.comparePks;
|
|
183
|
-
this.store = options.store ?? new
|
|
191
|
+
this.store = options.store ?? new OIMIndexStoreMapDrivenSetBased();
|
|
184
192
|
}
|
|
185
193
|
/**
|
|
186
194
|
* Get primary keys for multiple index keys
|
|
@@ -289,6 +297,155 @@ var OIMIndex = class {
|
|
|
289
297
|
}
|
|
290
298
|
};
|
|
291
299
|
|
|
300
|
+
// src/core/OIMIndexStoreMapDrivenArrayBased.ts
|
|
301
|
+
var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
302
|
+
constructor() {
|
|
303
|
+
super(...arguments);
|
|
304
|
+
this.pks = /* @__PURE__ */ new Map();
|
|
305
|
+
}
|
|
306
|
+
setOneByKey(key, pks) {
|
|
307
|
+
this.pks.set(key, pks);
|
|
308
|
+
}
|
|
309
|
+
removeOneByKey(key) {
|
|
310
|
+
this.pks.delete(key);
|
|
311
|
+
}
|
|
312
|
+
removeManyByKeys(keys) {
|
|
313
|
+
for (const key of keys) {
|
|
314
|
+
this.pks.delete(key);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
getOneByKey(key) {
|
|
318
|
+
return this.pks.get(key);
|
|
319
|
+
}
|
|
320
|
+
getManyByKeys(keys) {
|
|
321
|
+
const result = /* @__PURE__ */ new Map();
|
|
322
|
+
for (const key of keys) {
|
|
323
|
+
const pks = this.getOneByKey(key);
|
|
324
|
+
if (pks !== void 0) {
|
|
325
|
+
result.set(key, pks);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
getAllKeys() {
|
|
331
|
+
return Array.from(this.pks.keys());
|
|
332
|
+
}
|
|
333
|
+
getAll() {
|
|
334
|
+
return new Map(this.pks);
|
|
335
|
+
}
|
|
336
|
+
countAll() {
|
|
337
|
+
return this.pks.size;
|
|
338
|
+
}
|
|
339
|
+
clear() {
|
|
340
|
+
this.pks.clear();
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// src/abstract/OIMIndexArrayBased.ts
|
|
345
|
+
var OIMIndexArrayBased = class {
|
|
346
|
+
constructor(options = {}) {
|
|
347
|
+
this.emitter = new OIMEventEmitter();
|
|
348
|
+
this.comparePks = options.comparePks;
|
|
349
|
+
this.store = options.store ?? new OIMIndexStoreMapDrivenArrayBased();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get primary keys for multiple index keys
|
|
353
|
+
*/
|
|
354
|
+
getPksByKeys(keys) {
|
|
355
|
+
return this.store.getManyByKeys(keys);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Get primary keys for a specific index key
|
|
359
|
+
*/
|
|
360
|
+
getPksByKey(key) {
|
|
361
|
+
const pksArray = this.store.getOneByKey(key);
|
|
362
|
+
return pksArray ? pksArray : [];
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Check if an index key exists
|
|
366
|
+
*/
|
|
367
|
+
hasKey(key) {
|
|
368
|
+
return this.store.getOneByKey(key) !== void 0;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get all index keys
|
|
372
|
+
*/
|
|
373
|
+
getKeys() {
|
|
374
|
+
return this.store.getAllKeys();
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get the number of primary keys for a specific index key
|
|
378
|
+
*/
|
|
379
|
+
getKeySize(key) {
|
|
380
|
+
const pksArray = this.store.getOneByKey(key);
|
|
381
|
+
return pksArray ? pksArray.length : 0;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Get total number of index keys
|
|
385
|
+
*/
|
|
386
|
+
get size() {
|
|
387
|
+
return this.store.countAll();
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Check if the index is empty
|
|
391
|
+
*/
|
|
392
|
+
get isEmpty() {
|
|
393
|
+
return this.store.countAll() === 0;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get performance metrics for monitoring and debugging
|
|
397
|
+
*/
|
|
398
|
+
getMetrics() {
|
|
399
|
+
let totalPks = 0;
|
|
400
|
+
let maxBucketSize = 0;
|
|
401
|
+
let minBucketSize = Infinity;
|
|
402
|
+
const allPks = this.store.getAll();
|
|
403
|
+
for (const pksArray of allPks.values()) {
|
|
404
|
+
totalPks += pksArray.length;
|
|
405
|
+
maxBucketSize = Math.max(maxBucketSize, pksArray.length);
|
|
406
|
+
minBucketSize = Math.min(minBucketSize, pksArray.length);
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
totalKeys: allPks.size,
|
|
410
|
+
totalPks,
|
|
411
|
+
averagePksPerKey: allPks.size > 0 ? totalPks / allPks.size : 0,
|
|
412
|
+
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
413
|
+
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Clean up event listeners when index is no longer needed
|
|
418
|
+
*/
|
|
419
|
+
destroy() {
|
|
420
|
+
this.emitter.offAll();
|
|
421
|
+
this.store.clear();
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Set primary keys for a specific index key with optional comparison.
|
|
425
|
+
* If comparator is provided and returns true (no changes), skip the update.
|
|
426
|
+
*/
|
|
427
|
+
setPksWithComparison(key, newPks) {
|
|
428
|
+
if (this.comparePks) {
|
|
429
|
+
const existingPksArray = this.store.getOneByKey(key);
|
|
430
|
+
if (existingPksArray && existingPksArray.length === newPks.length) {
|
|
431
|
+
if (this.comparePks(existingPksArray, newPks)) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
} else if (!existingPksArray && newPks.length === 0) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
this.store.setOneByKey(key, newPks);
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Emit update event with changed keys
|
|
443
|
+
*/
|
|
444
|
+
emitUpdate(keys) {
|
|
445
|
+
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
|
|
292
449
|
// src/enum/EOIMUpdateEventCoalescerEventType.ts
|
|
293
450
|
var EOIMUpdateEventCoalescerEventType = /* @__PURE__ */ ((EOIMUpdateEventCoalescerEventType2) => {
|
|
294
451
|
EOIMUpdateEventCoalescerEventType2[EOIMUpdateEventCoalescerEventType2["HAS_CHANGES"] = 0] = "HAS_CHANGES";
|
|
@@ -415,8 +572,8 @@ var OIMUpdateEventEmitter = class {
|
|
|
415
572
|
}
|
|
416
573
|
};
|
|
417
574
|
|
|
418
|
-
// src/core/
|
|
419
|
-
var
|
|
575
|
+
// src/core/OIMIndexManualSetBased.ts
|
|
576
|
+
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
420
577
|
constructor(options = {}) {
|
|
421
578
|
super(options);
|
|
422
579
|
}
|
|
@@ -508,8 +665,8 @@ var OIMUpdateEventCoalescer = class {
|
|
|
508
665
|
constructor(index) {
|
|
509
666
|
this.emitter = new OIMEventEmitter();
|
|
510
667
|
this.hasEmittedChanges = false;
|
|
511
|
-
this.updatedKeysIndex = index ?? new
|
|
512
|
-
store: new
|
|
668
|
+
this.updatedKeysIndex = index ?? new OIMIndexManualSetBased({
|
|
669
|
+
store: new OIMIndexStoreMapDrivenSetBased()
|
|
513
670
|
});
|
|
514
671
|
if (!this.updatedKeysIndex.hasKey(OIMDBSettings.UPDATED_KEYS_INDEX_KEY)) {
|
|
515
672
|
this.updatedKeysIndex.setPks(
|
|
@@ -579,8 +736,49 @@ var OIMUpdateEventCoalescerIndex = class extends OIMUpdateEventCoalescer {
|
|
|
579
736
|
}
|
|
580
737
|
};
|
|
581
738
|
|
|
582
|
-
// src/abstract/
|
|
583
|
-
var
|
|
739
|
+
// src/abstract/OIMReactiveIndexSetBased.ts
|
|
740
|
+
var OIMReactiveIndexSetBased = class {
|
|
741
|
+
constructor(queue, opts) {
|
|
742
|
+
this.index = opts?.index ?? this.createDefaultIndex();
|
|
743
|
+
this.coalescer = new OIMUpdateEventCoalescerIndex(
|
|
744
|
+
this.index.emitter
|
|
745
|
+
);
|
|
746
|
+
this.updateEventEmitter = new OIMUpdateEventEmitter({
|
|
747
|
+
coalescer: this.coalescer,
|
|
748
|
+
queue
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
getPksByKey(key) {
|
|
752
|
+
return this.index.getPksByKey(key);
|
|
753
|
+
}
|
|
754
|
+
getPksByKeys(keys) {
|
|
755
|
+
return this.index.getPksByKeys(keys);
|
|
756
|
+
}
|
|
757
|
+
hasKey(key) {
|
|
758
|
+
return this.index.hasKey(key);
|
|
759
|
+
}
|
|
760
|
+
getKeys() {
|
|
761
|
+
return this.index.getKeys();
|
|
762
|
+
}
|
|
763
|
+
getKeySize(key) {
|
|
764
|
+
return this.index.getKeySize(key);
|
|
765
|
+
}
|
|
766
|
+
get size() {
|
|
767
|
+
return this.index.size;
|
|
768
|
+
}
|
|
769
|
+
get isEmpty() {
|
|
770
|
+
return this.index.isEmpty;
|
|
771
|
+
}
|
|
772
|
+
getMetrics() {
|
|
773
|
+
return this.index.getMetrics();
|
|
774
|
+
}
|
|
775
|
+
destroy() {
|
|
776
|
+
this.index.destroy();
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
// src/abstract/OIMReactiveIndexArrayBased.ts
|
|
781
|
+
var OIMReactiveIndexArrayBased = class {
|
|
584
782
|
constructor(queue, opts) {
|
|
585
783
|
this.index = opts?.index ?? this.createDefaultIndex();
|
|
586
784
|
this.coalescer = new OIMUpdateEventCoalescerIndex(
|
|
@@ -816,13 +1014,111 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
816
1014
|
}
|
|
817
1015
|
};
|
|
818
1016
|
|
|
819
|
-
// src/core/
|
|
820
|
-
var
|
|
1017
|
+
// src/core/OIMReactiveIndexManualSetBased.ts
|
|
1018
|
+
var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
1019
|
+
constructor(queue, opts) {
|
|
1020
|
+
super(queue, opts);
|
|
1021
|
+
}
|
|
1022
|
+
createDefaultIndex() {
|
|
1023
|
+
return new OIMIndexManualSetBased();
|
|
1024
|
+
}
|
|
1025
|
+
setPks(key, pks) {
|
|
1026
|
+
this.index.setPks(key, pks);
|
|
1027
|
+
}
|
|
1028
|
+
addPks(key, pks) {
|
|
1029
|
+
this.index.addPks(key, pks);
|
|
1030
|
+
}
|
|
1031
|
+
removePks(key, pks) {
|
|
1032
|
+
this.index.removePks(key, pks);
|
|
1033
|
+
}
|
|
1034
|
+
clear(key) {
|
|
1035
|
+
this.index.clear(key);
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
// src/core/OIMIndexManualArrayBased.ts
|
|
1040
|
+
var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
1041
|
+
constructor(options = {}) {
|
|
1042
|
+
super(options);
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Set primary keys for a specific index key, replacing any existing values.
|
|
1046
|
+
* Uses optional comparator to skip updates if PKs haven't actually changed.
|
|
1047
|
+
*/
|
|
1048
|
+
setPks(key, pks) {
|
|
1049
|
+
const hasChanges = this.setPksWithComparison(key, pks);
|
|
1050
|
+
if (hasChanges) {
|
|
1051
|
+
this.emitUpdate([key]);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Add primary keys to a specific index key
|
|
1056
|
+
*/
|
|
1057
|
+
addPks(key, pks) {
|
|
1058
|
+
if (pks.length === 0) return;
|
|
1059
|
+
let pksArray = this.store.getOneByKey(key);
|
|
1060
|
+
if (!pksArray) {
|
|
1061
|
+
pksArray = [];
|
|
1062
|
+
this.store.setOneByKey(key, pksArray);
|
|
1063
|
+
}
|
|
1064
|
+
const pksSet = new Set(pksArray);
|
|
1065
|
+
let hasChanges = false;
|
|
1066
|
+
for (const pk of pks) {
|
|
1067
|
+
if (!pksSet.has(pk)) {
|
|
1068
|
+
pksSet.add(pk);
|
|
1069
|
+
hasChanges = true;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (hasChanges) {
|
|
1073
|
+
this.store.setOneByKey(key, Array.from(pksSet));
|
|
1074
|
+
this.emitUpdate([key]);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Remove primary keys from a specific index key
|
|
1079
|
+
*/
|
|
1080
|
+
removePks(key, pks) {
|
|
1081
|
+
if (pks.length === 0) return;
|
|
1082
|
+
const pksArray = this.store.getOneByKey(key);
|
|
1083
|
+
if (!pksArray) return;
|
|
1084
|
+
const pksSet = new Set(pks);
|
|
1085
|
+
const filtered = pksArray.filter((pk) => !pksSet.has(pk));
|
|
1086
|
+
const hasChanges = filtered.length !== pksArray.length;
|
|
1087
|
+
if (hasChanges) {
|
|
1088
|
+
if (filtered.length === 0) {
|
|
1089
|
+
this.store.removeOneByKey(key);
|
|
1090
|
+
} else {
|
|
1091
|
+
this.store.setOneByKey(key, filtered);
|
|
1092
|
+
}
|
|
1093
|
+
this.emitUpdate([key]);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Clear all primary keys for a specific index key, or all keys if no key specified
|
|
1098
|
+
*/
|
|
1099
|
+
clear(key) {
|
|
1100
|
+
if (key === void 0) {
|
|
1101
|
+
const allKeys = this.store.getAllKeys();
|
|
1102
|
+
if (allKeys.length > 0) {
|
|
1103
|
+
this.store.clear();
|
|
1104
|
+
this.emitUpdate(allKeys);
|
|
1105
|
+
}
|
|
1106
|
+
} else {
|
|
1107
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1108
|
+
this.store.removeOneByKey(key);
|
|
1109
|
+
this.emitUpdate([key]);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
// src/core/OIMReactiveIndexManualArrayBased.ts
|
|
1116
|
+
var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased {
|
|
821
1117
|
constructor(queue, opts) {
|
|
822
1118
|
super(queue, opts);
|
|
823
1119
|
}
|
|
824
1120
|
createDefaultIndex() {
|
|
825
|
-
return new
|
|
1121
|
+
return new OIMIndexManualArrayBased();
|
|
826
1122
|
}
|
|
827
1123
|
setPks(key, pks) {
|
|
828
1124
|
this.index.setPks(key, pks);
|
|
@@ -842,7 +1138,7 @@ var OIMReactiveIndexManual = class extends OIMReactiveIndex {
|
|
|
842
1138
|
var OIMRICollection = class extends OIMReactiveCollection {
|
|
843
1139
|
constructor(queue, opts) {
|
|
844
1140
|
super(queue, opts.collectionOpts);
|
|
845
|
-
this.indexes = opts.indexes;
|
|
1141
|
+
this.indexes = opts.indexes || {};
|
|
846
1142
|
}
|
|
847
1143
|
};
|
|
848
1144
|
|
|
@@ -1229,15 +1525,23 @@ export {
|
|
|
1229
1525
|
OIMEventQueueSchedulerImmediate,
|
|
1230
1526
|
OIMEventQueueSchedulerMicrotask,
|
|
1231
1527
|
OIMEventQueueSchedulerTimeout,
|
|
1232
|
-
|
|
1528
|
+
OIMIndexArrayBased,
|
|
1233
1529
|
OIMIndexComparatorFactory,
|
|
1234
|
-
|
|
1530
|
+
OIMIndexManualArrayBased,
|
|
1531
|
+
OIMIndexManualSetBased,
|
|
1532
|
+
OIMIndexSetBased,
|
|
1533
|
+
OIMIndexStoreArrayBased,
|
|
1534
|
+
OIMIndexStoreMapDrivenArrayBased,
|
|
1535
|
+
OIMIndexStoreMapDrivenSetBased,
|
|
1536
|
+
OIMIndexStoreSetBased,
|
|
1235
1537
|
OIMMap2Keys,
|
|
1236
1538
|
OIMPkSelectorFactory,
|
|
1237
1539
|
OIMRICollection,
|
|
1238
1540
|
OIMReactiveCollection,
|
|
1239
|
-
|
|
1240
|
-
|
|
1541
|
+
OIMReactiveIndexArrayBased,
|
|
1542
|
+
OIMReactiveIndexManualArrayBased,
|
|
1543
|
+
OIMReactiveIndexManualSetBased,
|
|
1544
|
+
OIMReactiveIndexSetBased,
|
|
1241
1545
|
OIMUpdateEventCoalescer,
|
|
1242
1546
|
OIMUpdateEventCoalescerCollection,
|
|
1243
1547
|
OIMUpdateEventCoalescerIndex,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oimdb/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Core in-memory data library with type-safe indices, reactive subscriptions, and event processing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -32,6 +32,18 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"oimdb",
|
|
37
|
+
"in-memory",
|
|
38
|
+
"database",
|
|
39
|
+
"reactive",
|
|
40
|
+
"typescript",
|
|
41
|
+
"type-safe",
|
|
42
|
+
"indices",
|
|
43
|
+
"subscriptions",
|
|
44
|
+
"event-processing",
|
|
45
|
+
"state-management"
|
|
46
|
+
],
|
|
35
47
|
"author": "Andrei Baikov",
|
|
36
48
|
"license": "MIT",
|
|
37
49
|
"devDependencies": {
|