theprogrammablemind_4wp 7.5.4 → 7.5.5

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