theprogrammablemind 7.5.4-beta.0 → 7.5.4-beta.10

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({
@@ -1299,6 +1303,7 @@ const knowledgeModule = async ({
1299
1303
  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
1304
  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
1305
  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\'' })
1306
+ 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
1307
 
1303
1308
  const args = parser.parse_args()
1304
1309
  args.count = args.count || 1
@@ -1316,6 +1321,10 @@ const knowledgeModule = async ({
1316
1321
  console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
1317
1322
  }
1318
1323
  }
1324
+ if (args.debugOperator) {
1325
+ // id/level
1326
+ global.entodictonDebugOperator = args.debugOperator
1327
+ }
1319
1328
 
1320
1329
  if (args.clean) {
1321
1330
  const tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
@@ -1450,6 +1459,9 @@ const knowledgeModule = async ({
1450
1459
  for (const semantic of easyToRead) {
1451
1460
  semantic.match = semantic.match.toString()
1452
1461
  semantic.apply = semantic.apply.toString()
1462
+ if (semantic.applyWrapped) {
1463
+ semantic.applyWrapped = semantic.applyWrapped.toString()
1464
+ }
1453
1465
  }
1454
1466
  console.dir(easyToRead)
1455
1467
  }
@@ -1656,7 +1668,14 @@ function where(goUp = 2) {
1656
1668
  const e = new Error();
1657
1669
  const regexForm1 = /\((.*):(\d+):(\d+)\)$/
1658
1670
  const regexForm2 = /at (.*):(\d+):(\d+)$/
1659
- const line = e.stack.split("\n")[goUp];
1671
+ const lines = e.stack.split("\n")
1672
+ let line
1673
+ for (line of lines.slice(1)) {
1674
+ if (!(line.includes("config.js:") || line.includes("client.js:"))) {
1675
+ break;
1676
+ }
1677
+ }
1678
+ // const line = e.stack.split("\n")[goUp];
1660
1679
  const match = regexForm1.exec(line) || regexForm2.exec(line);
1661
1680
  if (match) {
1662
1681
  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-beta.0",
65
+ "version": "7.5.4-beta.10",
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,114 @@ 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.generatorp) {
76
+ config.config.generators.unshift({
77
+ where: bridge.generatorp.where || bridge.where || client.where(4),
78
+ match: ({context}) => bridge.id == context.marker && context.paraphrase,
79
+ apply: (args) => bridge.generatorp(args),
80
+ applyWrapped: bridge.generatorp,
81
+ property: 'generatorp',
82
+ })
83
+ }
84
+ if (bridge.generatorr) {
85
+ config.config.generators.unshift({
86
+ // TODO merge response and isResponse
87
+ where: bridge.generatorr.where || bridge.where || client.where(3),
88
+ match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
89
+ apply: (args) => bridge.generatorr(args),
90
+ applyWrapped: bridge.generatorr,
91
+ property: 'generatorr',
92
+ })
93
+ }
94
+ if (bridge.evaluator) {
95
+ config.config.semantics.unshift({
96
+ where: bridge.evaluator.where || bridge.where || client.where(3),
97
+ match: ({context}) => bridge.id == context.marker && context.evaluate,
98
+ apply: (args) => bridge.evaluator(args),
99
+ applyWrapped: bridge.evaluator,
100
+ property: 'evaluator',
101
+ })
102
+ }
103
+ if (bridge.semantic) {
104
+ config.config.semantics.unshift({
105
+ where: bridge.semantic.where || bridge.where || client.where(3),
106
+ match: ({context}) => bridge.id == context.marker,
107
+ apply: (args) => bridge.semantic(args),
108
+ applyWrapped: bridge.semantic,
109
+ property: 'semantic',
110
+ })
111
+ }
112
+ }
113
+
114
+ const handleCalculatedProps = (baseConfig, moreConfig) => {
115
+ for (let bridge of moreConfig.bridges) {
116
+ const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
117
+ 'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where' ]
118
+ helpers.validProps(valid, bridge, 'bridge')
119
+ handleBridgeProps(baseConfig, bridge)
120
+ }
121
+ if (moreConfig.operators) {
122
+ moreConfig.operators = moreConfig.operators.map((operator) => {
123
+ if (typeof operator === 'string') {
124
+ return { pattern: operator }
125
+ } else {
126
+ return operator
127
+ }
128
+ })
129
+ }
130
+ }
131
+
25
132
  if (runtime.process.env.DEBUG_HIERARCHY) {
26
133
  global.entodictonDebugHierarchy = JSON.parse(runtime.process.env.DEBUG_HIERARCHY)
27
134
  }
@@ -35,6 +142,11 @@ if (runtime.process.env.DEBUG_BRIDGE) {
35
142
  global.entodictonDebugBridge[1] = int(global.entodictonDebugBridge[1])
36
143
  }
37
144
 
145
+ if (runtime.process.env.DEBUG_OPERATOR) {
146
+ // id/level
147
+ global.entodictonDebugOperator = runtime.process.env.DEBUG_OPERATOR
148
+ }
149
+
38
150
  const hierarchyCanonical = (element) => {
39
151
  if (element.child && element.parent) {
40
152
  return element
@@ -86,6 +198,17 @@ const normalizeConfig = (config) => {
86
198
  config[bag][i].km = config.name
87
199
  }
88
200
  }
201
+
202
+ }
203
+ if (config['bridges']) {
204
+ for (let bridge of config['bridges']) {
205
+ if (!bridge.level) {
206
+ bridge.level = 0
207
+ }
208
+ if (!bridge.bridge) {
209
+ bridge.bridge = "{ ...next(operator) }"
210
+ }
211
+ }
89
212
  }
90
213
  }
91
214
  }
@@ -324,6 +447,37 @@ const multiApiImpl = (initializer) => {
324
447
 
325
448
  class Config {
326
449
 
450
+ inDevelopmentMode (call) {
451
+ config.developmentModeOn += 1
452
+ try {
453
+ call()
454
+ } finally {
455
+ config.developmentModeOn -= 1
456
+ }
457
+ }
458
+
459
+ // return the config with just the elements from the included KM's
460
+ baseConfig() {
461
+ const operators = this.config.operators.filter((operator) => {
462
+ return operator.uuid !== this.uuid
463
+ })
464
+ const bridges = this.config.bridges.filter((bridge) => {
465
+ return bridge.uuid !== this.uuid
466
+ })
467
+ const words = {}
468
+ for (let word in this.config.words) {
469
+ const defs = this.config.words[word].filter( (def) => def.uuid !== this.uuid )
470
+ if (defs.length > 0) {
471
+ words[word] = defs
472
+ }
473
+ }
474
+ return {
475
+ operators,
476
+ bridges,
477
+ words
478
+ }
479
+ }
480
+
327
481
  getCounter (maybeName = '') {
328
482
  const counter = this.configCounter
329
483
  this.configCounter += 1
@@ -525,12 +679,13 @@ class Config {
525
679
  }
526
680
  const instanceFragments = (instance.fragments || []).map((fragment) => fragment.key || fragment.query).map( toCanonical )
527
681
  const templateFragments = (template.fragments || []).concat(this.dynamicFragments).map( toCanonical )
528
- const sameFragments = deepEqual(templateFragments, instanceFragments)
529
- const sameQueries = deepEqual((template.queries || []), (instance.queries || []))
682
+ const sameFragments = helpers.safeEquals(templateFragments, instanceFragments)
683
+ const sameQueries = helpers.safeEquals((template.queries || []).map(helpers.updateQueries), (instance.queries || []))
530
684
  return !(instance && sameQueries && sameFragments)
531
685
  }
532
686
 
533
687
  load (template, instance, options = { rebuild: false } ) {
688
+ instance.template = template
534
689
  this.logs.push(`loading template for ${this.name}`)
535
690
  if (instance && instance.associations && !options.rebuild) {
536
691
  this.addAssociations(instance.associations)
@@ -592,7 +747,7 @@ class Config {
592
747
  }
593
748
  }
594
749
  if (global.entodictonDebugAssociation) {
595
- if (deepEqual(global.entodictonDebugAssociation, association)) {
750
+ if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
596
751
  debugger; // debug association hit
597
752
  }
598
753
  }
@@ -627,7 +782,7 @@ class Config {
627
782
  throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
628
783
  }
629
784
  if (global.entodictonDebugHierarchy) {
630
- if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
785
+ if ((helpers.safeEquals.entodictonDebugHierarchy, [child, parent])) {
631
786
  debugger; // debug hierarchy hit
632
787
  }
633
788
  }
@@ -645,7 +800,7 @@ class Config {
645
800
  }
646
801
 
647
802
  if (global.entodictonDebugHierarchy) {
648
- if (deepEqual(global.entodictonDebugHierarchy, [child, parent])) {
803
+ if (helpers.safeEquals(global.entodictonDebugHierarchy, [child, parent])) {
649
804
  debugger; // debug hierarchy hit
650
805
  }
651
806
  }
@@ -689,6 +844,7 @@ class Config {
689
844
  if (global.transitoryMode) {
690
845
  def.transitoryMode = true
691
846
  }
847
+ handleBridgeProps(this, def)
692
848
  bridges.push(def)
693
849
  this.checkBridges();
694
850
  this._delta.json.bridges.push({ action: 'add', bridge: def })
@@ -751,6 +907,7 @@ class Config {
751
907
  if (!this.config.operators) {
752
908
  this.config.operators = []
753
909
  }
910
+
754
911
  const operators = this.config.operators
755
912
 
756
913
  let operator;
@@ -760,6 +917,12 @@ class Config {
760
917
  operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
761
918
  }
762
919
 
920
+ if (global.entodictonDebugOperator) {
921
+ if (operator.pattern === global.entodictonDebugOperator) {
922
+ debugger; // debug operator hit
923
+ }
924
+ }
925
+
763
926
  if (operator.allowDups) {
764
927
  if (operators.find( (o) => o.pattern == operator.pattern )) {
765
928
  return;
@@ -1018,7 +1181,8 @@ class Config {
1018
1181
  'debug',
1019
1182
 
1020
1183
  // TODO Fix these from the test app
1021
- 'implicit',
1184
+ 'implicits',
1185
+ 'convolution',
1022
1186
  'expected_generated',
1023
1187
  'expected_results',
1024
1188
  'skipSemantics',
@@ -1114,115 +1278,12 @@ class Config {
1114
1278
  if (config) {
1115
1279
  config = _.cloneDeep(config)
1116
1280
  this.config = config
1117
- for (let bridge of this.config.bridges) {
1118
- const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'convolution', '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
- }
1281
+ handleCalculatedProps(this, config)
1212
1282
  }
1213
1283
  this.hierarchy = new Digraph(this.config.hierarchy)
1214
1284
  this.initConfig = _.cloneDeep(this.config)
1215
1285
  this.configs.push(new KM({ config: this.config, getCounter: (name) => this.config.getCounter(name), uuid: this._uuid }))
1216
1286
 
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
1287
  this.setUUIDs()
1227
1288
  this.initDefaults()
1228
1289
  if (!this.config.objects.namespaced) {
@@ -1311,6 +1372,7 @@ class Config {
1311
1372
  this._api.config = () => this
1312
1373
  this._api.uuid = this._uuid
1313
1374
  }
1375
+ this.rebuild()
1314
1376
  }
1315
1377
  }
1316
1378
 
@@ -1613,7 +1675,8 @@ class Config {
1613
1675
 
1614
1676
  if (currentConfig.api) {
1615
1677
  currentConfig.api.objects = args.objects
1616
- currentConfig.api.config = () => this
1678
+ // GREG42 currentConfig.api.config = () => this
1679
+ currentConfig.api.config = () => args.baseConfig
1617
1680
  currentConfig.api.uuid = currentConfig._uuid
1618
1681
  }
1619
1682
  // this.instances.forEach( (instance) => client.processInstance(this, instance) )
@@ -1877,7 +1940,6 @@ class Config {
1877
1940
  } else {
1878
1941
  addInternals.unshift(config)
1879
1942
  }
1880
- // this.addInternal(config, true, false, false, true)
1881
1943
  } else {
1882
1944
  if (interleaved) {
1883
1945
  addInternals.unshift(null)
@@ -1886,10 +1948,6 @@ class Config {
1886
1948
  km.valid()
1887
1949
  })
1888
1950
 
1889
- if (addInternals.length !== inits.length || addInternals.length !== initAfterApis.length) {
1890
- debugger // bug
1891
- }
1892
-
1893
1951
  const generators = this.config.generators
1894
1952
  const semantics = this.config.semantics
1895
1953
  if (reverseIt) {
@@ -1900,7 +1958,7 @@ class Config {
1900
1958
  if (!interleaved) {
1901
1959
  for (const config of addInternals) {
1902
1960
  if (!reverseIt) {
1903
- this.addInternal(config, true, false, false, true)
1961
+ this.addInternal(config, { includeNamespace: false, allowNameToBeNull: true })
1904
1962
  } else {
1905
1963
  this.addInternalR(config, true, false, false, true)
1906
1964
  }
@@ -2052,7 +2110,7 @@ class Config {
2052
2110
 
2053
2111
  this.applyNamespace(configPrime, km.namespace, km.uuid)
2054
2112
  first = false
2055
- this.addInternal(configPrime, false, true)
2113
+ this.addInternal(configPrime, { useOldVersion: false, skipObjects: true })
2056
2114
  applyUUID(configPrime, km.uuid)
2057
2115
  })
2058
2116
 
@@ -2342,7 +2400,7 @@ class Config {
2342
2400
  }
2343
2401
 
2344
2402
  // TODO get rid of useOldVersion arg
2345
- addInternal (more, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false) {
2403
+ addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2346
2404
  if (more instanceof Config) {
2347
2405
  more.initialize({ force: false })
2348
2406
  if (useOldVersion) {
@@ -2352,6 +2410,10 @@ class Config {
2352
2410
  more = _.cloneDeep(more.initConfig)
2353
2411
  }
2354
2412
  }
2413
+ if (hcps) {
2414
+ handleCalculatedProps(this, more)
2415
+ applyUUID(more, this._uuid)
2416
+ }
2355
2417
  for (const key of Object.keys(more)) {
2356
2418
  const value = more[key]
2357
2419
  // TODO remove name and description on the config bag
@@ -2560,9 +2622,6 @@ class Config {
2560
2622
  // console.log('key', key, 'XXX')
2561
2623
  // console.log('more', JSON.stringify(more, null, 2))
2562
2624
  // this.config[key] = this.config[key].concat(more[key])
2563
- if (key == '2enerators') {
2564
- debugger
2565
- }
2566
2625
  // this.config[key] = this.config[key].concat(more[key])
2567
2626
  this.config[key] = more[key].concat(this.config[key])
2568
2627
  } 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 = {}) {
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) {