theprogrammablemind 7.5.0 → 7.5.2
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/client.js +116 -38
- package/lines.js +3 -0
- package/package.json +1 -1
- package/src/config.js +362 -60
- package/src/digraph.js +28 -7
- package/src/generators.js +4 -2
- package/src/helpers.js +39 -1
- package/src/semantics.js +4 -2
package/client.js
CHANGED
@@ -78,7 +78,15 @@ const listable = (hierarchy) => (c, type) => {
|
|
78
78
|
return false
|
79
79
|
}
|
80
80
|
|
81
|
-
const isA = (hierarchy) => (child, parent) =>
|
81
|
+
const isA = (hierarchy) => (child, parent) => {
|
82
|
+
if (child.marker) {
|
83
|
+
child = child.marker
|
84
|
+
}
|
85
|
+
if (parent.marker) {
|
86
|
+
parent = parent.marker
|
87
|
+
}
|
88
|
+
return hierarchy.isA(child, parent)
|
89
|
+
}
|
82
90
|
|
83
91
|
const asList = (context) => {
|
84
92
|
if (context.marker === 'list') {
|
@@ -518,7 +526,7 @@ const processInstance = (config, instance) => {
|
|
518
526
|
global.transitoryMode = transitoryMode
|
519
527
|
}
|
520
528
|
|
521
|
-
const _process = async (config, query, { credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
529
|
+
const _process = async (config, query, { commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
522
530
|
if (credentials) {
|
523
531
|
config.server(credentials.server, credentials.key)
|
524
532
|
}
|
@@ -539,6 +547,9 @@ const _process = async (config, query, { credentials, writeTests, isTest, saveDe
|
|
539
547
|
}
|
540
548
|
|
541
549
|
let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, allowDelta: true })
|
550
|
+
if (commandLineArgs && commandLineArgs.checkForLoop) {
|
551
|
+
data.checkForLoop = true
|
552
|
+
}
|
542
553
|
let queries = query.split('\\n')
|
543
554
|
|
544
555
|
try {
|
@@ -670,9 +681,12 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
670
681
|
defaultErrorHandler(error)
|
671
682
|
}
|
672
683
|
|
673
|
-
|
684
|
+
let objects = getObjects(config.config.objects)(config.uuid)
|
685
|
+
if (testConfig.testModuleName) {
|
686
|
+
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
687
|
+
}
|
674
688
|
config.beforeQuery({ query: test, isModule: false, objects })
|
675
|
-
config.resetMotivations()
|
689
|
+
// config.resetMotivations()
|
676
690
|
try {
|
677
691
|
const result = await _process(config, test, { errorHandler, isTest: true })
|
678
692
|
result.query = test
|
@@ -692,10 +706,23 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
692
706
|
const failed_responses = !matching(result.responses, expected.responses)
|
693
707
|
const failed_contexts = !matching(result.contexts, expected.contexts)
|
694
708
|
const failed_objects = !matching(actual_objects, expected_objects)
|
709
|
+
|
710
|
+
const pickEm = (objects) => {
|
711
|
+
const picked = {}
|
712
|
+
for (let prop of (testConfig.check || [])) {
|
713
|
+
picked[prop] = objects[prop]
|
714
|
+
}
|
715
|
+
return picked
|
716
|
+
}
|
717
|
+
const expected_checked = sortJson(pickEm(expected.objects.namespaced[0]), { depth: 25 })
|
718
|
+
const actual_checked = sortJson(pickEm(objects), { depth: 25 })
|
719
|
+
const failed_checked = !matching(actual_objects, expected_objects)
|
720
|
+
|
721
|
+
const failed_checks = !matching(actual_objects, expected_objects)
|
695
722
|
const actual_config = sortJson(convertToStable(getConfigForTest(config, testConfig)), { depth: 25 })
|
696
723
|
const expected_config = sortJson(convertToStable(expected.config), { depth: 25 })
|
697
724
|
const failed_config = !matching(actual_config, expected_config)
|
698
|
-
let failed = failed_paraphrases || failed_responses || failed_contexts || failed_objects || failed_config
|
725
|
+
let failed = failed_paraphrases || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
|
699
726
|
if (!failed) {
|
700
727
|
if (config.afterTest) {
|
701
728
|
failed = config.afterTest({ query: test, expected, actual: result, config })
|
@@ -703,8 +730,8 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
703
730
|
return {
|
704
731
|
utterance: test,
|
705
732
|
errorFromAfterTest: failed,
|
706
|
-
expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, objects: expected_objects, config: expected.config },
|
707
|
-
actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, objects: actual_objects, config: actual_config }
|
733
|
+
expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, checked: expected_checked, objects: expected_objects, config: expected.config },
|
734
|
+
actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, checked: actual_checked, objects: actual_objects, config: actual_config }
|
708
735
|
}
|
709
736
|
}
|
710
737
|
}
|
@@ -720,8 +747,8 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
720
747
|
if (failed) {
|
721
748
|
return {
|
722
749
|
utterance: test,
|
723
|
-
expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, objects: expected_objects, config: expected.config },
|
724
|
-
actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, objects: actual_objects, config: actual_config }
|
750
|
+
expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, checked: expected_checked, objects: expected_objects, config: expected.config },
|
751
|
+
actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, checked: actual_checked, objects: actual_objects, config: actual_config }
|
725
752
|
}
|
726
753
|
}
|
727
754
|
} catch(error) {
|
@@ -770,7 +797,7 @@ const runTests = async (config, testFile, juicyBits) => {
|
|
770
797
|
const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
|
771
798
|
config.rebuild()
|
772
799
|
const objects = getObjects(config.config.objects)(config.uuid)
|
773
|
-
config.resetMotivations()
|
800
|
+
//config.resetMotivations()
|
774
801
|
config.beforeQuery({ query: test, isModule: false, objects })
|
775
802
|
console.log(test)
|
776
803
|
const result = await _process(config, test, { isTest: true })
|
@@ -845,6 +872,7 @@ const submitBugToAPI = async (subscription_id, subscription_password, config) =>
|
|
845
872
|
})
|
846
873
|
}
|
847
874
|
|
875
|
+
/*
|
848
876
|
const submitBug = async (subscription_id, subscription_password, config, utterance, retries = 2) => {
|
849
877
|
// TODO remove these from the config
|
850
878
|
const properties = ['expected_contexts', 'expected_generated']
|
@@ -881,6 +909,7 @@ const submitBug = async (subscription_id, subscription_password, config, utteran
|
|
881
909
|
throw error
|
882
910
|
})
|
883
911
|
}
|
912
|
+
*/
|
884
913
|
|
885
914
|
const defaultErrorHandler = async (error) => {
|
886
915
|
if (error.logs) {
|
@@ -1035,7 +1064,6 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1035
1064
|
if (typeof queryOrExtraConfig === 'string') {
|
1036
1065
|
query = { query }
|
1037
1066
|
}
|
1038
|
-
console.log('query', query.query)
|
1039
1067
|
config.config.skipSemantics = skipSemantics
|
1040
1068
|
const transitoryMode = global.transitoryMode
|
1041
1069
|
if (property == 'fragments') {
|
@@ -1059,6 +1087,11 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1059
1087
|
// TODO pass in the error handler like the other ones
|
1060
1088
|
defaultInnerProcess(config, defaultErrorHandler, results)
|
1061
1089
|
}
|
1090
|
+
if (results.contexts.length > 1) {
|
1091
|
+
console.log(`query ${query.query}. There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1092
|
+
} else {
|
1093
|
+
console.log(`query ${query.query}`)
|
1094
|
+
}
|
1062
1095
|
global.transitoryMode = transitoryMode
|
1063
1096
|
config.config.skipSemantics = null
|
1064
1097
|
results.query = query.query
|
@@ -1239,7 +1272,7 @@ const knowledgeModule = async ({
|
|
1239
1272
|
description: 'Entodicton knowledge module'
|
1240
1273
|
})
|
1241
1274
|
|
1242
|
-
parser.add_argument('-
|
1275
|
+
parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
|
1243
1276
|
parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
|
1244
1277
|
parser.add_argument('-tv', '--testVerbose', { action: 'store_true', help: 'Run the tests in verbose mode. Create tests by running with the --query or --loop with the --save flag' })
|
1245
1278
|
parser.add_argument('-tva', '--testAllVerbose', { action: 'store_true', help: 'Run the tests in verbose mode. All the tests will be run instead of stopping at first failure. Create tests by running with the --query or --loop with the --save flag' })
|
@@ -1250,11 +1283,12 @@ const knowledgeModule = async ({
|
|
1250
1283
|
parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
|
1251
1284
|
parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
|
1252
1285
|
parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
|
1286
|
+
parser.add_argument('-cl', '--checkForLoop', { action: 'store_true', help: 'Check for loops in the priorities' })
|
1253
1287
|
parser.add_argument('-r', '--retrain', { action: 'store_true', help: 'Get the server to retrain the neural nets' })
|
1254
1288
|
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
1255
1289
|
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
1256
1290
|
parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
|
1257
|
-
parser.add_argument('-
|
1291
|
+
parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
|
1258
1292
|
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
1259
1293
|
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
1260
1294
|
parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
|
@@ -1293,11 +1327,11 @@ const knowledgeModule = async ({
|
|
1293
1327
|
return
|
1294
1328
|
}
|
1295
1329
|
|
1296
|
-
if (args.
|
1330
|
+
if (args.deleteTest) {
|
1297
1331
|
let tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
|
1298
|
-
tests = tests.filter( (test) => test.query !== args.
|
1332
|
+
tests = tests.filter( (test) => test.query !== args.deleteTest );
|
1299
1333
|
writeTestFile(testConfig.name, tests)
|
1300
|
-
console.log(`Remove the test for "${args.
|
1334
|
+
console.log(`Remove the test for "${args.deleteTest}"`)
|
1301
1335
|
return
|
1302
1336
|
}
|
1303
1337
|
|
@@ -1453,7 +1487,15 @@ const knowledgeModule = async ({
|
|
1453
1487
|
}
|
1454
1488
|
return
|
1455
1489
|
}
|
1456
|
-
|
1490
|
+
let useTestConfig = testConfig
|
1491
|
+
if (args.testModuleName) {
|
1492
|
+
useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
1493
|
+
useTestConfig.testModuleName = args.testModuleName
|
1494
|
+
test = useTestConfig.name
|
1495
|
+
|
1496
|
+
}
|
1497
|
+
// runTests(config, args.testFileName ? `${args.testFileName}.test.json` : test, { debug: args.debug, testConfig: testConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1498
|
+
runTests(config, test, { debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1457
1499
|
if (results.length > 0 && args.vimdiff) {
|
1458
1500
|
for (const result of results) {
|
1459
1501
|
vimdiff(result.expected, result.actual)
|
@@ -1462,34 +1504,69 @@ const knowledgeModule = async ({
|
|
1462
1504
|
let newError = false
|
1463
1505
|
if (results.length > 0) {
|
1464
1506
|
let headerShown = false
|
1465
|
-
|
1507
|
+
|
1508
|
+
let hasError = false
|
1466
1509
|
for (const result of results) {
|
1467
|
-
console.log('Utterance: ', result.utterance)
|
1468
1510
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1469
|
-
|
1470
|
-
console.log(' Failure')
|
1471
|
-
}
|
1472
|
-
console.log(' expected paraphrases', result.expected.paraphrases)
|
1473
|
-
console.log(' actual paraphrases ', result.actual.paraphrases)
|
1474
|
-
newError = true
|
1475
|
-
headerShown = true
|
1511
|
+
hasError = true
|
1476
1512
|
}
|
1477
1513
|
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1478
|
-
|
1479
|
-
|
1514
|
+
hasError = true
|
1515
|
+
}
|
1516
|
+
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1517
|
+
hasError = true
|
1518
|
+
}
|
1519
|
+
}
|
1520
|
+
|
1521
|
+
if (hasError) {
|
1522
|
+
console.log('**************************** ERRORS ************************')
|
1523
|
+
for (const result of results) {
|
1524
|
+
console.log('Utterance: ', result.utterance)
|
1525
|
+
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1526
|
+
if (!headerShown) {
|
1527
|
+
console.log(' Failure')
|
1528
|
+
}
|
1529
|
+
console.log(' expected paraphrases', result.expected.paraphrases)
|
1530
|
+
console.log(' actual paraphrases ', result.actual.paraphrases)
|
1531
|
+
newError = true
|
1532
|
+
headerShown = true
|
1533
|
+
}
|
1534
|
+
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1535
|
+
if (!headerShown) {
|
1536
|
+
console.log(' Failure')
|
1537
|
+
}
|
1538
|
+
console.log(' expected responses ', result.expected.responses)
|
1539
|
+
console.log(' actual responses ', result.actual.responses)
|
1540
|
+
newError = true
|
1541
|
+
headerShown = true
|
1542
|
+
}
|
1543
|
+
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1544
|
+
if (!headerShown) {
|
1545
|
+
console.log(' Failure')
|
1546
|
+
}
|
1547
|
+
const widths = [4, 18, 72]
|
1548
|
+
const lines = new Lines(widths)
|
1549
|
+
lines.setElement(1, 1, 'expected checked')
|
1550
|
+
lines.setElement(2, 2, JSON.stringify(result.expected.checked, null, 2))
|
1551
|
+
lines.log()
|
1552
|
+
lines.setElement(1, 1, 'actual checked')
|
1553
|
+
lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
|
1554
|
+
lines.log()
|
1555
|
+
newError = true
|
1556
|
+
headerShown = true
|
1480
1557
|
}
|
1481
|
-
console.log(' expected responses ', result.expected.responses)
|
1482
|
-
console.log(' actual responses ', result.actual.responses)
|
1483
|
-
newError = true
|
1484
|
-
headerShown = true
|
1485
1558
|
}
|
1486
1559
|
}
|
1487
1560
|
if (!headerShown) {
|
1488
|
-
|
1561
|
+
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1562
|
+
console.log('There are failures due to things other than paraphrases, responses and checked properties being different. They are not shown because you ran -tv or -tva which only shows difference in paraphrase and results. Usually what I do is -s and do a diff to make sure there are no other problems. If the paraphrases or results were different they would have shown here.')
|
1563
|
+
}
|
1564
|
+
}
|
1565
|
+
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1566
|
+
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1567
|
+
// console.log(JSON.stringify(contexts))
|
1568
|
+
console.log('**************************** ERRORS ************************')
|
1489
1569
|
}
|
1490
|
-
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1491
|
-
// console.log(JSON.stringify(contexts))
|
1492
|
-
console.log('**************************** ERRORS ************************')
|
1493
1570
|
}
|
1494
1571
|
// const contexts = { failures: results }
|
1495
1572
|
l(n - 1, hasError || newError)
|
@@ -1540,13 +1617,14 @@ const knowledgeModule = async ({
|
|
1540
1617
|
}
|
1541
1618
|
config.beforeQuery({ query: args.query, isModule: false, objects })
|
1542
1619
|
try {
|
1543
|
-
processResults(_process(config, args.query, { dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1620
|
+
processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1544
1621
|
} catch( error ) {
|
1545
1622
|
console.log('Error', error);
|
1546
1623
|
}
|
1547
1624
|
}
|
1548
1625
|
} else {
|
1549
1626
|
config.addAssociationsFromTests(config.tests);
|
1627
|
+
config.setTestConfig(testConfig)
|
1550
1628
|
//for (let query in config.tests) {
|
1551
1629
|
// config.addAssociations(config.tests[query].associations || []);
|
1552
1630
|
//}
|
@@ -1596,7 +1674,7 @@ module.exports = {
|
|
1596
1674
|
process: _process,
|
1597
1675
|
where,
|
1598
1676
|
w,
|
1599
|
-
submitBug,
|
1677
|
+
// submitBug,
|
1600
1678
|
ensureTestFile,
|
1601
1679
|
build,
|
1602
1680
|
processContext,
|
package/lines.js
CHANGED
@@ -12,6 +12,9 @@ class Lines {
|
|
12
12
|
// will wrap to next line within the column
|
13
13
|
setElement (row, column, value) {
|
14
14
|
const values = value.toString().split('\n')
|
15
|
+
if (column >= this.widths.length) {
|
16
|
+
throw "Column out of range."
|
17
|
+
}
|
15
18
|
const width = this.widths[column]
|
16
19
|
let index = 0
|
17
20
|
for (value of values) {
|
package/package.json
CHANGED
package/src/config.js
CHANGED
@@ -330,6 +330,17 @@ class Config {
|
|
330
330
|
return `${maybeName}${counter}`
|
331
331
|
}
|
332
332
|
|
333
|
+
setTestConfig(testConfig) {
|
334
|
+
if (this.name == 'ui') {
|
335
|
+
console.log('ui setting testConfig')
|
336
|
+
}
|
337
|
+
this.testConfig = testConfig
|
338
|
+
}
|
339
|
+
|
340
|
+
getTestConfig() {
|
341
|
+
return this.testConfig
|
342
|
+
}
|
343
|
+
|
333
344
|
defaultConfig () {
|
334
345
|
this.config = {
|
335
346
|
operators: [], // TODO
|
@@ -412,11 +423,11 @@ class Config {
|
|
412
423
|
}
|
413
424
|
|
414
425
|
getSemantics (logs = []) {
|
415
|
-
return new Semantics(this.config.semantics
|
426
|
+
return new Semantics(this.config.semantics, logs, { km: this.name })
|
416
427
|
}
|
417
428
|
|
418
429
|
getGenerators (logs = []) {
|
419
|
-
return new Generators(this.config.generators
|
430
|
+
return new Generators(this.config.generators, logs, { km: this.name })
|
420
431
|
}
|
421
432
|
|
422
433
|
warningNotEvaluated (log, value) {
|
@@ -531,9 +542,23 @@ class Config {
|
|
531
542
|
client.build({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
|
532
543
|
} else {
|
533
544
|
// no change
|
534
|
-
this.initInstances.push(instance)
|
535
|
-
|
536
|
-
|
545
|
+
// this.initInstances.push({ ...instance, name: config.name })
|
546
|
+
const isEmpty = ( instance ) => {
|
547
|
+
const properties = [
|
548
|
+
"queries",
|
549
|
+
"resultss",
|
550
|
+
"fragments",
|
551
|
+
"semantics",
|
552
|
+
"associations",
|
553
|
+
]
|
554
|
+
return !properties.find( (property) => instance[property].length > 0 )
|
555
|
+
}
|
556
|
+
if (!isEmpty(instance)) {
|
557
|
+
instance.name = this.name
|
558
|
+
this.initInstances.push(instance)
|
559
|
+
this.instances.push(instance)
|
560
|
+
client.processInstance(this, instance)
|
561
|
+
}
|
537
562
|
}
|
538
563
|
}
|
539
564
|
|
@@ -593,18 +618,21 @@ class Config {
|
|
593
618
|
}
|
594
619
|
}
|
595
620
|
|
596
|
-
addHierarchyProperties (
|
597
|
-
|
621
|
+
addHierarchyProperties (edge) {
|
622
|
+
const { child, parent } = edge
|
623
|
+
if (typeof child !== 'string') {
|
598
624
|
throw `addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`
|
599
625
|
}
|
600
|
-
if (typeof
|
601
|
-
throw `addHierarchy expected parent
|
626
|
+
if (typeof parent !== 'string') {
|
627
|
+
throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
|
602
628
|
}
|
603
|
-
if (
|
604
|
-
|
629
|
+
if (global.entodictonDebugHierarchy) {
|
630
|
+
if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
|
631
|
+
debugger; // debug hierarchy hit
|
632
|
+
}
|
605
633
|
}
|
606
|
-
|
607
|
-
this.
|
634
|
+
this.config.hierarchy.push(edge)
|
635
|
+
// TODO greg11 this.hierarchy.addEdge(edge)
|
608
636
|
this._delta.json.hierarchy.push([child, parent])
|
609
637
|
}
|
610
638
|
|
@@ -615,14 +643,13 @@ class Config {
|
|
615
643
|
if (typeof parent !== 'string') {
|
616
644
|
throw `addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`
|
617
645
|
}
|
618
|
-
|
619
|
-
this.config.hierarchy = []
|
620
|
-
}
|
646
|
+
|
621
647
|
if (global.entodictonDebugHierarchy) {
|
622
648
|
if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
|
623
649
|
debugger; // debug hierarchy hit
|
624
650
|
}
|
625
651
|
}
|
652
|
+
|
626
653
|
if (this.config.hierarchy.find( (element) => {
|
627
654
|
const hc = hierarchyCanonical(element)
|
628
655
|
if (child == hc.child && parent == hc.parent) {
|
@@ -633,6 +660,7 @@ class Config {
|
|
633
660
|
}
|
634
661
|
|
635
662
|
this.config.hierarchy.push([child, parent])
|
663
|
+
// this.hierarchy.addEdge([child, parent])
|
636
664
|
this._delta.json.hierarchy.push([child, parent])
|
637
665
|
}
|
638
666
|
|
@@ -953,17 +981,11 @@ class Config {
|
|
953
981
|
if (!config) {
|
954
982
|
return
|
955
983
|
}
|
956
|
-
config.operators = config.operators || []
|
957
|
-
config.bridges = config.bridges || []
|
958
|
-
config.words = config.words || {}
|
959
|
-
config.generators = config.generators || []
|
960
|
-
config.semantics = config.semantics || []
|
961
|
-
|
962
984
|
config.operators = config.operators.filter( (element) => !element.development )
|
963
985
|
config.bridges = config.bridges.filter( (element) => !element.development )
|
964
986
|
config.generators = config.generators.filter( (element) => !element.development )
|
965
987
|
config.semantics = config.semantics.filter( (element) => !element.development )
|
966
|
-
config.hierarchy = (config.hierarchy
|
988
|
+
config.hierarchy = (config.hierarchy).filter( (element) => !element.development )
|
967
989
|
for (const word in config.words) {
|
968
990
|
const defs = config.words[word] || []
|
969
991
|
config.words[word] = defs.filter( (def) => !def.development )
|
@@ -979,6 +1001,44 @@ class Config {
|
|
979
1001
|
throw 'Excepted the config argument to be a hash not a Config object'
|
980
1002
|
}
|
981
1003
|
|
1004
|
+
if (config) {
|
1005
|
+
const valid = [
|
1006
|
+
'hierarchy',
|
1007
|
+
'objects',
|
1008
|
+
'bridges',
|
1009
|
+
'operators',
|
1010
|
+
'words',
|
1011
|
+
'priorities',
|
1012
|
+
'associations',
|
1013
|
+
'name',
|
1014
|
+
'version',
|
1015
|
+
'generators',
|
1016
|
+
'semantics',
|
1017
|
+
'floaters',
|
1018
|
+
'debug',
|
1019
|
+
|
1020
|
+
// TODO Fix these from the test app
|
1021
|
+
'implicit',
|
1022
|
+
'expected_generated',
|
1023
|
+
'expected_results',
|
1024
|
+
'skipSemantics',
|
1025
|
+
'description',
|
1026
|
+
'contexts',
|
1027
|
+
'utterances',
|
1028
|
+
'flatten',
|
1029
|
+
]
|
1030
|
+
helpers.validProps(valid, config, 'config')
|
1031
|
+
|
1032
|
+
config.operators = config.operators || []
|
1033
|
+
config.bridges = config.bridges || []
|
1034
|
+
config.words = config.words || {}
|
1035
|
+
config.generators = config.generators || []
|
1036
|
+
config.semantics = config.semantics || []
|
1037
|
+
config.hierarchy = config.hierarchy || []
|
1038
|
+
config.associations = config.associations || { negative: [], positive: [] }
|
1039
|
+
config.priorities = config.priorities || []
|
1040
|
+
}
|
1041
|
+
|
982
1042
|
this.allowDelta = false
|
983
1043
|
this.resetDelta()
|
984
1044
|
|
@@ -1030,7 +1090,8 @@ class Config {
|
|
1030
1090
|
normalizeConfig(config)
|
1031
1091
|
|
1032
1092
|
// set the default server so stuff just works
|
1033
|
-
this.server('
|
1093
|
+
// this.server('https://184.67.27.82:3000', '6804954f-e56d-471f-bbb8-08e3c54d9321')
|
1094
|
+
this.server('https://thinktelligence.com:3000', '6804954f-e56d-471f-bbb8-08e3c54d9321')
|
1034
1095
|
|
1035
1096
|
this.defaultConfig()
|
1036
1097
|
this.initializerFn = ({ currentConfig }) => {
|
@@ -1053,25 +1114,10 @@ class Config {
|
|
1053
1114
|
if (config) {
|
1054
1115
|
config = _.cloneDeep(config)
|
1055
1116
|
this.config = config
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
this.config.semantics = []
|
1061
|
-
}
|
1062
|
-
if (!this.config.words) {
|
1063
|
-
// this.config.words = {}
|
1064
|
-
}
|
1065
|
-
for (let bridge of (this.config.bridges || [])) {
|
1066
|
-
const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'hierarchy', 'id', 'inverted', 'isA',
|
1067
|
-
'level', 'optional', 'selector', 'semantic', 'uuid', 'words' ]
|
1068
|
-
for (let prop of Object.keys(bridge)) {
|
1069
|
-
if (!valid.includes(prop)) {
|
1070
|
-
if (!prop.endsWith("Bridge")) {
|
1071
|
-
throw `Unknown property "${prop}" in the bridge. Valid properties are ${valid}. The bridge is ${JSON.stringify(bridge)}`
|
1072
|
-
}
|
1073
|
-
}
|
1074
|
-
}
|
1117
|
+
for (let bridge of this.config.bridges) {
|
1118
|
+
const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'implicit', 'inverted', 'isA', 'children', 'parents',
|
1119
|
+
'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy' ]
|
1120
|
+
helpers.validProps(valid, bridge, 'bridge')
|
1075
1121
|
/*
|
1076
1122
|
if (bridge.generator) {
|
1077
1123
|
this.config.generators.push({
|
@@ -1080,6 +1126,16 @@ class Config {
|
|
1080
1126
|
})
|
1081
1127
|
}
|
1082
1128
|
*/
|
1129
|
+
if (bridge.children) {
|
1130
|
+
for (let child of bridge.children) {
|
1131
|
+
this.addHierarchy(child, bridge.id)
|
1132
|
+
}
|
1133
|
+
}
|
1134
|
+
if (bridge.parents) {
|
1135
|
+
for (let parent of bridge.parents) {
|
1136
|
+
this.addHierarchy(bridge.id, parent)
|
1137
|
+
}
|
1138
|
+
}
|
1083
1139
|
if (bridge.isA) {
|
1084
1140
|
for (let parent of bridge.isA) {
|
1085
1141
|
this.addHierarchy(bridge.id, parent)
|
@@ -1087,6 +1143,9 @@ class Config {
|
|
1087
1143
|
}
|
1088
1144
|
if (bridge.before) {
|
1089
1145
|
for (let after of bridge.before) {
|
1146
|
+
if (typeof after == 'string') {
|
1147
|
+
after = [after, 0]
|
1148
|
+
}
|
1090
1149
|
this.addPriorities([after, [bridge.id, bridge.level]])
|
1091
1150
|
}
|
1092
1151
|
}
|
@@ -1151,6 +1210,7 @@ class Config {
|
|
1151
1210
|
})
|
1152
1211
|
}
|
1153
1212
|
}
|
1213
|
+
this.hierarchy = new Digraph(this.config.hierarchy)
|
1154
1214
|
this.initConfig = _.cloneDeep(this.config)
|
1155
1215
|
this.configs.push(new KM({ config: this.config, getCounter: (name) => this.config.getCounter(name), uuid: this._uuid }))
|
1156
1216
|
|
@@ -1238,6 +1298,10 @@ class Config {
|
|
1238
1298
|
}
|
1239
1299
|
|
1240
1300
|
set api (value) {
|
1301
|
+
if (!value.initialize) {
|
1302
|
+
throw `Expected the API to have an initialize function for ${this.name}.`
|
1303
|
+
}
|
1304
|
+
|
1241
1305
|
if (this._api && this._api.multiApi) {
|
1242
1306
|
this._api.add(this, this._api, value)
|
1243
1307
|
} else {
|
@@ -1350,12 +1414,13 @@ class Config {
|
|
1350
1414
|
cp.name = this.name
|
1351
1415
|
cp.description = this.description
|
1352
1416
|
cp.tests = this.tests
|
1353
|
-
cp.motivations = this.motivations
|
1417
|
+
cp.motivations = [...this.motivations]
|
1354
1418
|
cp.isModule = this.isModule
|
1355
1419
|
cp.loadedForTesting = this.loadedForTesting
|
1356
1420
|
cp.initInstances = this.initInstances.slice()
|
1357
1421
|
cp.instances = this.instances.slice()
|
1358
1422
|
cp.configCounter = this.configCounter
|
1423
|
+
cp.testConfig = this.testConfig
|
1359
1424
|
|
1360
1425
|
cp.initConfig = _.cloneDeep(this.initConfig)
|
1361
1426
|
cp.defaultConfig()
|
@@ -1401,7 +1466,7 @@ class Config {
|
|
1401
1466
|
this.config.bridges && this.config.bridges.forEach((bridge) => { bridge.uuid = this._uuid })
|
1402
1467
|
this.config.words && setWordsUUIDs(this.config.words, this._uuid)
|
1403
1468
|
this.config.operators && this.config.operators.forEach((operator) => { operator.uuid = this._uuid })
|
1404
|
-
const ids = Array.from(new Set(
|
1469
|
+
const ids = Array.from(new Set(this.config.bridges.map((bridge) => bridge.id)))
|
1405
1470
|
ids.sort()
|
1406
1471
|
this.config.namespaces = {}
|
1407
1472
|
// if (true || ids.length > 0) {
|
@@ -1482,7 +1547,8 @@ class Config {
|
|
1482
1547
|
}
|
1483
1548
|
|
1484
1549
|
initializeFromConfigs () {
|
1485
|
-
this.configs.forEach(({ config, namespace, uuid }) => {
|
1550
|
+
// [...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
|
1551
|
+
[...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
|
1486
1552
|
/*
|
1487
1553
|
let objects = this.get('objects')
|
1488
1554
|
if (namespace) {
|
@@ -1617,6 +1683,13 @@ class Config {
|
|
1617
1683
|
return false
|
1618
1684
|
}
|
1619
1685
|
|
1686
|
+
/* TODO greg11
|
1687
|
+
if (!this.hierarchy) {
|
1688
|
+
debugBreak()
|
1689
|
+
return false
|
1690
|
+
}
|
1691
|
+
*/
|
1692
|
+
|
1620
1693
|
for (const key in this.config.words) {
|
1621
1694
|
const values = this.config.words[key]
|
1622
1695
|
if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
|
@@ -1626,7 +1699,7 @@ class Config {
|
|
1626
1699
|
}
|
1627
1700
|
|
1628
1701
|
const kmsUuids = this.configs.map((km) => km.uuid)
|
1629
|
-
const bridgesUuids =
|
1702
|
+
const bridgesUuids = this.config.bridges.map((bridge) => bridge.uuid).filter((uuid) => uuid)
|
1630
1703
|
let result = true
|
1631
1704
|
bridgesUuids.forEach((buuid) => {
|
1632
1705
|
if (!kmsUuids.includes(buuid)) {
|
@@ -1696,6 +1769,7 @@ class Config {
|
|
1696
1769
|
this.resetDelta()
|
1697
1770
|
const debug = this.config.debug;
|
1698
1771
|
this.config = _.cloneDeep(this.initConfig)
|
1772
|
+
this.hierarchy = new Digraph(this.config.hierarchy)
|
1699
1773
|
if (debug) {
|
1700
1774
|
this.config.debug = debug
|
1701
1775
|
}
|
@@ -1710,6 +1784,7 @@ class Config {
|
|
1710
1784
|
}
|
1711
1785
|
this.config.objects.namespaced = {}
|
1712
1786
|
this.resetWasInitialized()
|
1787
|
+
this.resetMotivations()
|
1713
1788
|
|
1714
1789
|
// reorder configs base on load ordering
|
1715
1790
|
{
|
@@ -1725,8 +1800,17 @@ class Config {
|
|
1725
1800
|
this.configs = [...oconfigs]
|
1726
1801
|
}
|
1727
1802
|
|
1803
|
+
const addInternals = []
|
1728
1804
|
const inits = []
|
1729
1805
|
const initAfterApis = []
|
1806
|
+
if (false && this.config.hierarchy.find( (pair) => JSON.stringify(pair) === JSON.stringify(["equipable2","property"]))) {
|
1807
|
+
debugger // happened
|
1808
|
+
}
|
1809
|
+
if (false && this.name == 'countable') {
|
1810
|
+
debugger // in rebuild
|
1811
|
+
}
|
1812
|
+
const reverseIt = true
|
1813
|
+
const interleaved = true
|
1730
1814
|
this.configs.forEach((km) => {
|
1731
1815
|
const namespace = km.namespace
|
1732
1816
|
this.config.objects.namespaced[km._uuid] = {}
|
@@ -1755,10 +1839,16 @@ class Config {
|
|
1755
1839
|
config.wasInitialized = false
|
1756
1840
|
// TODO change name of config: to baseConfig:
|
1757
1841
|
const kmFn = (name) => this.getConfig(name)
|
1758
|
-
const
|
1842
|
+
// const hierarchy = new Digraph((config.config || {}).hierarchy)
|
1843
|
+
const args = { isModule, addWord: aw, km: kmFn, hierarchy: this.hierarchy, config, baseConfig: this, currentConfig: config, uuid: config._uuid, objects: namespacedObjects, namespace, api: config.api }
|
1759
1844
|
config.initializerFn(args)
|
1760
1845
|
if (config.initAfterApi) {
|
1761
|
-
|
1846
|
+
// reverse the list
|
1847
|
+
initAfterApis.unshift({ config, args })
|
1848
|
+
} else {
|
1849
|
+
if (interleaved) {
|
1850
|
+
initAfterApis.unshift(null)
|
1851
|
+
}
|
1762
1852
|
}
|
1763
1853
|
// greg
|
1764
1854
|
if (config._api) {
|
@@ -1766,27 +1856,112 @@ class Config {
|
|
1766
1856
|
// reverse the list
|
1767
1857
|
inits.unshift( () => config._api.initialize({ config: this, km: kmFn, api: config._api }) )
|
1768
1858
|
// config._api.initialize({ config, api: config._api })
|
1859
|
+
} else {
|
1860
|
+
if (interleaved) {
|
1861
|
+
inits.unshift(null)
|
1862
|
+
}
|
1769
1863
|
}
|
1770
1864
|
config._api.objects = namespacedObjects
|
1771
1865
|
config._api.config = () => this
|
1772
1866
|
config._api.uuid = config._uuid
|
1867
|
+
} else {
|
1868
|
+
if (interleaved) {
|
1869
|
+
inits.unshift(null)
|
1870
|
+
}
|
1773
1871
|
}
|
1774
1872
|
config.setUUIDs()
|
1775
1873
|
config.applyNamespace(config.config, namespace, config.uuid)
|
1776
1874
|
if (!isSelf) {
|
1777
|
-
|
1875
|
+
if (!reverseIt) {
|
1876
|
+
addInternals.push(config)
|
1877
|
+
} else {
|
1878
|
+
addInternals.unshift(config)
|
1879
|
+
}
|
1880
|
+
// this.addInternal(config, true, false, false, true)
|
1881
|
+
} else {
|
1882
|
+
if (interleaved) {
|
1883
|
+
addInternals.unshift(null)
|
1884
|
+
}
|
1778
1885
|
}
|
1779
1886
|
km.valid()
|
1780
1887
|
})
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1888
|
+
|
1889
|
+
if (addInternals.length !== inits.length || addInternals.length !== initAfterApis.length) {
|
1890
|
+
debugger // bug
|
1784
1891
|
}
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1892
|
+
|
1893
|
+
const generators = this.config.generators
|
1894
|
+
const semantics = this.config.semantics
|
1895
|
+
if (reverseIt) {
|
1896
|
+
this.config.generators = []
|
1897
|
+
this.config.semantics = []
|
1788
1898
|
}
|
1789
|
-
|
1899
|
+
|
1900
|
+
if (!interleaved) {
|
1901
|
+
for (const config of addInternals) {
|
1902
|
+
if (!reverseIt) {
|
1903
|
+
this.addInternal(config, true, false, false, true)
|
1904
|
+
} else {
|
1905
|
+
this.addInternalR(config, true, false, false, true)
|
1906
|
+
}
|
1907
|
+
}
|
1908
|
+
// console.log('inits from config', inits)
|
1909
|
+
for (const init of inits) {
|
1910
|
+
init()
|
1911
|
+
}
|
1912
|
+
for (let init of initAfterApis) {
|
1913
|
+
// init.args.isAfterApi = true
|
1914
|
+
init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
|
1915
|
+
}
|
1916
|
+
this.instances.forEach((instance) => client.processInstance(this, instance))
|
1917
|
+
} else {
|
1918
|
+
const base = {
|
1919
|
+
operators: this.config.operators,
|
1920
|
+
bridges: this.config.bridges,
|
1921
|
+
hierarchy: this.config.hierarchy,
|
1922
|
+
priorities: this.config.priorities,
|
1923
|
+
associations: this.config.associations,
|
1924
|
+
words: this.config.words
|
1925
|
+
}
|
1926
|
+
|
1927
|
+
this.config.operators = []
|
1928
|
+
this.config.bridges = []
|
1929
|
+
this.config.hierarchy = []
|
1930
|
+
this.config.priorities = []
|
1931
|
+
this.config.associations = { positive: [], negative: [] }
|
1932
|
+
this.config.words = {}
|
1933
|
+
|
1934
|
+
for (let i = 0; i < addInternals.length; ++i) {
|
1935
|
+
let name;
|
1936
|
+
if (addInternals[i]) {
|
1937
|
+
this.addInternalR(addInternals[i], true, false, false, true)
|
1938
|
+
name = addInternals[i].name
|
1939
|
+
} else{
|
1940
|
+
this.addInternalR(base, true, false, false, true)
|
1941
|
+
name = this.name
|
1942
|
+
}
|
1943
|
+
// console.log('name -------------', name)
|
1944
|
+
if (inits[i]) {
|
1945
|
+
inits[i]()
|
1946
|
+
}
|
1947
|
+
if (initAfterApis[i]) {
|
1948
|
+
const init = initAfterApis[i]
|
1949
|
+
init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
|
1950
|
+
}
|
1951
|
+
const instance = this.instances.find((instance) => instance.name == name)
|
1952
|
+
if (instance) {
|
1953
|
+
client.processInstance(this, instance)
|
1954
|
+
}
|
1955
|
+
this.hierarchy.edges = this.config.hierarchy
|
1956
|
+
}
|
1957
|
+
// this.instances.forEach((instance) => client.processInstance(this, instance))
|
1958
|
+
}
|
1959
|
+
|
1960
|
+
if (reverseIt) {
|
1961
|
+
this.config.generators = generators.concat(this.config.generators)
|
1962
|
+
this.config.semantics = semantics.concat(this.config.semantics)
|
1963
|
+
}
|
1964
|
+
this.hierarchy.edges = this.config.hierarchy
|
1790
1965
|
this.valid()
|
1791
1966
|
this.checkBridges()
|
1792
1967
|
}
|
@@ -1952,8 +2127,7 @@ class Config {
|
|
1952
2127
|
}
|
1953
2128
|
|
1954
2129
|
if (config.hierarchy) {
|
1955
|
-
|
1956
|
-
hierarchy = hierarchy.map((h) => {
|
2130
|
+
helpers.mapInPlace(config.hierarchy, (h) => {
|
1957
2131
|
if (Array.isArray(h)) {
|
1958
2132
|
return h.map((id) => toNS(id))
|
1959
2133
|
} else {
|
@@ -1962,7 +2136,6 @@ class Config {
|
|
1962
2136
|
return Object.assign({}, h, { child: toNS(h.child), parent: toNS(h.parent) })
|
1963
2137
|
}
|
1964
2138
|
})
|
1965
|
-
config.hierarchy = hierarchy
|
1966
2139
|
}
|
1967
2140
|
|
1968
2141
|
if (config.priorities) {
|
@@ -2155,6 +2328,13 @@ class Config {
|
|
2155
2328
|
this.configs.forEach((km) => {
|
2156
2329
|
this.instances = (km._config.instances || this.initInstances.slice()).concat(this.instances)
|
2157
2330
|
})
|
2331
|
+
let noDups = []
|
2332
|
+
for (let instance of this.instances) {
|
2333
|
+
if (!noDups.find( (existing) => existing.name == instance.name )) {
|
2334
|
+
noDups.push(instance)
|
2335
|
+
}
|
2336
|
+
}
|
2337
|
+
this.instances = noDups
|
2158
2338
|
|
2159
2339
|
this.rebuild()
|
2160
2340
|
this.valid()
|
@@ -2272,6 +2452,128 @@ class Config {
|
|
2272
2452
|
}
|
2273
2453
|
return this
|
2274
2454
|
}
|
2455
|
+
|
2456
|
+
// assumes this is called in reverse order
|
2457
|
+
addInternalR (more, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false) {
|
2458
|
+
if (more instanceof Config) {
|
2459
|
+
more.initialize({ force: false })
|
2460
|
+
if (useOldVersion) {
|
2461
|
+
more = more.config
|
2462
|
+
} else {
|
2463
|
+
// more = more.initConfig
|
2464
|
+
more = _.cloneDeep(more.initConfig)
|
2465
|
+
}
|
2466
|
+
}
|
2467
|
+
for (const key of Object.keys(more)) {
|
2468
|
+
const value = more[key]
|
2469
|
+
// TODO remove name and description on the config bag
|
2470
|
+
const noOverwrite = ['name', 'namespaced']
|
2471
|
+
if (!this.config[key]) {
|
2472
|
+
if (allowNameToBeNull) {
|
2473
|
+
if (noOverwrite.includes(key)) {
|
2474
|
+
continue
|
2475
|
+
}
|
2476
|
+
} else if (this.config[key] && noOverwrite.includes(key)) {
|
2477
|
+
continue
|
2478
|
+
}
|
2479
|
+
this.config[key] = value
|
2480
|
+
continue
|
2481
|
+
}
|
2482
|
+
if (key === 'words') {
|
2483
|
+
const configWords = this.config.words
|
2484
|
+
const moreWords = more.words
|
2485
|
+
for (const word of Object.keys(moreWords)) {
|
2486
|
+
if (!configWords[word]) {
|
2487
|
+
configWords[word] = []
|
2488
|
+
}
|
2489
|
+
// configWords[word] = configWords[word].concat(moreWords[word])
|
2490
|
+
configWords[word] = moreWords[word].concat(configWords[word])
|
2491
|
+
}
|
2492
|
+
} else if (key === 'name') {
|
2493
|
+
/*
|
2494
|
+
if (this.config[key] === '') {
|
2495
|
+
this.config[key] = more[key]
|
2496
|
+
}
|
2497
|
+
*/
|
2498
|
+
} else if (key === 'namespaces') {
|
2499
|
+
if (includeNamespaces) {
|
2500
|
+
Object.assign(this.config[key], more[key])
|
2501
|
+
}
|
2502
|
+
} else if (key === 'debug') {
|
2503
|
+
this.config[key] = this.config[key] || more[key]
|
2504
|
+
} else if (key === 'description') {
|
2505
|
+
// this.config[key] += ' ' + more[key].trim()
|
2506
|
+
this.config[key] = more[key].trim() + ' ' + this.config[key]
|
2507
|
+
} else if (key === 'objects') {
|
2508
|
+
if (!skipObjects) {
|
2509
|
+
// namespaced is special
|
2510
|
+
const namespaced = this.config.objects.namespaced
|
2511
|
+
Object.assign(this.config[key], more[key])
|
2512
|
+
this.config.objects.namespaced = namespaced
|
2513
|
+
}
|
2514
|
+
} else if (key === 'associations') {
|
2515
|
+
const configAssociations = this.config.associations
|
2516
|
+
const moreAssociations = more.associations
|
2517
|
+
if (moreAssociations.positive) {
|
2518
|
+
// configAssociations.positive = configAssociations.positive.concat(moreAssociations.positive)
|
2519
|
+
configAssociations.positive = moreAssociations.positive.concat(configAssociations.positive)
|
2520
|
+
}
|
2521
|
+
if (moreAssociations.negative) {
|
2522
|
+
// configAssociations.negative = configAssociations.negative.concat(moreAssociations.negative)
|
2523
|
+
configAssociations.negative = moreAssociations.negative.concat(configAssociations.negative)
|
2524
|
+
}
|
2525
|
+
} else if (Array.isArray(value)) {
|
2526
|
+
// handle allowDups
|
2527
|
+
if (key == 'operators') {
|
2528
|
+
// TODO what about other props
|
2529
|
+
const isDup = (op1, op2) => op1.pattern == op2.pattern
|
2530
|
+
for (const newOne of more[key]) {
|
2531
|
+
for (let iOldOne = 0; iOldOne < this.config[key].length; ++iOldOne) {
|
2532
|
+
const oldOne = this.config[key][iOldOne];
|
2533
|
+
if (isDup(newOne, oldOne)) {
|
2534
|
+
if (oldOne.allowDups) {
|
2535
|
+
// the old one takes precedence to match what would happen during the original load
|
2536
|
+
debugger
|
2537
|
+
this.config[key].splice(iOldOne, 1)
|
2538
|
+
break;
|
2539
|
+
}
|
2540
|
+
}
|
2541
|
+
}
|
2542
|
+
}
|
2543
|
+
}
|
2544
|
+
if (key == 'bridges') {
|
2545
|
+
// TODO what about other props
|
2546
|
+
const idDup = (b1, b2) => b1.id == b2.id && b1.level == b2.level && b1.bridge == b2.bridge
|
2547
|
+
for (const newOne of more[key]) {
|
2548
|
+
for (let iOldOne = 0; iOldOne < this.config[key].length; ++iOldOne) {
|
2549
|
+
const oldOne = this.config[key][iOldOne];
|
2550
|
+
if (newOne.id == oldOne.id) {
|
2551
|
+
if (oldOne.allowDups) {
|
2552
|
+
// the old one takes precedence to match what would happen during the original load
|
2553
|
+
this.config[key].splice(iOldOne, 1)
|
2554
|
+
break;
|
2555
|
+
}
|
2556
|
+
}
|
2557
|
+
}
|
2558
|
+
}
|
2559
|
+
}
|
2560
|
+
// console.log('key', key, 'XXX')
|
2561
|
+
// console.log('more', JSON.stringify(more, null, 2))
|
2562
|
+
// this.config[key] = this.config[key].concat(more[key])
|
2563
|
+
if (key == '2enerators') {
|
2564
|
+
debugger
|
2565
|
+
}
|
2566
|
+
// this.config[key] = this.config[key].concat(more[key])
|
2567
|
+
this.config[key] = more[key].concat(this.config[key])
|
2568
|
+
} else {
|
2569
|
+
if (!(key in this.config)) {
|
2570
|
+
throw `Unexpected property in config ${key}`
|
2571
|
+
}
|
2572
|
+
this.config[key] = more[key]
|
2573
|
+
}
|
2574
|
+
}
|
2575
|
+
return this
|
2576
|
+
}
|
2275
2577
|
}
|
2276
2578
|
|
2277
2579
|
module.exports = {
|
package/src/digraph.js
CHANGED
@@ -9,21 +9,42 @@ const toA = (edge) => {
|
|
9
9
|
class Digraph {
|
10
10
|
// edges maybe either [child, parent] or { child, parent }
|
11
11
|
constructor (edges = []) {
|
12
|
-
this.
|
12
|
+
// dont make a copy of edges. this is shared and that breaks stuff. TODO fix this
|
13
|
+
this._edges = edges
|
13
14
|
}
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
addEdges(edges) {
|
17
|
+
for (let edge of edges) {
|
18
|
+
this.addEdge(edge)
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
addEdge(edge) {
|
23
|
+
edge = toA(edge)
|
24
|
+
this._edges.push(edge)
|
25
|
+
}
|
26
|
+
|
27
|
+
get edges() {
|
28
|
+
return this._edges
|
29
|
+
}
|
30
|
+
|
31
|
+
set edges(edges) {
|
32
|
+
this._edges = edges
|
33
|
+
}
|
34
|
+
|
35
|
+
/*
|
36
|
+
set edges(edges) {
|
37
|
+
this._edges = edges.map( toA )
|
18
38
|
}
|
19
39
|
*/
|
40
|
+
|
20
41
|
acdcs (s, from, to) {
|
21
42
|
const todo = [s]
|
22
43
|
const seen = new Set([s])
|
23
44
|
const acdcs = new Set([])
|
24
45
|
while (todo.length > 0) {
|
25
46
|
const n = todo.pop()
|
26
|
-
this.
|
47
|
+
this._edges.forEach((e) => {
|
27
48
|
e = toA(e)
|
28
49
|
if (e[from] === n) {
|
29
50
|
acdcs.add(e[to])
|
@@ -84,12 +105,12 @@ class Digraph {
|
|
84
105
|
}
|
85
106
|
|
86
107
|
add (child, parent) {
|
87
|
-
this.
|
108
|
+
this._edges.push([child, parent])
|
88
109
|
}
|
89
110
|
|
90
111
|
addList (l) {
|
91
112
|
for (let i = 1; i < l.length; ++i) {
|
92
|
-
this.
|
113
|
+
this._edges.push([l[i - 1], l[i]])
|
93
114
|
}
|
94
115
|
}
|
95
116
|
|
package/src/generators.js
CHANGED
@@ -195,10 +195,12 @@ class Generators {
|
|
195
195
|
} catch( e ) {
|
196
196
|
// the next if handle this
|
197
197
|
generated = null
|
198
|
+
e.retryCall = () => generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
|
199
|
+
const help = 'The error has a retryCall property that will recall the function that failed.'
|
198
200
|
if (e.stack && e.message) {
|
199
|
-
errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}`
|
201
|
+
errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
|
200
202
|
} else if (e.error) {
|
201
|
-
errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.error.join()}. Generator is ${generator.toString()}`
|
203
|
+
errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
|
202
204
|
} else {
|
203
205
|
errorMessage = e.toString()
|
204
206
|
}
|
package/src/helpers.js
CHANGED
@@ -217,4 +217,42 @@ const sortJson = (json) => {
|
|
217
217
|
return json
|
218
218
|
}
|
219
219
|
|
220
|
-
|
220
|
+
const validProps = (valids, object, type) => {
|
221
|
+
for (let prop of Object.keys(object)) {
|
222
|
+
let okay = false
|
223
|
+
for (valid of valids) {
|
224
|
+
if (prop.match(valid)) {
|
225
|
+
okay = true
|
226
|
+
break
|
227
|
+
}
|
228
|
+
}
|
229
|
+
if (!okay) {
|
230
|
+
throw `Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
const mapInPlace = (list, fn) => {
|
236
|
+
for (let i = 0; i < list.length; ++i) {
|
237
|
+
list[i] =fn(list[i])
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
module.exports = {
|
242
|
+
mapInPlace,
|
243
|
+
validProps,
|
244
|
+
args,
|
245
|
+
safeEquals,
|
246
|
+
appendNoDups,
|
247
|
+
hashIndexesGet,
|
248
|
+
hashIndexesSet,
|
249
|
+
translationMapping,
|
250
|
+
normalizeGenerator,
|
251
|
+
normalizeSemantic,
|
252
|
+
isArray,
|
253
|
+
isObject,
|
254
|
+
isCompound,
|
255
|
+
InitCalls,
|
256
|
+
hashCode,
|
257
|
+
sortJson
|
258
|
+
}
|
package/src/semantics.js
CHANGED
@@ -189,10 +189,12 @@ class Semantics {
|
|
189
189
|
} catch( e ) {
|
190
190
|
contextPrime = null
|
191
191
|
let errorMessage
|
192
|
+
e.retryCall = () => semantic.apply(args, context, s, log, options)
|
193
|
+
const help = 'The error has a retryCall property that will recall the function that failed.'
|
192
194
|
if (e.stack && e.message) {
|
193
|
-
errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.toString()} stack is ${e.stack}. Semantic is ${semantic.toString()}`
|
195
|
+
errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.toString()} stack is ${e.stack}. Semantic is ${semantic.toString()}. ${help}`
|
194
196
|
} else if (e.error) {
|
195
|
-
errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.error.join()}. Semantic is ${semantic.toString()}`
|
197
|
+
errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.error.join()}. Semantic is ${semantic.toString()}. ${help}`
|
196
198
|
} else {
|
197
199
|
errorMessage = e.toString();
|
198
200
|
}
|