theprogrammablemind_4wp 7.5.0 → 7.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|