@nymphjs/nymph 1.0.0-beta.130 → 1.0.0-beta.132
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/CHANGELOG.md +16 -0
- package/dist/Entity.d.ts +3 -1
- package/dist/Entity.js +94 -91
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.types.d.ts +4 -6
- package/dist/Nymph.d.ts +0 -2
- package/dist/Nymph.js.map +1 -1
- package/dist/Nymph.types.d.ts +1 -4
- package/dist/Nymph.types.js.map +1 -1
- package/dist/conf/defaults.js +0 -3
- package/dist/conf/defaults.js.map +1 -1
- package/dist/conf/index.d.ts +0 -14
- package/dist/conf/index.js.map +1 -1
- package/dist/driver/NymphDriver.d.ts +1 -50
- package/dist/driver/NymphDriver.js +2 -177
- package/dist/driver/NymphDriver.js.map +1 -1
- package/package.json +3 -3
- package/src/Entity.ts +109 -105
- package/src/Entity.types.ts +4 -6
- package/src/Nymph.ts +0 -2
- package/src/Nymph.types.ts +4 -4
- package/src/conf/defaults.ts +0 -3
- package/src/conf/index.ts +0 -14
- package/src/driver/NymphDriver.ts +8 -237
|
@@ -5,7 +5,12 @@ import { strtotime } from 'locutus/php/datetime/index';
|
|
|
5
5
|
import { Tokenizer } from '@sciactive/tokenizer';
|
|
6
6
|
|
|
7
7
|
import type Nymph from '../Nymph.js';
|
|
8
|
-
import
|
|
8
|
+
import {
|
|
9
|
+
type Selector,
|
|
10
|
+
type Options,
|
|
11
|
+
type FormattedSelector,
|
|
12
|
+
TilmeldAccessLevels,
|
|
13
|
+
} from '../Nymph.types.js';
|
|
9
14
|
import Entity from '../Entity.js';
|
|
10
15
|
import type { EntityInstanceType, EntityObjectType } from '../Entity.js';
|
|
11
16
|
import type {
|
|
@@ -47,22 +52,6 @@ export default abstract class NymphDriver {
|
|
|
47
52
|
|
|
48
53
|
protected tokenizer = new Tokenizer();
|
|
49
54
|
|
|
50
|
-
/**
|
|
51
|
-
* A cache to make entity retrieval faster.
|
|
52
|
-
*/
|
|
53
|
-
protected entityCache: {
|
|
54
|
-
[k: string]: {
|
|
55
|
-
cdate: number;
|
|
56
|
-
mdate: number;
|
|
57
|
-
tags: string[];
|
|
58
|
-
data: EntityData;
|
|
59
|
-
sdata: SerializedEntityData;
|
|
60
|
-
};
|
|
61
|
-
} = {};
|
|
62
|
-
/**
|
|
63
|
-
* A counter for the entity cache to determine the most accessed entities.
|
|
64
|
-
*/
|
|
65
|
-
protected entityCount: { [k: string]: number } = {};
|
|
66
55
|
/**
|
|
67
56
|
* Protect against infinite loops.
|
|
68
57
|
*/
|
|
@@ -359,8 +348,6 @@ export default abstract class NymphDriver {
|
|
|
359
348
|
sdata[propMatch[1]] = propMatch[2];
|
|
360
349
|
}
|
|
361
350
|
}
|
|
362
|
-
// Clear the entity cache.
|
|
363
|
-
this.entityCache = {};
|
|
364
351
|
}
|
|
365
352
|
// Save the last entity.
|
|
366
353
|
if (guid) {
|
|
@@ -681,15 +668,6 @@ export default abstract class NymphDriver {
|
|
|
681
668
|
}
|
|
682
669
|
}
|
|
683
670
|
|
|
684
|
-
/**
|
|
685
|
-
* Remove all copies of an entity from the cache.
|
|
686
|
-
*
|
|
687
|
-
* @param guid The GUID of the entity to remove.
|
|
688
|
-
*/
|
|
689
|
-
protected cleanCache(guid: string) {
|
|
690
|
-
delete this.entityCache[guid];
|
|
691
|
-
}
|
|
692
|
-
|
|
693
671
|
public async deleteEntity(entity: EntityInterface) {
|
|
694
672
|
const className = (entity.constructor as any).class as string;
|
|
695
673
|
if (entity.guid == null) {
|
|
@@ -1026,7 +1004,9 @@ export default abstract class NymphDriver {
|
|
|
1026
1004
|
...qrefOptions,
|
|
1027
1005
|
class: QrefEntityClass,
|
|
1028
1006
|
source: options.source,
|
|
1007
|
+
skipAc: options.skipAc,
|
|
1029
1008
|
};
|
|
1009
|
+
delete newOptions.return;
|
|
1030
1010
|
const newSelectors = this.formatSelectors(qrefSelectors, options);
|
|
1031
1011
|
qrefs.push(
|
|
1032
1012
|
[newOptions, ...newSelectors.selectors],
|
|
@@ -1280,108 +1260,6 @@ export default abstract class NymphDriver {
|
|
|
1280
1260
|
);
|
|
1281
1261
|
}
|
|
1282
1262
|
|
|
1283
|
-
// Check if the requested entity is cached.
|
|
1284
|
-
if (
|
|
1285
|
-
this.nymph.config.cache &&
|
|
1286
|
-
!options.skipCache &&
|
|
1287
|
-
selectors.length &&
|
|
1288
|
-
'guid' in selectors[0] &&
|
|
1289
|
-
typeof selectors[0].guid === 'number'
|
|
1290
|
-
) {
|
|
1291
|
-
// Only safe to use the cache option with no other selectors than a GUID
|
|
1292
|
-
// and tags.
|
|
1293
|
-
if (
|
|
1294
|
-
selectors.length === 1 &&
|
|
1295
|
-
selectors[0].type === '&' &&
|
|
1296
|
-
(Object.keys(selectors[0]).length === 2 ||
|
|
1297
|
-
(Object.keys(selectors[0]).length === 3 && 'tag' in selectors[0]))
|
|
1298
|
-
) {
|
|
1299
|
-
const cacheEntity = this.pullCache(selectors[0]['guid']);
|
|
1300
|
-
|
|
1301
|
-
if (
|
|
1302
|
-
cacheEntity != null &&
|
|
1303
|
-
cacheEntity.guid != null &&
|
|
1304
|
-
(!('tag' in selectors[0]) ||
|
|
1305
|
-
!(
|
|
1306
|
-
Array.isArray(selectors[0].tag)
|
|
1307
|
-
? selectors[0].tag
|
|
1308
|
-
: [selectors[0].tag]
|
|
1309
|
-
).find((tag) => tag == null || !cacheEntity.tags.includes(tag)))
|
|
1310
|
-
) {
|
|
1311
|
-
// Return the value from the cache.
|
|
1312
|
-
const { guid, cdate, mdate, tags, data, sdata } = cacheEntity;
|
|
1313
|
-
|
|
1314
|
-
if (options.return === 'count') {
|
|
1315
|
-
return {
|
|
1316
|
-
result: Promise.resolve(null),
|
|
1317
|
-
process: () => 1,
|
|
1318
|
-
};
|
|
1319
|
-
} else if (options.return === 'guid') {
|
|
1320
|
-
return {
|
|
1321
|
-
result: Promise.resolve(null),
|
|
1322
|
-
process: () => [guid],
|
|
1323
|
-
};
|
|
1324
|
-
} else if (options.return === 'object') {
|
|
1325
|
-
return {
|
|
1326
|
-
result: Promise.resolve(null),
|
|
1327
|
-
process: () => [
|
|
1328
|
-
{
|
|
1329
|
-
guid,
|
|
1330
|
-
cdate,
|
|
1331
|
-
mdate,
|
|
1332
|
-
tags,
|
|
1333
|
-
...data,
|
|
1334
|
-
...Object.fromEntries(
|
|
1335
|
-
Object.entries(sdata).map(([name, value]) => [
|
|
1336
|
-
name,
|
|
1337
|
-
JSON.parse(value),
|
|
1338
|
-
]),
|
|
1339
|
-
),
|
|
1340
|
-
} as EntityObjectType<T>,
|
|
1341
|
-
],
|
|
1342
|
-
};
|
|
1343
|
-
} else {
|
|
1344
|
-
const entity = this.nymph
|
|
1345
|
-
.getEntityClass(EntityClass.class)
|
|
1346
|
-
.factorySync() as EntityInstanceType<T>;
|
|
1347
|
-
if (entity) {
|
|
1348
|
-
entity.$nymph = this.nymph;
|
|
1349
|
-
if (options.skipAc != null) {
|
|
1350
|
-
entity.$useSkipAc(!!options.skipAc);
|
|
1351
|
-
}
|
|
1352
|
-
entity.guid = guid;
|
|
1353
|
-
entity.cdate = cdate;
|
|
1354
|
-
entity.mdate = mdate;
|
|
1355
|
-
entity.tags = tags;
|
|
1356
|
-
entity.$putData(
|
|
1357
|
-
classNamesToEntityConstructors(
|
|
1358
|
-
this.nymph,
|
|
1359
|
-
referencesToEntities(
|
|
1360
|
-
data,
|
|
1361
|
-
this.nymph,
|
|
1362
|
-
!!options.skipAc,
|
|
1363
|
-
false,
|
|
1364
|
-
),
|
|
1365
|
-
false,
|
|
1366
|
-
),
|
|
1367
|
-
sdata,
|
|
1368
|
-
'server',
|
|
1369
|
-
);
|
|
1370
|
-
return {
|
|
1371
|
-
result: Promise.resolve(null),
|
|
1372
|
-
process: () => [entity],
|
|
1373
|
-
};
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
return {
|
|
1377
|
-
result: Promise.resolve(null),
|
|
1378
|
-
process: () => [],
|
|
1379
|
-
};
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
1263
|
try {
|
|
1386
1264
|
const formattedSelectors = this.formatSelectors(selectors, options);
|
|
1387
1265
|
this.nymph.runQueryCallbacks(options, formattedSelectors.selectors);
|
|
@@ -1542,9 +1420,6 @@ export default abstract class NymphDriver {
|
|
|
1542
1420
|
this.putDataCounter--;
|
|
1543
1421
|
entities.push(entity);
|
|
1544
1422
|
}
|
|
1545
|
-
if (this.nymph.config.cache) {
|
|
1546
|
-
this.pushCache(guid, cdate, mdate, tags, data, sdata);
|
|
1547
|
-
}
|
|
1548
1423
|
}
|
|
1549
1424
|
}
|
|
1550
1425
|
|
|
@@ -1639,10 +1514,6 @@ export default abstract class NymphDriver {
|
|
|
1639
1514
|
entity.mdate = mdate;
|
|
1640
1515
|
}
|
|
1641
1516
|
} else {
|
|
1642
|
-
// Removed any cached versions of this entity.
|
|
1643
|
-
if (this.nymph.config.cache) {
|
|
1644
|
-
this.cleanCache(entity.guid);
|
|
1645
|
-
}
|
|
1646
1517
|
success = await saveExistingEntityCallback({
|
|
1647
1518
|
entity,
|
|
1648
1519
|
guid: entity.guid,
|
|
@@ -1660,17 +1531,6 @@ export default abstract class NymphDriver {
|
|
|
1660
1531
|
if (commitTransactionCallback) {
|
|
1661
1532
|
success = await commitTransactionCallback(success);
|
|
1662
1533
|
}
|
|
1663
|
-
// Cache the entity.
|
|
1664
|
-
if (success && this.nymph.config.cache) {
|
|
1665
|
-
this.pushCache(
|
|
1666
|
-
entity.guid as string,
|
|
1667
|
-
entity.cdate as number,
|
|
1668
|
-
entity.mdate as number,
|
|
1669
|
-
entity.tags,
|
|
1670
|
-
data,
|
|
1671
|
-
sdata,
|
|
1672
|
-
);
|
|
1673
|
-
}
|
|
1674
1534
|
|
|
1675
1535
|
if (!success) {
|
|
1676
1536
|
entity.guid = originalGuid;
|
|
@@ -1697,95 +1557,6 @@ export default abstract class NymphDriver {
|
|
|
1697
1557
|
}
|
|
1698
1558
|
}
|
|
1699
1559
|
|
|
1700
|
-
/**
|
|
1701
|
-
* Pull an entity from the cache.
|
|
1702
|
-
*
|
|
1703
|
-
* @param guid The entity's GUID.
|
|
1704
|
-
* @returns The entity's data or null if it's not cached.
|
|
1705
|
-
*/
|
|
1706
|
-
protected pullCache(guid: string): {
|
|
1707
|
-
guid: string;
|
|
1708
|
-
cdate: number;
|
|
1709
|
-
mdate: number;
|
|
1710
|
-
tags: string[];
|
|
1711
|
-
data: EntityData;
|
|
1712
|
-
sdata: SerializedEntityData;
|
|
1713
|
-
} | null {
|
|
1714
|
-
// Increment the entity access count.
|
|
1715
|
-
if (!(guid in this.entityCount)) {
|
|
1716
|
-
this.entityCount[guid] = 0;
|
|
1717
|
-
}
|
|
1718
|
-
this.entityCount[guid]++;
|
|
1719
|
-
if (guid in this.entityCache) {
|
|
1720
|
-
return {
|
|
1721
|
-
guid,
|
|
1722
|
-
cdate: this.entityCache[guid]['cdate'],
|
|
1723
|
-
mdate: this.entityCache[guid]['mdate'],
|
|
1724
|
-
tags: this.entityCache[guid]['tags'],
|
|
1725
|
-
data: this.entityCache[guid]['data'],
|
|
1726
|
-
sdata: this.entityCache[guid]['sdata'],
|
|
1727
|
-
};
|
|
1728
|
-
}
|
|
1729
|
-
return null;
|
|
1730
|
-
}
|
|
1731
|
-
|
|
1732
|
-
/**
|
|
1733
|
-
* Push an entity onto the cache.
|
|
1734
|
-
*
|
|
1735
|
-
* @param guid The entity's GUID.
|
|
1736
|
-
* @param cdate The entity's cdate.
|
|
1737
|
-
* @param mdate The entity's mdate.
|
|
1738
|
-
* @param tags The entity's tags.
|
|
1739
|
-
* @param data The entity's data.
|
|
1740
|
-
* @param sdata The entity's sdata.
|
|
1741
|
-
*/
|
|
1742
|
-
protected pushCache(
|
|
1743
|
-
guid: string,
|
|
1744
|
-
cdate: number,
|
|
1745
|
-
mdate: number,
|
|
1746
|
-
tags: string[],
|
|
1747
|
-
data: EntityData,
|
|
1748
|
-
sdata: SerializedEntityData,
|
|
1749
|
-
) {
|
|
1750
|
-
if (guid == null) {
|
|
1751
|
-
return;
|
|
1752
|
-
}
|
|
1753
|
-
// Increment the entity access count.
|
|
1754
|
-
if (!(guid in this.entityCount)) {
|
|
1755
|
-
this.entityCount[guid] = 0;
|
|
1756
|
-
}
|
|
1757
|
-
this.entityCount[guid]++;
|
|
1758
|
-
// Check the threshold.
|
|
1759
|
-
if (this.entityCount[guid] < this.nymph.config.cacheThreshold) {
|
|
1760
|
-
return;
|
|
1761
|
-
}
|
|
1762
|
-
// Cache the entity.
|
|
1763
|
-
this.entityCache[guid] = {
|
|
1764
|
-
cdate,
|
|
1765
|
-
mdate,
|
|
1766
|
-
tags,
|
|
1767
|
-
data,
|
|
1768
|
-
sdata,
|
|
1769
|
-
};
|
|
1770
|
-
while (
|
|
1771
|
-
this.nymph.config.cacheLimit &&
|
|
1772
|
-
Object.keys(this.entityCache).length >= this.nymph.config.cacheLimit
|
|
1773
|
-
) {
|
|
1774
|
-
// Find which entity has been accessed the least.
|
|
1775
|
-
const least =
|
|
1776
|
-
Object.entries(this.entityCount)
|
|
1777
|
-
.sort(([_guidA, countA], [_guidB, countB]) => countA - countB)
|
|
1778
|
-
.pop()?.[0] ?? null;
|
|
1779
|
-
if (least == null) {
|
|
1780
|
-
// This should never happen.
|
|
1781
|
-
return;
|
|
1782
|
-
}
|
|
1783
|
-
// Remove it.
|
|
1784
|
-
delete this.entityCache[least];
|
|
1785
|
-
delete this.entityCount[least];
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
1560
|
protected findReferences(svalue: string): string[] {
|
|
1790
1561
|
const re = /\["nymph_entity_reference","([0-9a-fA-F]+)",/g;
|
|
1791
1562
|
const matches = svalue.match(re);
|