theprogrammablemind 7.5.4 → 7.5.5

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 CHANGED
@@ -8,7 +8,7 @@ const _ = require('lodash')
8
8
  const stringify = require('json-stable-stringify')
9
9
  const Lines = require('./lines')
10
10
  const flattens = require('./src/flatten')
11
- const { appendNoDups, InitCalls } = require('./src/helpers')
11
+ const { appendNoDups, InitCalls, updateQueries } = require('./src/helpers')
12
12
  const runtime = require('./runtime')
13
13
  const sortJson = runtime.sortJson
14
14
 
@@ -478,7 +478,7 @@ const doWithRetries = async (n, url, queryParams, data) => {
478
478
  }
479
479
  }
480
480
 
481
- const setupProcessB = ({ config, allowDelta=false } = {}) => {
481
+ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
482
482
  const key = config._key
483
483
 
484
484
  const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
@@ -515,10 +515,13 @@ const processInstance = (config, instance) => {
515
515
  const transitoryMode = global.transitoryMode
516
516
  global.transitoryMode = false
517
517
  const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
518
- for (const results of (instance.resultss || [])) {
518
+ // for (const results of (instance.resultss || [])) {
519
+ for (const i in (instance.resultss || [])) {
520
+ const results = instance.resultss[i]
519
521
  if (results.extraConfig) {
520
522
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
521
- config.addInternal(results)
523
+ // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
524
+ config.addInternal(instance.template.queries[i], { handleCalculatedProps: true } )
522
525
  } else {
523
526
  processContextsB({ config, hierarchy, json: results/*, generators, semantics */ })
524
527
  }
@@ -526,7 +529,7 @@ const processInstance = (config, instance) => {
526
529
  global.transitoryMode = transitoryMode
527
530
  }
528
531
 
529
- const _process = async (config, query, { commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
532
+ const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
530
533
  if (credentials) {
531
534
  config.server(credentials.server, credentials.key)
532
535
  }
@@ -546,7 +549,7 @@ const _process = async (config, query, { commandLineArgs, credentials, writeTest
546
549
  throw error
547
550
  }
548
551
 
549
- let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, allowDelta: true })
552
+ let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, initializer, allowDelta: true })
550
553
  if (commandLineArgs && commandLineArgs.checkForLoop) {
551
554
  data.checkForLoop = true
552
555
  }
@@ -1057,7 +1060,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1057
1060
  finish()
1058
1061
  return
1059
1062
  }
1060
- const { property, hierarchy, query: queryOrExtraConfig, skipSemantics } = queries.shift()
1063
+ const { property, hierarchy, query: queryOrExtraConfig, initializer, skipSemantics } = queries.shift()
1061
1064
  // queries are strings or { query: "blah", development: true/false }
1062
1065
  if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
1063
1066
  let query = queryOrExtraConfig;
@@ -1082,7 +1085,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1082
1085
  }
1083
1086
 
1084
1087
  try {
1085
- const results = await _process(config, query.query, {})
1088
+ const results = await _process(config, query.query, {initializer})
1086
1089
  if (config.config.debug) {
1087
1090
  // TODO pass in the error handler like the other ones
1088
1091
  defaultInnerProcess(config, defaultErrorHandler, results)
@@ -1143,7 +1146,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1143
1146
  return template
1144
1147
  };
1145
1148
  stabilizeOutput(accumulators)
1146
- runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries }, accumulators), 0, 2))
1149
+ runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries.map(updateQueries) }, accumulators), 0, 2))
1147
1150
 
1148
1151
  // km tests file
1149
1152
  const testsName = `./${target}.test.json`
@@ -1160,7 +1163,9 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1160
1163
  return queryStringOrProperties
1161
1164
  }
1162
1165
  }
1163
- let todo = (template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } })
1166
+ let todo = []
1167
+ todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false } }))
1168
+ todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } }))
1164
1169
  todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
1165
1170
  todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
1166
1171
  await looper(Object.assign([], todo))
@@ -1265,7 +1270,6 @@ const knowledgeModule = async ({
1265
1270
  config.load(template.template, template.instance)
1266
1271
  }
1267
1272
  }
1268
-
1269
1273
  if (isProcess) {
1270
1274
  // setup();
1271
1275
  const parser = new runtime.ArgumentParser({
@@ -1295,10 +1299,12 @@ const knowledgeModule = async ({
1295
1299
  parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server. for example --print wb' })
1296
1300
  parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
1297
1301
  parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
1302
+ parser.add_argument('-dic', '--debugIncludeConvolutions', { action: 'store_true', help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoying verbose. Default is false' })
1298
1303
  parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
1299
1304
  parser.add_argument('-da', '--debugAssociation', { help: 'When running with the --debugAssociation flag the debugging will break when the specified association is added to the config' })
1300
1305
  parser.add_argument('-dh', '--debugHierarchy', { help: 'When running with the --debugHierarchy flag the debugging will break when the specified child-parent pair is added to the config for the main config. Set DEBUG_HIERARCHY to debug any config loaded. For example DEBUG_HIERARCHY=\'["cat", "mammel"]\'' })
1301
1306
  parser.add_argument('-db', '--debugBridge', { help: 'When running with the --debugBridge flag the debugging will break when the specified bridge is added to the config for the main config. Set DEBUG_BRIDGE to debug any config loaded. For example DEBUG_BRIDGE=\'id/level\'' })
1307
+ parser.add_argument('-do', '--debugOperator', { help: 'When running with the --debugOperator flag the debugging will break when the specified operator is added to the config for the main config. Set DEBUG_OPERATOR to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\'' })
1302
1308
 
1303
1309
  const args = parser.parse_args()
1304
1310
  args.count = args.count || 1
@@ -1316,6 +1322,10 @@ const knowledgeModule = async ({
1316
1322
  console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
1317
1323
  }
1318
1324
  }
1325
+ if (args.debugOperator) {
1326
+ // id/level
1327
+ global.entodictonDebugOperator = args.debugOperator
1328
+ }
1319
1329
 
1320
1330
  if (args.clean) {
1321
1331
  const tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
@@ -1353,6 +1363,7 @@ const knowledgeModule = async ({
1353
1363
  if (args.debug) {
1354
1364
  config.config.debug = true
1355
1365
  }
1366
+ config.config.debugIncludeConvolutions = args.debugIncludeConvolutions
1356
1367
 
1357
1368
  if (template) {
1358
1369
  const needsRebuild = config.needsRebuild(template.template, template.instance, options)
@@ -1450,6 +1461,9 @@ const knowledgeModule = async ({
1450
1461
  for (const semantic of easyToRead) {
1451
1462
  semantic.match = semantic.match.toString()
1452
1463
  semantic.apply = semantic.apply.toString()
1464
+ if (semantic.applyWrapped) {
1465
+ semantic.applyWrapped = semantic.applyWrapped.toString()
1466
+ }
1453
1467
  }
1454
1468
  console.dir(easyToRead)
1455
1469
  }
@@ -1656,7 +1670,14 @@ function where(goUp = 2) {
1656
1670
  const e = new Error();
1657
1671
  const regexForm1 = /\((.*):(\d+):(\d+)\)$/
1658
1672
  const regexForm2 = /at (.*):(\d+):(\d+)$/
1659
- const line = e.stack.split("\n")[goUp];
1673
+ const lines = e.stack.split("\n")
1674
+ let line
1675
+ for (line of lines.slice(1)) {
1676
+ if (!(line.includes("config.js:") || line.includes("client.js:"))) {
1677
+ break;
1678
+ }
1679
+ }
1680
+ // const line = e.stack.split("\n")[goUp];
1660
1681
  const match = regexForm1.exec(line) || regexForm2.exec(line);
1661
1682
  if (match) {
1662
1683
  return `${match[1]}:${match[2]}`
package/package.json CHANGED
@@ -10,12 +10,13 @@
10
10
  "eslint": "^7.31.0"
11
11
  },
12
12
  "scripts": {
13
- "to:debug": "node inspect node_modules/.bin/jest --runInBand -t ONE23",
13
+ "to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
14
14
  "test:debug": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
15
- "tod": "node inspect node_modules/.bin/jest --runInBand -t ONE23",
15
+ "tod": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
16
16
  "lint:fix": "eslint \"**/*.js\" --fix",
17
17
  "lint": "eslint \"**/*.js\"",
18
- "to": "node node_modules/.bin/jest --runInBand -t ONE23",
18
+ "to": "node node_modules/.bin/jest --runInBand -t NEO23",
19
+ "tos": "node node_modules/.bin/jest --runInBand -t NEOS23",
19
20
  "test": "jest --config ./jest.config.json",
20
21
  "test:watch": "npm run test -- --watch"
21
22
  },
@@ -61,6 +62,6 @@
61
62
  "json-stable-stringify": "^1.0.1",
62
63
  "node-fetch": "^2.6.1"
63
64
  },
64
- "version": "7.5.4",
65
+ "version": "7.5.5",
65
66
  "license": "ISC"
66
67
  }
package/src/config.js CHANGED
@@ -5,7 +5,6 @@ const { Generators } = require('./generators')
5
5
  const client = require('../client')
6
6
  const Digraph = require('./digraph')
7
7
  const helpers = require('./helpers')
8
- const deepEqual = require('deep-equal')
9
8
  const runtime = require('../runtime')
10
9
  const _ = require('lodash')
11
10
 
@@ -22,6 +21,118 @@ const indent = (string, indent) => {
22
21
  return string.replace(/^/gm, ' '.repeat(indent));
23
22
  }
24
23
 
24
+ const handleBridgeProps = (config, bridge) => {
25
+ if (!bridge.bridge) {
26
+ bridge.bridge = "{ ...next(operator) }"
27
+ }
28
+ if (!bridge.level) {
29
+ bridge.level = 0
30
+ }
31
+ if (bridge.children) {
32
+ for (let child of bridge.children) {
33
+ config.addHierarchy(child, bridge.id)
34
+ }
35
+ }
36
+ if (bridge.parents) {
37
+ for (let parent of bridge.parents) {
38
+ config.addHierarchy(bridge.id, parent)
39
+ }
40
+ }
41
+ if (bridge.isA) {
42
+ for (let parent of bridge.isA) {
43
+ config.addHierarchy(bridge.id, parent)
44
+ }
45
+ }
46
+ if (bridge.before) {
47
+ for (let after of bridge.before) {
48
+ if (typeof after == 'string') {
49
+ after = [after, 0]
50
+ }
51
+ config.addPriorities([after, [bridge.id, bridge.level]])
52
+ }
53
+ }
54
+ if (bridge.words) {
55
+ for (let def of bridge.words) {
56
+ if (typeof def == 'string') {
57
+ config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
58
+ } else {
59
+ const word = def.word
60
+ def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
61
+ config.addWordInternal(word, def)
62
+ }
63
+ }
64
+ }
65
+ if (bridge.generator) {
66
+ config.config.generators.unshift(bridge.generator)
67
+ }
68
+ if (bridge.generators) {
69
+ const generators = [...bridge.generators]
70
+ generators.reverse()
71
+ for (let generator of generators) {
72
+ config.config.generators.unshift(generator)
73
+ }
74
+ }
75
+ if (bridge.generatorpr) {
76
+ bridge.generatorp = bridge.generatorpr
77
+ bridge.generatorr = bridge.generatorpr
78
+ }
79
+ if (bridge.generatorp) {
80
+ config.config.generators.unshift({
81
+ where: bridge.generatorp.where || bridge.where || client.where(4),
82
+ match: ({context}) => bridge.id == context.marker && context.paraphrase,
83
+ apply: (args) => bridge.generatorp(args),
84
+ applyWrapped: bridge.generatorp,
85
+ property: 'generatorp',
86
+ })
87
+ }
88
+ if (bridge.generatorr) {
89
+ config.config.generators.unshift({
90
+ // TODO merge response and isResponse
91
+ where: bridge.generatorr.where || bridge.where || client.where(3),
92
+ match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
93
+ apply: (args) => bridge.generatorr(args),
94
+ applyWrapped: bridge.generatorr,
95
+ property: 'generatorr',
96
+ })
97
+ }
98
+ if (bridge.evaluator) {
99
+ config.config.semantics.unshift({
100
+ where: bridge.evaluator.where || bridge.where || client.where(3),
101
+ match: ({context}) => bridge.id == context.marker && context.evaluate,
102
+ apply: (args) => bridge.evaluator(args),
103
+ applyWrapped: bridge.evaluator,
104
+ property: 'evaluator',
105
+ })
106
+ }
107
+ if (bridge.semantic) {
108
+ config.config.semantics.unshift({
109
+ where: bridge.semantic.where || bridge.where || client.where(3),
110
+ match: ({context}) => bridge.id == context.marker,
111
+ apply: (args) => bridge.semantic(args),
112
+ applyWrapped: bridge.semantic,
113
+ property: 'semantic',
114
+ })
115
+ }
116
+ }
117
+
118
+ const handleCalculatedProps = (baseConfig, moreConfig) => {
119
+ for (let bridge of moreConfig.bridges) {
120
+ const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
121
+ 'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where' ]
122
+ helpers.validProps(valid, bridge, 'bridge')
123
+ handleBridgeProps(baseConfig, bridge)
124
+ }
125
+ if (moreConfig.operators) {
126
+ moreConfig.operators = moreConfig.operators.map((operator) => {
127
+ if (typeof operator === 'string') {
128
+ return { pattern: operator }
129
+ } else {
130
+ return operator
131
+ }
132
+ })
133
+ }
134
+ }
135
+
25
136
  if (runtime.process.env.DEBUG_HIERARCHY) {
26
137
  global.entodictonDebugHierarchy = JSON.parse(runtime.process.env.DEBUG_HIERARCHY)
27
138
  }
@@ -35,6 +146,11 @@ if (runtime.process.env.DEBUG_BRIDGE) {
35
146
  global.entodictonDebugBridge[1] = int(global.entodictonDebugBridge[1])
36
147
  }
37
148
 
149
+ if (runtime.process.env.DEBUG_OPERATOR) {
150
+ // id/level
151
+ global.entodictonDebugOperator = runtime.process.env.DEBUG_OPERATOR
152
+ }
153
+
38
154
  const hierarchyCanonical = (element) => {
39
155
  if (element.child && element.parent) {
40
156
  return element
@@ -86,6 +202,17 @@ const normalizeConfig = (config) => {
86
202
  config[bag][i].km = config.name
87
203
  }
88
204
  }
205
+
206
+ }
207
+ if (config['bridges']) {
208
+ for (let bridge of config['bridges']) {
209
+ if (!bridge.level) {
210
+ bridge.level = 0
211
+ }
212
+ if (!bridge.bridge) {
213
+ bridge.bridge = "{ ...next(operator) }"
214
+ }
215
+ }
89
216
  }
90
217
  }
91
218
  }
@@ -324,6 +451,37 @@ const multiApiImpl = (initializer) => {
324
451
 
325
452
  class Config {
326
453
 
454
+ inDevelopmentMode (call) {
455
+ config.developmentModeOn += 1
456
+ try {
457
+ call()
458
+ } finally {
459
+ config.developmentModeOn -= 1
460
+ }
461
+ }
462
+
463
+ // return the config with just the elements from the included KM's
464
+ baseConfig() {
465
+ const operators = this.config.operators.filter((operator) => {
466
+ return operator.uuid !== this.uuid
467
+ })
468
+ const bridges = this.config.bridges.filter((bridge) => {
469
+ return bridge.uuid !== this.uuid
470
+ })
471
+ const words = {}
472
+ for (let word in this.config.words) {
473
+ const defs = this.config.words[word].filter( (def) => def.uuid !== this.uuid )
474
+ if (defs.length > 0) {
475
+ words[word] = defs
476
+ }
477
+ }
478
+ return {
479
+ operators,
480
+ bridges,
481
+ words
482
+ }
483
+ }
484
+
327
485
  getCounter (maybeName = '') {
328
486
  const counter = this.configCounter
329
487
  this.configCounter += 1
@@ -525,12 +683,26 @@ class Config {
525
683
  }
526
684
  const instanceFragments = (instance.fragments || []).map((fragment) => fragment.key || fragment.query).map( toCanonical )
527
685
  const templateFragments = (template.fragments || []).concat(this.dynamicFragments).map( toCanonical )
528
- const sameFragments = deepEqual(templateFragments, instanceFragments)
529
- const sameQueries = deepEqual((template.queries || []), (instance.queries || []))
686
+ const sameFragments = helpers.safeEquals(templateFragments, instanceFragments)
687
+ const sameQueries = helpers.safeEquals((template.queries || []).map(helpers.updateQueries), (instance.queries || []))
530
688
  return !(instance && sameQueries && sameFragments)
531
689
  }
532
690
 
691
+ validifyTemplate (template) {
692
+ if (!template.queries && !template.fragments) {
693
+ throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: queries and fragments`)
694
+ }
695
+ for (let query of template.queries || []) {
696
+ if (typeof query == 'string') {
697
+ } else if (query instanceof Config) {
698
+ throw new Error(`For the template for ${this.name}, each element in queries should be either a string or a structure with a config (not a Config object).`)
699
+ }
700
+ }
701
+ }
702
+
533
703
  load (template, instance, options = { rebuild: false } ) {
704
+ this.validifyTemplate(template)
705
+ instance.template = template
534
706
  this.logs.push(`loading template for ${this.name}`)
535
707
  if (instance && instance.associations && !options.rebuild) {
536
708
  this.addAssociations(instance.associations)
@@ -592,7 +764,7 @@ class Config {
592
764
  }
593
765
  }
594
766
  if (global.entodictonDebugAssociation) {
595
- if (deepEqual(global.entodictonDebugAssociation, association)) {
767
+ if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
596
768
  debugger; // debug association hit
597
769
  }
598
770
  }
@@ -627,7 +799,7 @@ class Config {
627
799
  throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
628
800
  }
629
801
  if (global.entodictonDebugHierarchy) {
630
- if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
802
+ if ((helpers.safeEquals.entodictonDebugHierarchy, [child, parent])) {
631
803
  debugger; // debug hierarchy hit
632
804
  }
633
805
  }
@@ -645,7 +817,7 @@ class Config {
645
817
  }
646
818
 
647
819
  if (global.entodictonDebugHierarchy) {
648
- if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
820
+ if (helpers.safeEquals(global.entodictonDebugHierarchy, [child, parent])) {
649
821
  debugger; // debug hierarchy hit
650
822
  }
651
823
  }
@@ -689,6 +861,7 @@ class Config {
689
861
  if (global.transitoryMode) {
690
862
  def.transitoryMode = true
691
863
  }
864
+ handleBridgeProps(this, def)
692
865
  bridges.push(def)
693
866
  this.checkBridges();
694
867
  this._delta.json.bridges.push({ action: 'add', bridge: def })
@@ -751,6 +924,7 @@ class Config {
751
924
  if (!this.config.operators) {
752
925
  this.config.operators = []
753
926
  }
927
+
754
928
  const operators = this.config.operators
755
929
 
756
930
  let operator;
@@ -760,6 +934,12 @@ class Config {
760
934
  operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
761
935
  }
762
936
 
937
+ if (global.entodictonDebugOperator) {
938
+ if (operator.pattern === global.entodictonDebugOperator) {
939
+ debugger; // debug operator hit
940
+ }
941
+ }
942
+
763
943
  if (operator.allowDups) {
764
944
  if (operators.find( (o) => o.pattern == operator.pattern )) {
765
945
  return;
@@ -1018,7 +1198,8 @@ class Config {
1018
1198
  'debug',
1019
1199
 
1020
1200
  // TODO Fix these from the test app
1021
- 'implicit',
1201
+ 'implicits',
1202
+ 'convolution',
1022
1203
  'expected_generated',
1023
1204
  'expected_results',
1024
1205
  'skipSemantics',
@@ -1114,115 +1295,12 @@ class Config {
1114
1295
  if (config) {
1115
1296
  config = _.cloneDeep(config)
1116
1297
  this.config = config
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')
1121
- /*
1122
- if (bridge.generator) {
1123
- this.config.generators.push({
1124
- match: ({context}) => bridge.id == context.marker,
1125
- apply: (args) => bridge.generator(args),
1126
- })
1127
- }
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
- }
1139
- if (bridge.isA) {
1140
- for (let parent of bridge.isA) {
1141
- this.addHierarchy(bridge.id, parent)
1142
- }
1143
- }
1144
- if (bridge.before) {
1145
- for (let after of bridge.before) {
1146
- if (typeof after == 'string') {
1147
- after = [after, 0]
1148
- }
1149
- this.addPriorities([after, [bridge.id, bridge.level]])
1150
- }
1151
- }
1152
- if (bridge.words) {
1153
- for (let def of bridge.words) {
1154
- if (typeof def == 'string') {
1155
- this.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
1156
- } else {
1157
- const word = def.word
1158
- def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
1159
- this.addWordInternal(word, def)
1160
- }
1161
- }
1162
- }
1163
- if (bridge.generator) {
1164
- this.config.generators.unshift(bridge.generator)
1165
- }
1166
- if (bridge.generators) {
1167
- const generators = [...bridge.generators]
1168
- generators.reverse()
1169
- for (let generator of generators) {
1170
- this.config.generators.unshift(generator)
1171
- }
1172
- }
1173
- if (bridge.generatorp) {
1174
- this.config.generators.unshift({
1175
- where: bridge.generatorp.where || client.where(3),
1176
- match: ({context}) => bridge.id == context.marker && context.paraphrase,
1177
- apply: (args) => bridge.generatorp(args),
1178
- })
1179
- }
1180
- if (bridge.generatorr) {
1181
- this.config.generators.unshift({
1182
- // TODO merge response and isResponse
1183
- where: bridge.generatorr.where || client.where(3),
1184
- match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
1185
- apply: (args) => bridge.generatorr(args),
1186
- })
1187
- }
1188
- if (bridge.evaluator) {
1189
- this.config.semantics.unshift({
1190
- where: bridge.evaluator.where || client.where(3),
1191
- match: ({context}) => bridge.id == context.marker && context.evaluate,
1192
- apply: (args) => bridge.evaluator(args),
1193
- })
1194
- }
1195
- if (bridge.semantic) {
1196
- this.config.semantics.unshift({
1197
- where: bridge.semantic.where || client.where(3),
1198
- match: ({context}) => bridge.id == context.marker,
1199
- apply: (args) => bridge.semantic(args),
1200
- })
1201
- }
1202
- }
1203
- if (config.operators) {
1204
- config.operators = config.operators.map((operator) => {
1205
- if (typeof operator === 'string') {
1206
- return { pattern: operator }
1207
- } else {
1208
- return operator
1209
- }
1210
- })
1211
- }
1298
+ handleCalculatedProps(this, config)
1212
1299
  }
1213
1300
  this.hierarchy = new Digraph(this.config.hierarchy)
1214
1301
  this.initConfig = _.cloneDeep(this.config)
1215
1302
  this.configs.push(new KM({ config: this.config, getCounter: (name) => this.config.getCounter(name), uuid: this._uuid }))
1216
1303
 
1217
- /*
1218
- if (config) {
1219
- this.configs.push(new KM({config, isSelf: true}))
1220
- this.addInternal(Object.assign({}, config), false)
1221
- } else {
1222
- this.configs.push( new KM({config: this.config, isSelf: true}) )
1223
- }
1224
- */
1225
-
1226
1304
  this.setUUIDs()
1227
1305
  this.initDefaults()
1228
1306
  if (!this.config.objects.namespaced) {
@@ -1311,6 +1389,7 @@ class Config {
1311
1389
  this._api.config = () => this
1312
1390
  this._api.uuid = this._uuid
1313
1391
  }
1392
+ this.rebuild()
1314
1393
  }
1315
1394
  }
1316
1395
 
@@ -1613,7 +1692,8 @@ class Config {
1613
1692
 
1614
1693
  if (currentConfig.api) {
1615
1694
  currentConfig.api.objects = args.objects
1616
- currentConfig.api.config = () => this
1695
+ // GREG42 currentConfig.api.config = () => this
1696
+ currentConfig.api.config = () => args.baseConfig
1617
1697
  currentConfig.api.uuid = currentConfig._uuid
1618
1698
  }
1619
1699
  // this.instances.forEach( (instance) => client.processInstance(this, instance) )
@@ -1877,7 +1957,6 @@ class Config {
1877
1957
  } else {
1878
1958
  addInternals.unshift(config)
1879
1959
  }
1880
- // this.addInternal(config, true, false, false, true)
1881
1960
  } else {
1882
1961
  if (interleaved) {
1883
1962
  addInternals.unshift(null)
@@ -1886,10 +1965,6 @@ class Config {
1886
1965
  km.valid()
1887
1966
  })
1888
1967
 
1889
- if (addInternals.length !== inits.length || addInternals.length !== initAfterApis.length) {
1890
- debugger // bug
1891
- }
1892
-
1893
1968
  const generators = this.config.generators
1894
1969
  const semantics = this.config.semantics
1895
1970
  if (reverseIt) {
@@ -1900,7 +1975,7 @@ class Config {
1900
1975
  if (!interleaved) {
1901
1976
  for (const config of addInternals) {
1902
1977
  if (!reverseIt) {
1903
- this.addInternal(config, true, false, false, true)
1978
+ this.addInternal(config, { includeNamespace: false, allowNameToBeNull: true })
1904
1979
  } else {
1905
1980
  this.addInternalR(config, true, false, false, true)
1906
1981
  }
@@ -2052,7 +2127,7 @@ class Config {
2052
2127
 
2053
2128
  this.applyNamespace(configPrime, km.namespace, km.uuid)
2054
2129
  first = false
2055
- this.addInternal(configPrime, false, true)
2130
+ this.addInternal(configPrime, { useOldVersion: false, skipObjects: true })
2056
2131
  applyUUID(configPrime, km.uuid)
2057
2132
  })
2058
2133
 
@@ -2342,7 +2417,7 @@ class Config {
2342
2417
  }
2343
2418
 
2344
2419
  // TODO get rid of useOldVersion arg
2345
- addInternal (more, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false) {
2420
+ addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2346
2421
  if (more instanceof Config) {
2347
2422
  more.initialize({ force: false })
2348
2423
  if (useOldVersion) {
@@ -2352,6 +2427,10 @@ class Config {
2352
2427
  more = _.cloneDeep(more.initConfig)
2353
2428
  }
2354
2429
  }
2430
+ if (hcps) {
2431
+ handleCalculatedProps(this, more)
2432
+ applyUUID(more, this._uuid)
2433
+ }
2355
2434
  for (const key of Object.keys(more)) {
2356
2435
  const value = more[key]
2357
2436
  // TODO remove name and description on the config bag
@@ -2533,7 +2612,6 @@ class Config {
2533
2612
  if (isDup(newOne, oldOne)) {
2534
2613
  if (oldOne.allowDups) {
2535
2614
  // the old one takes precedence to match what would happen during the original load
2536
- debugger
2537
2615
  this.config[key].splice(iOldOne, 1)
2538
2616
  break;
2539
2617
  }
@@ -2560,9 +2638,6 @@ class Config {
2560
2638
  // console.log('key', key, 'XXX')
2561
2639
  // console.log('more', JSON.stringify(more, null, 2))
2562
2640
  // this.config[key] = this.config[key].concat(more[key])
2563
- if (key == '2enerators') {
2564
- debugger
2565
- }
2566
2641
  // this.config[key] = this.config[key].concat(more[key])
2567
2642
  this.config[key] = more[key].concat(this.config[key])
2568
2643
  } else {
package/src/generators.js CHANGED
@@ -6,9 +6,11 @@ class Generator {
6
6
  // constructor ({ match, apply, uuid, index, km, priority, notes }) {
7
7
  constructor (generator) {
8
8
  generator = normalizeGenerator(generator)
9
- const { match, apply, uuid, index, km, priority, where, notes, debug } = generator
9
+ const { match, apply, uuid, index, km, priority, where, notes, debug, applyWrapped, property } = generator
10
10
  this.match = match
11
11
  this._apply = apply
12
+ this._applyWrapped = applyWrapped
13
+ this.property = property
12
14
  this.uuid = uuid
13
15
  this.index = index
14
16
  this.km = km
@@ -39,7 +41,7 @@ class Generator {
39
41
  }
40
42
 
41
43
  toString () {
42
- return `Generator(${this.match}, ${this._apply})`
44
+ return `Generator(${this.match}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
43
45
  }
44
46
 
45
47
  matches (baseArgs, objects, context, hierarchy, config, options = {}) {
@@ -198,9 +200,11 @@ class Generators {
198
200
  e.retryCall = () => generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
199
201
  const help = 'The error has a retryCall property that will recall the function that failed.'
200
202
  if (e.stack && e.message) {
201
- errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
203
+ const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
204
+ errorMessage = `Error applying generator '${info}. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
202
205
  } else if (e.error) {
203
- errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
206
+ const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
207
+ errorMessage = `Error applying generator '${info}. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
204
208
  } else {
205
209
  errorMessage = e.toString()
206
210
  }
package/src/helpers.js CHANGED
@@ -44,10 +44,23 @@ const appendNoDups = (l1, l2) => {
44
44
  }
45
45
 
46
46
  const safeEquals = (v1, v2) => {
47
- if (!deepEqual(stringify(v1), stringify(v2))) {
47
+ if (typeof v1 !== typeof v2) {
48
48
  return false
49
49
  }
50
- return true
50
+
51
+ const type = typeof v1
52
+ if (type == 'number' || type == 'string') {
53
+ return v1 == v2
54
+ } else if (type == 'function') {
55
+ return v1.toString() == v2.toString()
56
+ } else {
57
+ for (let key in v1) {
58
+ if (!safeEquals(v1[key], v2[key])) {
59
+ return false
60
+ }
61
+ }
62
+ return true
63
+ }
51
64
  }
52
65
 
53
66
  /*
@@ -238,7 +251,66 @@ const mapInPlace = (list, fn) => {
238
251
  }
239
252
  }
240
253
 
254
+ const updateQueries = (queryOrConfig) => {
255
+ if (typeof queryOrConfig == 'string' || queryOrConfig.query) {
256
+ return queryOrConfig
257
+ } else {
258
+ const config = queryOrConfig
259
+ return functionsToStrings(config)
260
+ }
261
+ }
262
+
263
+ const functionsToStrings = (config) => {
264
+ config = {...config}
265
+ const mapGenerator = (generator) => {
266
+ if (generator.apply) {
267
+ return { ...generator, match: generator.match.toString(), apply: generator.apply.toString() }
268
+ } else {
269
+ return [ generator[0].toString(), generator[1].toString() ]
270
+ }
271
+ }
272
+ if (config.generators) {
273
+ config.generators = config.generators.map( mapGenerator )
274
+ }
275
+ if (config.semantics) {
276
+ config.semantics = config.semantics.map( (semantic) => {
277
+ if (semantic.apply) {
278
+ return { ...semantic, match: semantic.match.toString(), apply: semantic.apply.toString() }
279
+ } else {
280
+ return [ semantic[0].toString(), semantic[1].toString() ]
281
+ }
282
+ })
283
+ }
284
+ if (config.bridges) {
285
+ config.bridges = config.bridges.map( (bridge) => {
286
+ bridge = {...bridge}
287
+ if (bridge.generator) {
288
+ bridge.generator = bridge.generator.toString()
289
+ }
290
+ if (bridge.generators) {
291
+ bridge.generators = bridge.generators.map( mapGenerator )
292
+ }
293
+ if (bridge.generatorp) {
294
+ bridge.generatorp = bridge.generatorp.toString()
295
+ }
296
+ if (bridge.generatorr) {
297
+ bridge.generatorr = bridge.generatorr.toString()
298
+ }
299
+ if (bridge.semantic) {
300
+ bridge.semantic = bridge.semantic.toString()
301
+ }
302
+ if (bridge.evaluator) {
303
+ bridge.evaluator = bridge.evaluator.toString()
304
+ }
305
+ return bridge
306
+ })
307
+ }
308
+ return config
309
+ }
310
+
241
311
  module.exports = {
312
+ functionsToStrings,
313
+ updateQueries,
242
314
  mapInPlace,
243
315
  validProps,
244
316
  args,
package/src/semantics.js CHANGED
@@ -6,9 +6,11 @@ class Semantic {
6
6
  // constructor ({match, apply, uuid, index, km, notes}) {
7
7
  constructor (semantic) {
8
8
  semantic = normalizeSemantic(semantic)
9
- const { match, apply, uuid, index, km, notes, priority, debug, where } = semantic
9
+ const { match, apply, uuid, index, km, notes, priority, debug, where, applyWrapped, property } = semantic
10
10
  this.matcher = match
11
11
  this._apply = apply
12
+ this._applyWrapped = applyWrapped
13
+ this.property = property
12
14
  this.uuid = uuid
13
15
  this.index = index
14
16
  this.km = km
@@ -27,7 +29,7 @@ class Semantic {
27
29
  }
28
30
 
29
31
  toString () {
30
- return `Semantic(${this.matcher}, ${this._apply})`
32
+ return `Semantic(${this.matcher}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
31
33
  }
32
34
 
33
35
  getAPI (config) {
@@ -192,9 +194,11 @@ class Semantics {
192
194
  e.retryCall = () => semantic.apply(args, context, s, log, options)
193
195
  const help = 'The error has a retryCall property that will recall the function that failed.'
194
196
  if (e.stack && e.message) {
195
- errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.toString()} stack is ${e.stack}. Semantic is ${semantic.toString()}. ${help}`
197
+ const info = `${semantic.notes ? semantic.notes : ''}${semantic.where ? semantic.where : ''}`
198
+ errorMessage = `Error applying semantics '${info}'. Error is ${e.toString()} stack is ${e.stack}. Semantic is ${semantic.toString()}. ${help}`
196
199
  } else if (e.error) {
197
- errorMessage = `Error applying semantics '${semantic.notes}'. Error is ${e.error.join()}. Semantic is ${semantic.toString()}. ${help}`
200
+ const info = `${semantic.notes ? semantic.notes : ''}${semantic.where ? semantic.where : ''}`
201
+ errorMessage = `Error applying semantics '${info}'. Error is ${e.error.join()}. Semantic is ${semantic.toString()}. ${help}`
198
202
  } else {
199
203
  errorMessage = e.toString();
200
204
  }