theprogrammablemind_4wp 7.5.0-beta.9 → 7.5.1

Sign up to get free protection for your applications and to get access to all the features.
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) => hierarchy.isA(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
- const objects = getObjects(config.config.objects)(config.uuid)
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
@@ -783,7 +797,7 @@ const runTests = async (config, testFile, juicyBits) => {
783
797
  const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
784
798
  config.rebuild()
785
799
  const objects = getObjects(config.config.objects)(config.uuid)
786
- config.resetMotivations()
800
+ //config.resetMotivations()
787
801
  config.beforeQuery({ query: test, isModule: false, objects })
788
802
  console.log(test)
789
803
  const result = await _process(config, test, { isTest: true })
@@ -858,6 +872,7 @@ const submitBugToAPI = async (subscription_id, subscription_password, config) =>
858
872
  })
859
873
  }
860
874
 
875
+ /*
861
876
  const submitBug = async (subscription_id, subscription_password, config, utterance, retries = 2) => {
862
877
  // TODO remove these from the config
863
878
  const properties = ['expected_contexts', 'expected_generated']
@@ -894,6 +909,7 @@ const submitBug = async (subscription_id, subscription_password, config, utteran
894
909
  throw error
895
910
  })
896
911
  }
912
+ */
897
913
 
898
914
  const defaultErrorHandler = async (error) => {
899
915
  if (error.logs) {
@@ -1048,7 +1064,6 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1048
1064
  if (typeof queryOrExtraConfig === 'string') {
1049
1065
  query = { query }
1050
1066
  }
1051
- console.log('query', query.query)
1052
1067
  config.config.skipSemantics = skipSemantics
1053
1068
  const transitoryMode = global.transitoryMode
1054
1069
  if (property == 'fragments') {
@@ -1072,6 +1087,11 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1072
1087
  // TODO pass in the error handler like the other ones
1073
1088
  defaultInnerProcess(config, defaultErrorHandler, results)
1074
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
+ }
1075
1095
  global.transitoryMode = transitoryMode
1076
1096
  config.config.skipSemantics = null
1077
1097
  results.query = query.query
@@ -1252,7 +1272,7 @@ const knowledgeModule = async ({
1252
1272
  description: 'Entodicton knowledge module'
1253
1273
  })
1254
1274
 
1255
- parser.add_argument('-tfn', '--testFileName', { help: 'Override the test file for the module when the tests are being run' })
1275
+ parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
1256
1276
  parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1257
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' })
1258
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' })
@@ -1263,11 +1283,12 @@ const knowledgeModule = async ({
1263
1283
  parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
1264
1284
  parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
1265
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' })
1266
1287
  parser.add_argument('-r', '--retrain', { action: 'store_true', help: 'Get the server to retrain the neural nets' })
1267
1288
  parser.add_argument('-q', '--query', { help: 'Run the specified query' })
1268
1289
  parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
1269
1290
  parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
1270
- parser.add_argument('-td', '--testDelete', { help: 'Delete the specified query from the tests file.' })
1291
+ parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
1271
1292
  parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
1272
1293
  parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
1273
1294
  parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
@@ -1306,11 +1327,11 @@ const knowledgeModule = async ({
1306
1327
  return
1307
1328
  }
1308
1329
 
1309
- if (args.testDelete) {
1330
+ if (args.deleteTest) {
1310
1331
  let tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
1311
- tests = tests.filter( (test) => test.query !== args.testDelete );
1332
+ tests = tests.filter( (test) => test.query !== args.deleteTest );
1312
1333
  writeTestFile(testConfig.name, tests)
1313
- console.log(`Remove the test for "${args.testDelete}"`)
1334
+ console.log(`Remove the test for "${args.deleteTest}"`)
1314
1335
  return
1315
1336
  }
1316
1337
 
@@ -1466,7 +1487,15 @@ const knowledgeModule = async ({
1466
1487
  }
1467
1488
  return
1468
1489
  }
1469
- runTests(config, args.testFileName ? `${args.testFileName}.test.json` : test, { debug: args.debug, testConfig: testConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
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) => {
1470
1499
  if (results.length > 0 && args.vimdiff) {
1471
1500
  for (const result of results) {
1472
1501
  vimdiff(result.expected, result.actual)
@@ -1515,19 +1544,25 @@ const knowledgeModule = async ({
1515
1544
  if (!headerShown) {
1516
1545
  console.log(' Failure')
1517
1546
  }
1518
- console.log(' expected checked', result.expected.checked)
1519
- console.log(' actual checked ', result.actual.checked)
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()
1520
1555
  newError = true
1521
1556
  headerShown = true
1522
1557
  }
1523
1558
  }
1524
1559
  }
1525
1560
  if (!headerShown) {
1526
- if (!(testConfig.check && testConfig.check.length > 0)) {
1561
+ if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
1527
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.')
1528
1563
  }
1529
1564
  }
1530
- if (!(testConfig.check && testConfig.check.length > 0)) {
1565
+ if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
1531
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.')
1532
1567
  // console.log(JSON.stringify(contexts))
1533
1568
  console.log('**************************** ERRORS ************************')
@@ -1582,13 +1617,14 @@ const knowledgeModule = async ({
1582
1617
  }
1583
1618
  config.beforeQuery({ query: args.query, isModule: false, objects })
1584
1619
  try {
1585
- 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 }))
1586
1621
  } catch( error ) {
1587
1622
  console.log('Error', error);
1588
1623
  }
1589
1624
  }
1590
1625
  } else {
1591
1626
  config.addAssociationsFromTests(config.tests);
1627
+ config.setTestConfig(testConfig)
1592
1628
  //for (let query in config.tests) {
1593
1629
  // config.addAssociations(config.tests[query].associations || []);
1594
1630
  //}
@@ -1638,7 +1674,7 @@ module.exports = {
1638
1674
  process: _process,
1639
1675
  where,
1640
1676
  w,
1641
- submitBug,
1677
+ // submitBug,
1642
1678
  ensureTestFile,
1643
1679
  build,
1644
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
@@ -61,6 +61,6 @@
61
61
  "json-stable-stringify": "^1.0.1",
62
62
  "node-fetch": "^2.6.1"
63
63
  },
64
- "version": "7.5.0-beta.9",
64
+ "version": "7.5.1",
65
65
  "license": "ISC"
66
66
  }
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
@@ -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
- this.instances.push(instance)
536
- client.processInstance(this, instance)
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
 
@@ -1090,7 +1115,7 @@ class Config {
1090
1115
  config = _.cloneDeep(config)
1091
1116
  this.config = config
1092
1117
  for (let bridge of this.config.bridges) {
1093
- const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'implicit', 'inverted', 'isA',
1118
+ const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'implicit', 'inverted', 'isA', 'children', 'parents',
1094
1119
  'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy' ]
1095
1120
  helpers.validProps(valid, bridge, 'bridge')
1096
1121
  /*
@@ -1101,6 +1126,16 @@ class Config {
1101
1126
  })
1102
1127
  }
1103
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
+ }
1104
1139
  if (bridge.isA) {
1105
1140
  for (let parent of bridge.isA) {
1106
1141
  this.addHierarchy(bridge.id, parent)
@@ -1379,12 +1414,13 @@ class Config {
1379
1414
  cp.name = this.name
1380
1415
  cp.description = this.description
1381
1416
  cp.tests = this.tests
1382
- cp.motivations = this.motivations
1417
+ cp.motivations = [...this.motivations]
1383
1418
  cp.isModule = this.isModule
1384
1419
  cp.loadedForTesting = this.loadedForTesting
1385
1420
  cp.initInstances = this.initInstances.slice()
1386
1421
  cp.instances = this.instances.slice()
1387
1422
  cp.configCounter = this.configCounter
1423
+ cp.testConfig = this.testConfig
1388
1424
 
1389
1425
  cp.initConfig = _.cloneDeep(this.initConfig)
1390
1426
  cp.defaultConfig()
@@ -1511,7 +1547,8 @@ class Config {
1511
1547
  }
1512
1548
 
1513
1549
  initializeFromConfigs () {
1514
- this.configs.forEach(({ config, namespace, uuid }) => {
1550
+ // [...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
1551
+ [...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
1515
1552
  /*
1516
1553
  let objects = this.get('objects')
1517
1554
  if (namespace) {
@@ -1747,6 +1784,7 @@ class Config {
1747
1784
  }
1748
1785
  this.config.objects.namespaced = {}
1749
1786
  this.resetWasInitialized()
1787
+ this.resetMotivations()
1750
1788
 
1751
1789
  // reorder configs base on load ordering
1752
1790
  {
@@ -1762,8 +1800,17 @@ class Config {
1762
1800
  this.configs = [...oconfigs]
1763
1801
  }
1764
1802
 
1803
+ const addInternals = []
1765
1804
  const inits = []
1766
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
1767
1814
  this.configs.forEach((km) => {
1768
1815
  const namespace = km.namespace
1769
1816
  this.config.objects.namespaced[km._uuid] = {}
@@ -1796,7 +1843,12 @@ class Config {
1796
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 }
1797
1844
  config.initializerFn(args)
1798
1845
  if (config.initAfterApi) {
1799
- initAfterApis.push({ config, args })
1846
+ // reverse the list
1847
+ initAfterApis.unshift({ config, args })
1848
+ } else {
1849
+ if (interleaved) {
1850
+ initAfterApis.unshift(null)
1851
+ }
1800
1852
  }
1801
1853
  // greg
1802
1854
  if (config._api) {
@@ -1804,27 +1856,112 @@ class Config {
1804
1856
  // reverse the list
1805
1857
  inits.unshift( () => config._api.initialize({ config: this, km: kmFn, api: config._api }) )
1806
1858
  // config._api.initialize({ config, api: config._api })
1859
+ } else {
1860
+ if (interleaved) {
1861
+ inits.unshift(null)
1862
+ }
1807
1863
  }
1808
1864
  config._api.objects = namespacedObjects
1809
1865
  config._api.config = () => this
1810
1866
  config._api.uuid = config._uuid
1867
+ } else {
1868
+ if (interleaved) {
1869
+ inits.unshift(null)
1870
+ }
1811
1871
  }
1812
1872
  config.setUUIDs()
1813
1873
  config.applyNamespace(config.config, namespace, config.uuid)
1814
1874
  if (!isSelf) {
1815
- this.addInternal(config, true, false, false, true)
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
+ }
1816
1885
  }
1817
1886
  km.valid()
1818
1887
  })
1819
- // console.log('inits from config', inits)
1820
- for (const init of inits) {
1821
- init()
1888
+
1889
+ if (addInternals.length !== inits.length || addInternals.length !== initAfterApis.length) {
1890
+ debugger // bug
1822
1891
  }
1823
- for (let init of initAfterApis) {
1824
- // init.args.isAfterApi = true
1825
- init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
1892
+
1893
+ const generators = this.config.generators
1894
+ const semantics = this.config.semantics
1895
+ if (reverseIt) {
1896
+ this.config.generators = []
1897
+ this.config.semantics = []
1826
1898
  }
1827
- this.instances.forEach((instance) => client.processInstance(this, instance))
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
1828
1965
  this.valid()
1829
1966
  this.checkBridges()
1830
1967
  }
@@ -2191,6 +2328,13 @@ class Config {
2191
2328
  this.configs.forEach((km) => {
2192
2329
  this.instances = (km._config.instances || this.initInstances.slice()).concat(this.instances)
2193
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
2194
2338
 
2195
2339
  this.rebuild()
2196
2340
  this.valid()
@@ -2308,6 +2452,128 @@ class Config {
2308
2452
  }
2309
2453
  return this
2310
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
+ }
2311
2577
  }
2312
2578
 
2313
2579
  module.exports = {
package/src/digraph.js CHANGED
@@ -28,6 +28,10 @@ class Digraph {
28
28
  return this._edges
29
29
  }
30
30
 
31
+ set edges(edges) {
32
+ this._edges = edges
33
+ }
34
+
31
35
  /*
32
36
  set edges(edges) {
33
37
  this._edges = edges.map( toA )
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
@@ -227,7 +227,7 @@ const validProps = (valids, object, type) => {
227
227
  }
228
228
  }
229
229
  if (!okay) {
230
- throw `Unknown property "${prop}" in the ${type}. Valid properties are ${valid}. The ${type} is ${JSON.stringify(object)}`
230
+ throw `Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`
231
231
  }
232
232
  }
233
233
  }
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
  }