theprogrammablemind_4wp 7.5.4-beta.1 → 7.5.4-beta.10

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({
@@ -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.1",
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', '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
- }
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) {