@nymphjs/nymph 1.0.0-beta.131 → 1.0.0-beta.133
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/README.md +16 -9
- package/dist/Entity.d.ts +6 -6
- package/dist/Entity.js +2 -6
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.types.d.ts +5 -10
- 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/dist/testArtifacts.d.ts +6 -2
- package/dist/testArtifacts.js +13 -13
- package/dist/testArtifacts.js.map +1 -1
- package/package.json +3 -3
- package/src/Entity.ts +47 -49
- package/src/Entity.types.ts +6 -10
- 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 +7 -237
- package/src/testArtifacts.ts +19 -15
|
@@ -5,7 +5,11 @@ 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
|
+
} from '../Nymph.types.js';
|
|
9
13
|
import Entity from '../Entity.js';
|
|
10
14
|
import type { EntityInstanceType, EntityObjectType } from '../Entity.js';
|
|
11
15
|
import type {
|
|
@@ -47,22 +51,6 @@ export default abstract class NymphDriver {
|
|
|
47
51
|
|
|
48
52
|
protected tokenizer = new Tokenizer();
|
|
49
53
|
|
|
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
54
|
/**
|
|
67
55
|
* Protect against infinite loops.
|
|
68
56
|
*/
|
|
@@ -359,8 +347,6 @@ export default abstract class NymphDriver {
|
|
|
359
347
|
sdata[propMatch[1]] = propMatch[2];
|
|
360
348
|
}
|
|
361
349
|
}
|
|
362
|
-
// Clear the entity cache.
|
|
363
|
-
this.entityCache = {};
|
|
364
350
|
}
|
|
365
351
|
// Save the last entity.
|
|
366
352
|
if (guid) {
|
|
@@ -681,15 +667,6 @@ export default abstract class NymphDriver {
|
|
|
681
667
|
}
|
|
682
668
|
}
|
|
683
669
|
|
|
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
670
|
public async deleteEntity(entity: EntityInterface) {
|
|
694
671
|
const className = (entity.constructor as any).class as string;
|
|
695
672
|
if (entity.guid == null) {
|
|
@@ -1026,7 +1003,9 @@ export default abstract class NymphDriver {
|
|
|
1026
1003
|
...qrefOptions,
|
|
1027
1004
|
class: QrefEntityClass,
|
|
1028
1005
|
source: options.source,
|
|
1006
|
+
skipAc: options.skipAc,
|
|
1029
1007
|
};
|
|
1008
|
+
delete newOptions.return;
|
|
1030
1009
|
const newSelectors = this.formatSelectors(qrefSelectors, options);
|
|
1031
1010
|
qrefs.push(
|
|
1032
1011
|
[newOptions, ...newSelectors.selectors],
|
|
@@ -1280,108 +1259,6 @@ export default abstract class NymphDriver {
|
|
|
1280
1259
|
);
|
|
1281
1260
|
}
|
|
1282
1261
|
|
|
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
1262
|
try {
|
|
1386
1263
|
const formattedSelectors = this.formatSelectors(selectors, options);
|
|
1387
1264
|
this.nymph.runQueryCallbacks(options, formattedSelectors.selectors);
|
|
@@ -1542,9 +1419,6 @@ export default abstract class NymphDriver {
|
|
|
1542
1419
|
this.putDataCounter--;
|
|
1543
1420
|
entities.push(entity);
|
|
1544
1421
|
}
|
|
1545
|
-
if (this.nymph.config.cache) {
|
|
1546
|
-
this.pushCache(guid, cdate, mdate, tags, data, sdata);
|
|
1547
|
-
}
|
|
1548
1422
|
}
|
|
1549
1423
|
}
|
|
1550
1424
|
|
|
@@ -1639,10 +1513,6 @@ export default abstract class NymphDriver {
|
|
|
1639
1513
|
entity.mdate = mdate;
|
|
1640
1514
|
}
|
|
1641
1515
|
} else {
|
|
1642
|
-
// Removed any cached versions of this entity.
|
|
1643
|
-
if (this.nymph.config.cache) {
|
|
1644
|
-
this.cleanCache(entity.guid);
|
|
1645
|
-
}
|
|
1646
1516
|
success = await saveExistingEntityCallback({
|
|
1647
1517
|
entity,
|
|
1648
1518
|
guid: entity.guid,
|
|
@@ -1660,17 +1530,6 @@ export default abstract class NymphDriver {
|
|
|
1660
1530
|
if (commitTransactionCallback) {
|
|
1661
1531
|
success = await commitTransactionCallback(success);
|
|
1662
1532
|
}
|
|
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
1533
|
|
|
1675
1534
|
if (!success) {
|
|
1676
1535
|
entity.guid = originalGuid;
|
|
@@ -1697,95 +1556,6 @@ export default abstract class NymphDriver {
|
|
|
1697
1556
|
}
|
|
1698
1557
|
}
|
|
1699
1558
|
|
|
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
1559
|
protected findReferences(svalue: string): string[] {
|
|
1790
1560
|
const re = /\["nymph_entity_reference","([0-9a-fA-F]+)",/g;
|
|
1791
1561
|
const matches = svalue.match(re);
|
package/src/testArtifacts.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Entity from './Entity.js';
|
|
|
2
2
|
import { transactional } from './decorators/index.js';
|
|
3
3
|
import { transaction } from './helpers/index.js';
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export interface TestModelData {
|
|
6
6
|
name?: string;
|
|
7
7
|
null?: null;
|
|
8
8
|
string?: string;
|
|
@@ -24,7 +24,9 @@ export type TestModelData = {
|
|
|
24
24
|
index?: string;
|
|
25
25
|
// For uniqueness tests.
|
|
26
26
|
uniques?: string[];
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface TestModel extends TestModelData {}
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* This class is a test class that extends the Entity class.
|
|
@@ -43,12 +45,12 @@ export class TestModel extends Entity<TestModelData> {
|
|
|
43
45
|
super();
|
|
44
46
|
|
|
45
47
|
this.$addTag('test');
|
|
46
|
-
this
|
|
47
|
-
this
|
|
48
|
+
this.boolean = true;
|
|
49
|
+
this.uniques = [];
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
public async $getUniques() {
|
|
51
|
-
return this
|
|
53
|
+
return this.uniques ?? [];
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
public $useProtectedData() {
|
|
@@ -72,12 +74,12 @@ export class TestModel extends Entity<TestModelData> {
|
|
|
72
74
|
|
|
73
75
|
@transactional
|
|
74
76
|
public async $testTransactionalDecorator(throwError: boolean) {
|
|
75
|
-
this
|
|
77
|
+
this.string = 'this has been changed';
|
|
76
78
|
|
|
77
|
-
if (this
|
|
78
|
-
await this
|
|
79
|
-
this
|
|
80
|
-
await this
|
|
79
|
+
if (this.reference) {
|
|
80
|
+
await this.reference.$wake();
|
|
81
|
+
this.reference.string = 'this has been changed too';
|
|
82
|
+
await this.reference.$save();
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
await this.$save();
|
|
@@ -95,12 +97,12 @@ export class TestModel extends Entity<TestModelData> {
|
|
|
95
97
|
'test-transaction',
|
|
96
98
|
async (nymph) => {
|
|
97
99
|
this.$setNymph(nymph);
|
|
98
|
-
this
|
|
100
|
+
this.string = 'this has been changed';
|
|
99
101
|
|
|
100
|
-
if (this
|
|
101
|
-
await this
|
|
102
|
-
this
|
|
103
|
-
await this
|
|
102
|
+
if (this.reference) {
|
|
103
|
+
await this.reference.$wake();
|
|
104
|
+
this.reference.string = 'this has been changed too';
|
|
105
|
+
await this.reference.$save();
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
await this.$save();
|
|
@@ -128,6 +130,8 @@ export class TestBModel extends TestModel {
|
|
|
128
130
|
|
|
129
131
|
export type TestEmptyModelData = {};
|
|
130
132
|
|
|
133
|
+
export interface TestEmptyModel extends TestEmptyModelData {}
|
|
134
|
+
|
|
131
135
|
/**
|
|
132
136
|
* This class is a test class that extends the Entity class.
|
|
133
137
|
*/
|