theprogrammablemind_4wp 7.5.8 → 7.6.0-beta.1

Sign up to get free protection for your applications and to get access to all the features.
package/src/config.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // lookup = (name) => returns <config>
2
2
  const { Semantics, normalizeGenerator } = require('./semantics')
3
3
  const { Generators } = require('./generators')
4
- // const { uuid: uuidv4 } = require('uuidv4')
4
+ const { v4 : uuidv4 } = require('uuid');
5
5
  const client = require('../client')
6
6
  const DigraphInternal = require('./digraph_internal')
7
7
  const helpers = require('./helpers')
8
+ const { ecatch } = require('./helpers')
8
9
  const runtime = require('../runtime')
9
10
  const _ = require('lodash')
10
11
 
@@ -21,106 +22,332 @@ const indent = (string, indent) => {
21
22
  return string.replace(/^/gm, ' '.repeat(indent));
22
23
  }
23
24
 
24
- const handleBridgeProps = (config, bridge) => {
25
- if (!bridge.bridge) {
26
- bridge.bridge = "{ ...next(operator) }"
27
- }
28
- if (!bridge.level) {
29
- bridge.level = 0
25
+ const config_toServer = (config) => {
26
+ }
27
+
28
+ const debugPriority = (priority) => {
29
+ if (global.entodictonDebugPriority) {
30
+ if (helpers.safeEquals(entodictonDebugPriority, priority)) {
31
+ debugger; // debug hierarchy hit
32
+ }
30
33
  }
31
- if (bridge.children) {
32
- for (let child of bridge.children) {
33
- config.addHierarchy(child, bridge.id)
34
+ }
35
+
36
+ const debugAssociation = (association) => {
37
+ if (global.entodictonDebugAssociation) {
38
+ if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
39
+ debugger; // debug association hit
34
40
  }
35
41
  }
36
- if (bridge.parents) {
37
- for (let parent of bridge.parents) {
38
- config.addHierarchy(bridge.id, parent)
42
+ }
43
+
44
+ const debugHierarchy = (pair) => {
45
+ if (global.entodictonDebugHierarchy) {
46
+ if (helpers.safeEquals(global.entodictonDebugHierarchy, pair)) {
47
+ debugger; // debug hierarchy hit
39
48
  }
40
49
  }
41
- if (bridge.isA) {
42
- for (let parent of bridge.isA) {
43
- config.addHierarchy(bridge.id, parent)
50
+ }
51
+
52
+ const debugBridge = (bridge) => {
53
+ if (global.entodictonDebugBridge) {
54
+ if (global.entodictonDebugBridge[0] == bridge.id && global.entodictonDebugBridge[1] == bridge.level) {
55
+ debugger; // debug hierarchy hit
44
56
  }
45
57
  }
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]])
58
+ }
59
+
60
+ const debugOperator = (operator) => {
61
+ if (global.entodictonDebugOperator) {
62
+ if ((operator.pattern || operator) === global.entodictonDebugOperator) {
63
+ debugger; // debug operator hit
52
64
  }
53
65
  }
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)
66
+ }
67
+
68
+ const debugConfigProps = (config) => {
69
+ if (!config) {
70
+ return
71
+ }
72
+ const checkProps = [
73
+ { property: 'priorities', check: (v) => debugPriority(v) },
74
+ { property: 'association', check: (v) => debugAssociation(v) },
75
+ { property: 'hierarchy', check: (v) => debugHierarchy(v) },
76
+ { property: 'operators', check: (v) => debugOperator(v) },
77
+ { property: 'bridges', check: (v) => debugBridge(v) },
78
+ ]
79
+ for (const { property, check } of checkProps) {
80
+ if (config[property]) {
81
+ for (const value of config[property]) {
82
+ check(value)
62
83
  }
63
84
  }
64
85
  }
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
- }
86
+ }
87
+
88
+ const validConfigProps = (config) => {
89
+ const valid = [
90
+ 'hierarchy',
91
+ 'objects',
92
+ 'bridges',
93
+ 'operators',
94
+ 'words',
95
+ 'priorities',
96
+ 'associations',
97
+ 'name',
98
+ 'version',
99
+ 'generatorp',
100
+ 'generators',
101
+ 'semantics',
102
+ 'where',
103
+ 'floaters',
104
+ 'debug',
105
+
106
+ // TODO Fix these from the test app
107
+ 'implicits',
108
+ 'convolution',
109
+ 'expected_generated',
110
+ 'expected_results',
111
+ 'skipSemantics',
112
+ 'description',
113
+ 'contexts',
114
+ 'utterances',
115
+ 'flatten',
116
+
117
+ 'namespaces',
118
+ 'eqClasses',
119
+ ]
120
+ helpers.validProps(valid, config, 'config')
121
+ }
122
+
123
+ const setupInitializerFNArgs = (config, args) => {
124
+ const aw = (word, def) => config.addWord(word, def, args.uuid)
125
+ const ag = (generator) => config.addGenerator(generator, args.uuid, config.name)
126
+ const km = (name) => config.getConfig(name)
127
+ const apis = (name) => config.getConfig(name).api
128
+
129
+ return {
130
+ ...args,
131
+ addWord: aw,
132
+ addGenerator: ag,
133
+ config: config.getPseudoConfig(args.uuid, args.currentConfig),
134
+ km,
135
+ baseConfig: config,
136
+ apis,
74
137
  }
75
- if (bridge.generatorpr) {
76
- bridge.generatorp = bridge.generatorpr
77
- bridge.generatorr = bridge.generatorpr
138
+ }
139
+
140
+ const operatorKey_valid = (key) => {
141
+ if (
142
+ !_.isArray(key) ||
143
+ key.length != 2 ||
144
+ !_.isString(key[0]) ||
145
+ !_.isInteger(key[1]) ||
146
+ key[1] < 0
147
+ ) {
148
+
149
+ let details = ''
150
+ if (!_.isArray(key)) {
151
+ details = "Expected an array."
152
+ } else if (key.length != 2) {
153
+ details = "Expected an array of length two."
154
+ } else if (!_.isString(key[0])) {
155
+ details = "Expected element zero to be a string that is an operator id."
156
+ } else if (!_.isInteger(key[1])) {
157
+ details = "Expected element one to be a number that is an operator level."
158
+ } else if (key[1] < 0) {
159
+ details = "Expected element one to be a number that is an operator level which is greater than zero."
160
+ }
161
+ throw new Error(`${JSON.stringify(key)} is not a valid operator key. Values are of the form [<operatorId>, <operatorLevel>]. ${details}`)
78
162
  }
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
- })
163
+ }
164
+
165
+ const elist = (list, check, prefix) => {
166
+ for ([index, element] of list.entries()) {
167
+ try {
168
+ check(element)
169
+ } catch( e ) {
170
+ throw new Error(prefix(index, e))
171
+ }
87
172
  }
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
- })
173
+ }
174
+ const priorities_valid = (cps) => {
175
+ elist(cps, (cp) => priority_valid(cp), (index, e) => `priorities has an invalid priority at position ${index}. ${e}`)
176
+ }
177
+
178
+ const priority_valid = (cp) => {
179
+ if (!cp.context) {
180
+ throw new Error(`The priority ${JSON.stringify(cp)} is missing the "context" property. That is a list of the operator keys that are to be prioritized differently.`)
97
181
  }
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
- })
182
+ if (!_.isArray(cp.context)) {
183
+ throw new Error(`The priority ${JSON.stringify(cp)} has an invalid "context" value. That is a list of the operator keys that are to be prioritized differently.`)
106
184
  }
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
- })
185
+ elist(cp.context, (element) => operatorKey_valid(element), (index, e) => `The priority ${JSON.stringify(cp)} has an invalid operator key at position ${index}. ${e}`)
186
+ if (!_.isArray(cp.choose)) {
187
+ throw new Error(`The priority ${JSON.stringify(cp)} has an invalid "choose" value. The value should be a list of the operators in the context to consider for prioritization.`)
115
188
  }
189
+ elist(cp.choose,
190
+ (element) => {
191
+ if (!element && element !== 0) {
192
+ throw new Error(`The value should be an index into the "context" property of the operator that is to be considered for prioritization.`)
193
+ }
194
+ if (!_.isInteger(element) || element < 0 || element >= cp.context.length) {
195
+ throw new Error(`The value should be an index into the "context" property of the operator that is to be considered for prioritization. Valid values are between 0 and ${cp.context.length-1}.`)
196
+ }
197
+ },
198
+ (index, e) => `The choose property in the priority ${JSON.stringify(cp)} has an invalid index at position ${index}. ${e}`
199
+ )
116
200
  }
117
201
 
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' ]
202
+ const handleBridgeProps = (config, bridge, addFirst) => {
203
+ ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
204
+ () => {
205
+ if (!bridge.bridge) {
206
+ bridge.bridge = "{ ...next(operator) }"
207
+ }
208
+ if (!bridge.level) {
209
+ bridge.level = 0
210
+ }
211
+ if (bridge.children) {
212
+ for (let child of bridge.children) {
213
+ config.addHierarchy(child, bridge.id)
214
+ }
215
+ }
216
+ if (bridge.parents) {
217
+ for (let parent of bridge.parents) {
218
+ config.addHierarchy(bridge.id, parent)
219
+ }
220
+ }
221
+ if (bridge.isA) {
222
+ for (let parent of bridge.isA) {
223
+ config.addHierarchy(bridge.id, parent)
224
+ }
225
+ }
226
+ if (bridge.before) {
227
+ for (let after of bridge.before) {
228
+ if (typeof after == 'string') {
229
+ after = [after, 0]
230
+ }
231
+ config.addPriority({ context: [[bridge.id, bridge.level], after], choose: [0] })
232
+ }
233
+ }
234
+ if (bridge.after) {
235
+ for (let before of bridge.after) {
236
+ if (typeof before == 'string') {
237
+ before = [before, 0]
238
+ }
239
+ config.addPriority({ context: [before, [bridge.id, bridge.level]], choose: [0] })
240
+ }
241
+ }
242
+ if (bridge.words) {
243
+ for (let def of bridge.words) {
244
+ if (typeof def == 'string') {
245
+ config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
246
+ } else {
247
+ const word = def.word
248
+ def = { initial: JSON.stringify(def), id: bridge.id, word }
249
+ config.addWordInternal(word, def)
250
+ }
251
+ }
252
+ }
253
+ /*
254
+ if (bridge.generator) {
255
+ if (addFirst) {
256
+ config.config.generators.unshift(bridge.generator)
257
+ } else {
258
+ config.config.generators.push(bridge.generator)
259
+ }
260
+ }
261
+ */
262
+ if (bridge.generators) {
263
+ const generators = [...bridge.generators]
264
+ generators.reverse()
265
+ for (let generator of generators) {
266
+ if (addFirst) {
267
+ config.config.generators.unshift(generator)
268
+ } else {
269
+ config.config.generators.push(generator)
270
+ }
271
+ }
272
+ }
273
+ if (bridge.generatorpr) {
274
+ bridge.generatorp = bridge.generatorpr
275
+ bridge.generatorr = bridge.generatorpr
276
+ }
277
+ if (bridge.generatorp) {
278
+ const match = bridge.generatorp.match || (() => true)
279
+ const apply = typeof bridge.generatorp == 'function' ? bridge.generatorp : bridge.generatorp.apply || bridge.generatorp
280
+ const level = bridge.generatorp.level >= 0 ? bridge.generatorp.level : bridge.level + 1
281
+
282
+ const generator = {
283
+ where: bridge.generatorp.where || bridge.where || client.where(4),
284
+ match: (args) => bridge.id == args.context.marker && args.context.level == level && args.context.paraphrase && match(args),
285
+ apply: (args) => apply(args),
286
+ applyWrapped: apply,
287
+ property: 'generatorp',
288
+ }
289
+ if (addFirst) {
290
+ config.config.generators.unshift(generator)
291
+ } else {
292
+ config.config.generators.push(generator)
293
+ }
294
+
295
+ }
296
+ if (bridge.generatorr) {
297
+ const match = bridge.generatorr.match || (() => true)
298
+ const apply = typeof bridge.generatorr == 'function' ? bridge.generatorr : bridge.generatorr.apply || bridge.generatorr
299
+ const level = bridge.generatorr.level >= 0 ? bridge.generatorr.level : bridge.level + 1
300
+ const generator = {
301
+ where: bridge.generatorr.where || bridge.where || client.where(4),
302
+ match: (args) => bridge.id == args.context.marker && args.context.level == level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && match(args),
303
+ apply: (args) => apply(args),
304
+ applyWrapped: apply,
305
+ property: 'generatorr',
306
+ }
307
+ if (addFirst) {
308
+ config.config.generators.unshift(generator)
309
+ } else {
310
+ config.config.generators.push(generator)
311
+ }
312
+ }
313
+ if (bridge.evaluator) {
314
+ const semantic = {
315
+ where: bridge.evaluator.where || bridge.where || client.where(3),
316
+ match: ({context}) => bridge.id == context.marker && context.evaluate,
317
+ apply: (args) => bridge.evaluator(args),
318
+ applyWrapped: bridge.evaluator,
319
+ property: 'evaluator',
320
+ }
321
+ if (addFirst) {
322
+ config.config.semantics.unshift(semantic)
323
+ } else {
324
+ config.config.semantics.push(semantic)
325
+ }
326
+ }
327
+ if (bridge.semantic) {
328
+ const semantic = {
329
+ where: bridge.semantic.where || bridge.where || client.where(3),
330
+ match: ({context}) => bridge.id == context.marker,
331
+ apply: (args) => bridge.semantic(args),
332
+ applyWrapped: bridge.semantic,
333
+ property: 'semantic',
334
+ }
335
+ if (addFirst) {
336
+ config.config.semantics.unshift(semantic)
337
+ } else {
338
+ config.config.semantics.push(semantic)
339
+ }
340
+ }
341
+ }
342
+ )
343
+ }
344
+
345
+ const handleCalculatedProps = (baseConfig, moreConfig, addFirst) => {
346
+ for (let bridge of (moreConfig.bridges || [])) {
347
+ const valid = [ 'after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
348
+ 'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid' ]
122
349
  helpers.validProps(valid, bridge, 'bridge')
123
- handleBridgeProps(baseConfig, bridge)
350
+ handleBridgeProps(baseConfig, bridge, addFirst)
124
351
  }
125
352
  if (moreConfig.operators) {
126
353
  moreConfig.operators = moreConfig.operators.map((operator) => {
@@ -137,13 +364,31 @@ if (runtime.process.env.DEBUG_HIERARCHY) {
137
364
  global.entodictonDebugHierarchy = JSON.parse(runtime.process.env.DEBUG_HIERARCHY)
138
365
  }
139
366
 
367
+
368
+ // i keep randomly doing one of the other so I will just make both work the same way
369
+ if (runtime.process.env.DEBUG_PRIORITIES) {
370
+ global.entodictonDebugPriority = JSON.parse(runtime.process.env.DEBUG_PRIORITIES)
371
+ }
372
+ if (runtime.process.env.DEBUG_PRIORITY) {
373
+ global.entodictonDebugPriority = JSON.parse(runtime.process.env.DEBUG_PRIORITY)
374
+ }
375
+
376
+ if (runtime.process.env.DEBUG_CONTEXTUAL_PRIORITY) {
377
+ global.entodictonDebugContextualPriority = JSON.parse(runtime.process.env.DEBUG_CONTEXTUAL_PRIORITY)
378
+ }
379
+
380
+ if (runtime.process.env.DEBUG_ASSOCIATION) {
381
+ global.entodictonDebugAssociation = JSON.parse(runtime.process.env.DEBUG_ASSOCIATION)
382
+ }
383
+
140
384
  if (runtime.process.env.DEBUG_BRIDGE) {
141
385
  // id/level
142
386
  global.entodictonDebugBridge = runtime.process.env.DEBUG_BRIDGE.split('/')
143
387
  if (global.entodictonDebugBridge.length !== 2) {
144
388
  console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
389
+ process.exit(-1)
145
390
  }
146
- global.entodictonDebugBridge[1] = int(global.entodictonDebugBridge[1])
391
+ global.entodictonDebugBridge[1] = parseInt(global.entodictonDebugBridge[1])
147
392
  }
148
393
 
149
394
  if (runtime.process.env.DEBUG_OPERATOR) {
@@ -161,7 +406,7 @@ const hierarchyCanonical = (element) => {
161
406
 
162
407
  const isValidDef = (word, def, config) => {
163
408
  if (!def.id) {
164
- throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`
409
+ throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
165
410
  }
166
411
  /*
167
412
  if (!def.initial) {
@@ -214,6 +459,14 @@ const normalizeConfig = (config) => {
214
459
  }
215
460
  }
216
461
  }
462
+
463
+ if (config.semantics) {
464
+ for (let semantic of config.semantics) {
465
+ if (semantic.oneShot) {
466
+ semantic.id = uuid()
467
+ }
468
+ }
469
+ }
217
470
  }
218
471
  }
219
472
 
@@ -421,8 +674,8 @@ const multiApiImpl = (initializer) => {
421
674
  initializer(config, api)
422
675
  const name = api.getName()
423
676
  multiApi.apis[name] = api
424
- api.objects = config.get('objects')
425
- api.config = () => config
677
+ // api.objects = config.get('objects')
678
+ // api.config = () => config
426
679
  multiApi.current = name
427
680
  },
428
681
 
@@ -433,11 +686,13 @@ const multiApiImpl = (initializer) => {
433
686
  }
434
687
  },
435
688
 
689
+ /*
436
690
  set objects (value) {
437
691
  for (const key in Object.keys(this.apis)) {
438
692
  this.apis[key].objects = value
439
693
  }
440
694
  },
695
+ */
441
696
 
442
697
  // "product1": apiInstance(testData1),
443
698
  apis: {
@@ -451,6 +706,47 @@ const multiApiImpl = (initializer) => {
451
706
 
452
707
  class Config {
453
708
 
709
+ toServer (config) {
710
+ return config_toServer(config)
711
+ }
712
+
713
+ base () {
714
+ const base = new Config()
715
+ for (let km of this.configs.reverse()) {
716
+ if (km.isSelf) {
717
+ continue
718
+ }
719
+ base.add(km.config)
720
+ }
721
+ return base
722
+ }
723
+
724
+ getPseudoConfig (uuid, config) {
725
+ return {
726
+ description: "this is a pseudo config that has limited functionality due to being available in the initializer function context",
727
+ addAssociation: (...args) => this.addAssociation(...args),
728
+ addAssociations: (...args) => this.addAssociations(...args),
729
+ addBridge: (...args) => this.addBridge(...args, uuid),
730
+ addGenerator: (...args) => this.addGenerator(...args, uuid, config.name),
731
+ addHierarchy: (...args) => this.addHierarchy(...args),
732
+ addOperator: (...args) => this.addOperator(...args, uuid),
733
+ addPriority: (...args) => this.addPriority(...args),
734
+ addPriorities: (...args) => this.addPriorities(...args),
735
+ addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
736
+ removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
737
+ addWord: (...args) => this.addWord(...args, uuid),
738
+
739
+ getHierarchy: (...args) => this.config.hierarchy,
740
+ getBridges: (...args) => this.config.bridges,
741
+
742
+ addArgs: (...args) => this.addArgs(...args),
743
+ getBridge: (...args) => this.getBridge(...args),
744
+ fragment: (...args) => this.fragment(...args),
745
+ exists: (...args) => this.exists(...args),
746
+ addAPI: (...args) => this.addAPI(...args),
747
+ }
748
+ }
749
+
454
750
  inDevelopmentMode (call) {
455
751
  config.developmentModeOn += 1
456
752
  try {
@@ -489,9 +785,6 @@ class Config {
489
785
  }
490
786
 
491
787
  setTestConfig(testConfig) {
492
- if (this.name == 'ui') {
493
- console.log('ui setting testConfig')
494
- }
495
788
  this.testConfig = testConfig
496
789
  }
497
790
 
@@ -614,8 +907,9 @@ class Config {
614
907
  return instance
615
908
  }
616
909
  */
617
- getEvaluator (s, log, context) {
910
+ getEvaluator (s, calls, log, context) {
618
911
  const instance = s({ ...context, evaluate: true })
912
+ calls.touch(instance)
619
913
  if (!instance.evalue && !instance.verbatim && !instance.value) {
620
914
  this.warningNotEvaluated(log, context);
621
915
  }
@@ -670,7 +964,8 @@ class Config {
670
964
  }
671
965
  }
672
966
 
673
- needsRebuild(template, instance, options = { rebuild: false }) {
967
+ // { rebuild: false, isModule: false }
968
+ needsRebuild(template, instance, options) {
674
969
  if (options.rebuild) {
675
970
  return true
676
971
  }
@@ -684,7 +979,103 @@ class Config {
684
979
  const instanceFragments = (instance.fragments || []).map((fragment) => fragment.key || fragment.query).map( toCanonical )
685
980
  const templateFragments = (template.fragments || []).concat(this.dynamicFragments).map( toCanonical )
686
981
  const sameFragments = helpers.safeEquals(templateFragments, instanceFragments)
687
- const sameQueries = helpers.safeEquals((template.queries || []).map(helpers.updateQueries), (instance.queries || []))
982
+ const toCanonicalQuery = (queryOrConfig) => {
983
+ if (typeof queryOrConfig == 'string') {
984
+ const query = queryOrConfig
985
+ return query
986
+ } else {
987
+ const config = { ...queryOrConfig }
988
+ delete config.where
989
+ config.operators = (config.operators || []).map( (operator) => {
990
+ if (typeof operator == 'string') {
991
+ return { pattern: operator }
992
+ } else {
993
+ operator = { ...operator }
994
+ delete operator.uuid
995
+ return operator
996
+ }
997
+ })
998
+ config.bridges = (config.bridges || []).map( (bridge) => {
999
+ bridge = { ...bridge },
1000
+ bridge.level = bridge.level || 0
1001
+ delete bridge.uuid
1002
+ return bridge
1003
+ })
1004
+ if (options.isModule) {
1005
+ // things like webpack rewrite the functions if there are constants so this compare does not work
1006
+ delete config.generators;
1007
+ delete config.semantics;
1008
+ config.bridges = (config.bridges || []).map((bridge) => {
1009
+ bridge = {...bridge}
1010
+ delete bridge.where
1011
+ delete bridge.generatorp
1012
+ delete bridge.generatorr
1013
+ delete bridge.generatorpr
1014
+ delete bridge.evaluator
1015
+ delete bridge.semantic
1016
+ return bridge
1017
+ });
1018
+ } else {
1019
+ config.generators = (config.generators || []).map((generator) => {
1020
+ generator = {...generator}
1021
+ delete generator.where
1022
+ generator.match = generator.match.toString()
1023
+ generator.apply = generator.apply.toString()
1024
+ return generator
1025
+ })
1026
+ config.semantics = (config.semantics || []).map((semantic) => {
1027
+ semantic = {...semantic}
1028
+ delete semantic.where
1029
+ semantic.match = semantic.match.toString()
1030
+ semantic.apply = semantic.apply.toString()
1031
+ return semantic
1032
+ })
1033
+ config.bridges = (config.bridges || []).map((bridge) => {
1034
+ bridge = {...bridge}
1035
+ delete bridge.where
1036
+ if (bridge.generatorp) {
1037
+ bridge.generatorp = bridge.generatorp.toString()
1038
+ }
1039
+ if (bridge.generatorr) {
1040
+ bridge.generatorr = bridge.generatorr.toString()
1041
+ }
1042
+ if (bridge.generatorpr) {
1043
+ bridge.generatorpr = bridge.generatorpr.toString()
1044
+ }
1045
+ if (bridge.evaluator) {
1046
+ bridge.evaluator = bridge.evaluator.toString()
1047
+ }
1048
+ if (bridge.semantic) {
1049
+ bridge.semantic = bridge.semantic.toString()
1050
+ }
1051
+ return bridge
1052
+ })
1053
+ }
1054
+ return config
1055
+ }
1056
+ }
1057
+ const toCanonicalQueries = (elements) => {
1058
+ return elements.map( toCanonicalQuery )
1059
+ }
1060
+
1061
+ const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
1062
+
1063
+ const debug = false
1064
+ if (debug) {
1065
+ if (!(instance && sameQueries && sameFragments)) {
1066
+ if (!sameQueries) {
1067
+ debugger
1068
+ debugger
1069
+ }
1070
+ console.log("instance", instance)
1071
+ console.log("sameQueries", sameQueries)
1072
+ console.log("sameFragments", sameFragments)
1073
+ console.log("templateFragments", templateFragments)
1074
+ console.log("instanceFragments", instanceFragments)
1075
+ console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
1076
+ console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
1077
+ }
1078
+ }
688
1079
  return !(instance && sameQueries && sameFragments)
689
1080
  }
690
1081
 
@@ -700,18 +1091,21 @@ class Config {
700
1091
  }
701
1092
  }
702
1093
 
1094
+ toData (data) {
1095
+ Object.assign(data, this.config)
1096
+ config_toServer(data)
1097
+ }
1098
+
1099
+ // loadTemplate
703
1100
  load (template, instance, options = { rebuild: false } ) {
704
1101
  this.validifyTemplate(template)
705
1102
  instance.template = template
706
1103
  this.logs.push(`loading template for ${this.name}`)
707
- if (instance && instance.associations && !options.rebuild) {
708
- this.addAssociations(instance.associations)
709
- }
710
1104
  if (options.rebuild) {
711
1105
  // TODO fix beforeQuery
712
1106
  template = { fragments: [], queries: [], ...template }
713
1107
  template.fragments = template.fragments.concat(this.dynamicFragments)
714
- client.build({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
1108
+ client.rebuildTemplate({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
715
1109
  } else {
716
1110
  // no change
717
1111
  // this.initInstances.push({ ...instance, name: config.name })
@@ -723,13 +1117,13 @@ class Config {
723
1117
  "semantics",
724
1118
  "associations",
725
1119
  ]
726
- return !properties.find( (property) => instance[property].length > 0 )
1120
+ return !properties.find( (property) => instance[property] && instance[property].length > 0 )
727
1121
  }
728
1122
  if (!isEmpty(instance)) {
729
1123
  instance.name = this.name
730
1124
  this.initInstances.push(instance)
731
1125
  this.instances.push(instance)
732
- client.processInstance(this, instance)
1126
+ client.loadInstance(this, instance)
733
1127
  }
734
1128
  }
735
1129
  }
@@ -743,19 +1137,15 @@ class Config {
743
1137
  return this.config.objects.namespaced[this._uuid]
744
1138
  }
745
1139
 
746
- addAssociationsFromTests(tests = []) {
747
- for (let test of tests) {
748
- this.addAssociations(test.associations || []);
749
- }
750
- }
751
-
752
-
753
1140
  addAssociations (associations) {
754
1141
  for (let association of associations) {
755
1142
  this.addAssociation(association)
756
1143
  }
757
1144
  }
758
1145
 
1146
+ debugConfig() {
1147
+ }
1148
+
759
1149
  addAssociation (association) {
760
1150
  if (!this.config.associations) {
761
1151
  this.config.associations = {
@@ -763,24 +1153,30 @@ class Config {
763
1153
  positive: []
764
1154
  }
765
1155
  }
766
- if (global.entodictonDebugAssociation) {
767
- if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
768
- debugger; // debug association hit
769
- }
770
- }
1156
+ debugAssociation(association)
771
1157
  this.config.associations.positive.push(association)
772
1158
  this._delta.json.associations.push({ action: 'add', association })
773
1159
  }
774
1160
 
775
1161
  // TODO add more error checking to these like addHierarchy has
776
- addPriorities (priorities) {
1162
+ // TODO change name from priorities to priority
1163
+ // [ context: <list of [id, level]>, choose: [<indexes of prioritized operator>], [ordered: [true|false]] ]
1164
+ addPriority (priority) {
777
1165
  if (!this.config.priorities) {
778
1166
  this.config.priorities = []
779
1167
  }
780
- this.config.priorities.push(priorities)
781
- this._delta.json.priorities.push({ action: 'add', priorities })
1168
+ debugPriority(priority)
1169
+ priority_valid(priority)
1170
+ this.config.priorities.push(priority)
1171
+ this._delta.json.priorities.push({ action: 'add', priority })
782
1172
  }
783
-
1173
+
1174
+ addPriorities (priorities) {
1175
+ for (let priority of priorities) {
1176
+ this.addPriority(priority)
1177
+ }
1178
+ }
1179
+
784
1180
  addHierarchy (child, parent) {
785
1181
  if (child && parent || !child || Array.isArray(child) || (typeof child == 'string' && !parent)) {
786
1182
  this.addHierarchyChildParent(child, parent)
@@ -793,16 +1189,12 @@ class Config {
793
1189
  addHierarchyProperties (edge) {
794
1190
  const { child, parent } = edge
795
1191
  if (typeof child !== 'string') {
796
- throw `addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`
1192
+ throw new Error(`addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`)
797
1193
  }
798
1194
  if (typeof parent !== 'string') {
799
- throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
800
- }
801
- if (global.entodictonDebugHierarchy) {
802
- if ((helpers.safeEquals.entodictonDebugHierarchy, [child, parent])) {
803
- debugger; // debug hierarchy hit
804
- }
1195
+ throw new Error(`addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`)
805
1196
  }
1197
+ debugHierarchy([child, parent])
806
1198
  this.config.hierarchy.push(edge)
807
1199
  // TODO greg11 this.hierarchy.addEdge(edge)
808
1200
  this._delta.json.hierarchy.push([child, parent])
@@ -810,18 +1202,12 @@ class Config {
810
1202
 
811
1203
  addHierarchyChildParent (child, parent) {
812
1204
  if (typeof child !== 'string') {
813
- throw `addHierarchy expected child to be a string. got ${JSON.stringify(child)}`
1205
+ throw new Error(`addHierarchy expected child to be a string. got ${JSON.stringify(child)}`)
814
1206
  }
815
1207
  if (typeof parent !== 'string') {
816
- throw `addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`
1208
+ throw new Error(`addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`)
817
1209
  }
818
-
819
- if (global.entodictonDebugHierarchy) {
820
- if (helpers.safeEquals(global.entodictonDebugHierarchy, [child, parent])) {
821
- debugger; // debug hierarchy hit
822
- }
823
- }
824
-
1210
+ debugHierarchy([child, parent])
825
1211
  if (this.config.hierarchy.find( (element) => {
826
1212
  const hc = hierarchyCanonical(element)
827
1213
  if (child == hc.child && parent == hc.parent) {
@@ -837,24 +1223,24 @@ class Config {
837
1223
  }
838
1224
 
839
1225
  getBridge (id, level) {
840
- return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1226
+ if (level) {
1227
+ return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1228
+ } else {
1229
+ return this.config.bridges.find( (bridge) => bridge.id == id)
1230
+ }
841
1231
  }
842
1232
 
843
- addBridge (bridge) {
1233
+ addBridge (bridge, uuid) {
844
1234
  if (!this.config.bridges) {
845
1235
  this.config.bridges = []
846
1236
  }
847
1237
  const bridges = this.config.bridges
848
- const def = Object.assign({}, bridge, { uuid: this._uuid })
849
-
850
- if (global.entodictonDebugBridge) {
851
- if (global.entodictonDebugBridge[0] == bridge.id && global.entodictonDebugBridge[1] == bridge.level) {
852
- debugger; // debug hierarchy hit
853
- }
854
- }
855
-
1238
+ const def = Object.assign({}, bridge, { uuid: uuid || this._uuid })
1239
+
1240
+ debugBridge(bridge)
856
1241
  if (bridge.allowDups) {
857
- if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1242
+ // if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1243
+ if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level)) {
858
1244
  return;
859
1245
  }
860
1246
  }
@@ -867,17 +1253,12 @@ class Config {
867
1253
  this._delta.json.bridges.push({ action: 'add', bridge: def })
868
1254
  }
869
1255
 
870
- addGenerator (match, apply) {
871
- let generator = match
872
- if ((typeof match === 'function') && (typeof apply === 'function')) {
873
- generator = { match, apply }
874
- }
875
-
1256
+ addGenerator (generator, uuid, name) {
876
1257
  if (!(typeof generator.match === 'function')) {
877
- throw 'addGenerator: Expected matcher to be a function'
1258
+ throw new Error('addGenerator: Expected matcher to be a function')
878
1259
  }
879
1260
  if (!(typeof generator.apply === 'function')) {
880
- throw 'addGenerator: Expected action to be a function'
1261
+ throw new Error('addGenerator: Expected action to be a function')
881
1262
  }
882
1263
 
883
1264
  if (!this.config.generators) {
@@ -889,22 +1270,18 @@ class Config {
889
1270
  }
890
1271
 
891
1272
  const generators = this.config.generators
892
- Object.assign(generator, { uuid: this._uuid, km: this.name, index: generators.length })
1273
+ Object.assign(generator, { uuid: uuid || this._uuid, km: name || this.name, index: generators.length })
893
1274
  // used to be unshift
894
1275
  generators.unshift(generator)
895
1276
  }
896
1277
 
897
- addSemantic (match, apply) {
898
- let semantic = match
899
- if ((typeof match === 'function') && (typeof apply === 'function')) {
900
- semantic = { match, apply }
901
- }
902
-
1278
+ addSemantic (semantic, uuid, name) {
903
1279
  if (!(typeof semantic.match === 'function')) {
904
- throw 'addSemantic: Expected match to be a function'
1280
+ throw new Error('addSemantic: Expected match to be a function')
905
1281
  }
1282
+
906
1283
  if (!(typeof semantic.apply === 'function')) {
907
- throw 'addSemantic: Expected apply to be a function'
1284
+ throw new Error('addSemantic: Expected apply to be a function')
908
1285
  }
909
1286
 
910
1287
  if (!this.config.semantics) {
@@ -916,11 +1293,18 @@ class Config {
916
1293
  }
917
1294
 
918
1295
  const semantics = this.config.semantics
919
- Object.assign(semantic, { uuid: this._uuid, km: this.name, index: semantics.length })
1296
+ Object.assign(semantic, { uuid: uuid || semantic.uuid || this._uuid, km: name || this.name, index: semantics.length, id: semantic.id || uuidv4() })
920
1297
  semantics.unshift(semantic)
921
1298
  }
922
1299
 
923
- addOperator (objectOrPattern) {
1300
+ removeSemantic(deleteSemantic) {
1301
+ const index = this.config.semantics.findIndex( (semantic) => semantic.id === deleteSemantic.id )
1302
+ if (index >= 0) {
1303
+ this.config.semantics.splice(index, 1)
1304
+ }
1305
+ }
1306
+
1307
+ addOperator (objectOrPattern, uuid) {
924
1308
  if (!this.config.operators) {
925
1309
  this.config.operators = []
926
1310
  }
@@ -929,16 +1313,12 @@ class Config {
929
1313
 
930
1314
  let operator;
931
1315
  if (typeof objectOrPattern === 'string') {
932
- operator = { pattern: objectOrPattern, uuid: this._uuid }
1316
+ operator = { pattern: objectOrPattern, uuid: uuid || this._uuid }
933
1317
  } else {
934
- operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
1318
+ operator = Object.assign({}, objectOrPattern, { uuid: uuid || this._uuid })
935
1319
  }
936
1320
 
937
- if (global.entodictonDebugOperator) {
938
- if (operator.pattern === global.entodictonDebugOperator) {
939
- debugger; // debug operator hit
940
- }
941
- }
1321
+ debugOperator(operator)
942
1322
 
943
1323
  if (operator.allowDups) {
944
1324
  if (operators.find( (o) => o.pattern == operator.pattern )) {
@@ -952,16 +1332,16 @@ class Config {
952
1332
  this._delta.json.operators.push({ action: 'add', operator })
953
1333
  }
954
1334
 
955
- addWord (word, def) {
956
- this.addWordInternal(word, def)
1335
+ addWord (word, def, uuid) {
1336
+ this.addWordInternal(word, def, uuid)
957
1337
  }
958
1338
 
959
- addWordInternal (word, def) {
1339
+ addWordInternal (word, def, uuid) {
960
1340
  if (!this.config.words) {
961
1341
  this.config.words = {}
962
1342
  }
963
1343
  const words = this.config.words
964
- def = Object.assign({}, def, { uuid: this._uuid })
1344
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
965
1345
  if (words[word]) {
966
1346
  if (!words[word].some((e) => helpers.safeEquals(e, def))) {
967
1347
  words[word].unshift(def)
@@ -1178,37 +1558,11 @@ class Config {
1178
1558
  // configs = [ { config, namespace } ... ]
1179
1559
  constructor (config, module) {
1180
1560
  if (config instanceof Config) {
1181
- throw 'Excepted the config argument to be a hash not a Config object'
1561
+ throw new Error('Excepted the config argument to be a hash not a Config object')
1182
1562
  }
1183
1563
 
1184
1564
  if (config) {
1185
- const valid = [
1186
- 'hierarchy',
1187
- 'objects',
1188
- 'bridges',
1189
- 'operators',
1190
- 'words',
1191
- 'priorities',
1192
- 'associations',
1193
- 'name',
1194
- 'version',
1195
- 'generators',
1196
- 'semantics',
1197
- 'floaters',
1198
- 'debug',
1199
-
1200
- // TODO Fix these from the test app
1201
- 'implicits',
1202
- 'convolution',
1203
- 'expected_generated',
1204
- 'expected_results',
1205
- 'skipSemantics',
1206
- 'description',
1207
- 'contexts',
1208
- 'utterances',
1209
- 'flatten',
1210
- ]
1211
- helpers.validProps(valid, config, 'config')
1565
+ validConfigProps(config)
1212
1566
 
1213
1567
  config.operators = config.operators || []
1214
1568
  config.bridges = config.bridges || []
@@ -1259,7 +1613,7 @@ class Config {
1259
1613
  }
1260
1614
  duplicated = Array.from(duplicated)
1261
1615
  if (duplicated.length > 0) {
1262
- throw `In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`
1616
+ throw new Error(`In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`)
1263
1617
  }
1264
1618
  }
1265
1619
 
@@ -1271,6 +1625,10 @@ class Config {
1271
1625
  }
1272
1626
  }
1273
1627
 
1628
+ if (config && config.priorities) {
1629
+ priorities_valid(config.priorities)
1630
+ }
1631
+
1274
1632
  normalizeConfig(config)
1275
1633
 
1276
1634
  // set the default server so stuff just works
@@ -1286,7 +1644,6 @@ class Config {
1286
1644
  if (config) {
1287
1645
  this.name = config.name
1288
1646
  }
1289
- this.motivations = []
1290
1647
  this.loadOrder = new DigraphInternal()
1291
1648
  this.wasInitialized = false
1292
1649
  this.configs = []
@@ -1311,6 +1668,7 @@ class Config {
1311
1668
  }
1312
1669
  this.get('objects').namespaced[this._uuid] = {}
1313
1670
  this.valid()
1671
+ debugConfigProps(this.config)
1314
1672
  }
1315
1673
 
1316
1674
  addArgs(moreArgs) {
@@ -1341,7 +1699,10 @@ class Config {
1341
1699
  }
1342
1700
 
1343
1701
  delta () {
1344
- return { cacheKey: this._delta.cacheKey, json: this._delta.json }
1702
+ return {
1703
+ cacheKey: this._delta.cacheKey,
1704
+ json: this._delta.json
1705
+ }
1345
1706
  }
1346
1707
 
1347
1708
  resetDelta (cacheKey) {
@@ -1374,24 +1735,26 @@ class Config {
1374
1735
  if (this._api && this._api.multiApi) {
1375
1736
  this._api.add(this, this._api, api)
1376
1737
  } else {
1377
- throw "Can only add apis to a multi-api";
1738
+ throw new Error("Can only add apis to a multi-api")
1378
1739
  }
1379
1740
  }
1380
1741
 
1381
1742
  set api (value) {
1382
1743
  if (!value.initialize) {
1383
- throw `Expected the API to have an initialize function for ${this.name}.`
1744
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
1384
1745
  }
1385
1746
 
1386
1747
  if (this._api && this._api.multiApi) {
1387
1748
  this._api.add(this, this._api, value)
1388
1749
  } else {
1389
1750
  this._api = _.cloneDeep(value)
1751
+ /*
1390
1752
  if (this._api) {
1391
- this._api.objects = this.config.objects
1392
- this._api.config = () => this
1393
- this._api.uuid = this._uuid
1753
+ // this._api.objects = this.config.objects
1754
+ // this._api.config = () => this
1755
+ // this._api.uuid = this._uuid
1394
1756
  }
1757
+ */
1395
1758
  this.rebuild()
1396
1759
  }
1397
1760
  }
@@ -1434,40 +1797,6 @@ class Config {
1434
1797
  // this.valid() init was not run because the kms are not all setup yet
1435
1798
  }
1436
1799
 
1437
- // motivation === { match, apply, uuid }
1438
- addMotivation (motivation) {
1439
- if (!motivation.uuid) {
1440
- motivation.uuid = this.uuid
1441
- }
1442
- this.motivations.push(motivation)
1443
- }
1444
-
1445
- resetMotivations () {
1446
- this.motivations = []
1447
- }
1448
-
1449
- doMotivations (args, context) {
1450
- args = Object.assign({}, args, { context })
1451
- // console.log('src/config doMotivations this.uuid', this.uuid)
1452
- // args.objects = args.getObjects(this.uuid)
1453
- const motivations = this.motivations
1454
- this.motivations = []
1455
- let done = false
1456
- for (const motivation of motivations) {
1457
- args.objects = args.getObjects(motivation.uuid)
1458
- if (!done && motivation.match(args)) {
1459
- motivation.apply(args)
1460
- if (args.context.controlKeepMotivation || motivation.repeat) {
1461
- this.motivations.push(motivation)
1462
- }
1463
- done = true
1464
- } else {
1465
- this.motivations.push(motivation)
1466
- }
1467
- }
1468
- return done
1469
- }
1470
-
1471
1800
  // TODO add more details
1472
1801
  equal(config) {
1473
1802
  if (JSON.stringify(this.config) != JSON.stringify(config.config)) {
@@ -1481,6 +1810,9 @@ class Config {
1481
1810
  runtime.fs.writeFileSync(fn, JSON.stringify(this.config, 0, 2))
1482
1811
  }
1483
1812
 
1813
+ copy (options = { callInitializers: true }) {
1814
+ }
1815
+
1484
1816
  copy (options = { callInitializers: true }) {
1485
1817
  this.valid()
1486
1818
  const cp = new Config()
@@ -1490,15 +1822,14 @@ class Config {
1490
1822
  cp.transitoryMode = this.transitoryMode
1491
1823
  cp.configs = this.configs.map((km) => km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
1492
1824
  cp._uuid = cp.configs[0]._uuid
1825
+ // update uuid here set the uuid in the objects and add error checking
1493
1826
  cp.initializerFn = this.initializerFn
1494
- cp.initAfterApi = this.initAfterApi
1495
1827
  cp._api = _.cloneDeep(this._api)
1496
1828
  cp._namespace = this._namespace
1497
1829
  cp._eqClasses = this._eqClasses
1498
1830
  cp.name = this.name
1499
1831
  cp.description = this.description
1500
1832
  cp.tests = this.tests
1501
- cp.motivations = [...this.motivations]
1502
1833
  cp.isModule = this.isModule
1503
1834
  cp.loadedForTesting = this.loadedForTesting
1504
1835
  cp.initInstances = this.initInstances.slice()
@@ -1523,25 +1854,38 @@ class Config {
1523
1854
  }
1524
1855
  cp.mapUUIDs(map)
1525
1856
 
1857
+ if (cp._uuid == 'concept2') {
1858
+ // debugger
1859
+ }
1526
1860
  if (options.callInitializers) {
1527
1861
  cp.rebuild(options)
1528
- }
1529
- if (cp._api) {
1530
- cp._api.objects = cp.config.objects
1531
- cp._api.config = () => (cp instanceof Config) ? cp : cp.config
1532
- cp._api.uuid = cp._uuid
1533
- }
1862
+ } else {
1863
+ // this mess is for duplicate into a KM after resetToOne was called
1864
+ /*
1865
+ if (cp._api) {
1866
+ // cp._api.objects = cp.config.objects
1867
+ // cp._api.config = () => (cp instanceof Config) ? cp : cp.config
1868
+ // cp._api.uuid = cp._uuid
1869
+ }
1870
+ */
1534
1871
 
1535
- if (!cp.config.objects) {
1536
- cp.config.objects = { namespaced: {} }
1537
- } else if (!cp.config.objects.namespaced) {
1538
- cp.config.objects.namespaced = {}
1872
+ if (!cp.config.objects) {
1873
+ cp.config.objects = { namespaced: {} }
1874
+ } else if (!cp.config.objects.namespaced) {
1875
+ cp.config.objects.namespaced = {}
1876
+ }
1877
+ cp.configs.forEach((km) => {
1878
+ // const namespace = km.namespace
1879
+ cp.config.objects.namespaced[km._uuid] = {}
1880
+ })
1881
+ /*
1882
+ if (cp._uuid == 'concept2') {
1883
+ if (!cp.api.objects.defaultTypesForHierarchy) {
1884
+ debugger
1885
+ }
1886
+ }
1887
+ */
1539
1888
  }
1540
- cp.configs.forEach((km) => {
1541
- // const namespace = km.namespace
1542
- cp.config.objects.namespaced[km._uuid] = {}
1543
- })
1544
-
1545
1889
  cp.valid()
1546
1890
  return cp
1547
1891
  }
@@ -1641,38 +1985,33 @@ class Config {
1641
1985
  }
1642
1986
  */
1643
1987
  const objects = {}
1644
- const km = (name) => this.getConfig(name)
1645
1988
  if (config instanceof Config) {
1646
- // const aw = addWord(this.config, config.uuid)
1647
- const aw = (word, def) => this.addWord(word, def)
1648
1989
  this.get('objects').namespaced[config._uuid] = objects
1990
+ /*
1649
1991
  if (config._api) {
1650
- config._api.objects = objects
1651
- config._api.config = () => this
1992
+ // config._api.objects = objects
1993
+ // config._api.config = () => this
1652
1994
  }
1653
- config.initializerFn({ addWord: aw, km, config, baseConfig: this, currentConfig: config, objects, namespace, uuid, api: config.api })
1995
+ */
1996
+ config.initializerFn(setupInitializerFNArgs(this, { testConfig: config, currentConfig: config, objects, namespace, uuid }))
1654
1997
  } else {
1655
- // const aw = addWord(this.config, this.uuid)
1656
- const aw = (word, def) => this.addWord(word, def)
1657
1998
  this.get('objects').namespaced[this._uuid] = objects
1999
+ /*
1658
2000
  if (config._api) {
1659
- config._api.objects = objects
1660
- config._api.config = () => this
2001
+ // config._api.objects = objects
2002
+ // config._api.config = () => this
1661
2003
  }
1662
- this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects, namespace, uuid, api: this.api })
2004
+ */
2005
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, namespace, uuid }))
1663
2006
  }
1664
2007
  })
1665
- this.instances.forEach((instance) => client.processInstance(this, instance))
2008
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
1666
2009
  }
1667
2010
 
1668
2011
  initialize ({ force = true } = {}) {
1669
2012
  if (force || !this.wasInitialized) {
1670
- // const aw = addWord(this.config, this.uuid)
1671
- const aw = (word, def) => this.addWord(word, def)
1672
- const km = (name) => this.getConfig(name)
1673
- // this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects: this.get('objects'), uuid: this._uuid, namespace: '', api: this.api })
1674
2013
  const objects = this.config.objects.namespaced[this._uuid]
1675
- this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '', api: this.api })
2014
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '' }))
1676
2015
  this.wasInitialized = true
1677
2016
  }
1678
2017
  }
@@ -1680,29 +2019,22 @@ class Config {
1680
2019
  initializer (fn, options = {}) {
1681
2020
  if (options) {
1682
2021
  for (let option of Object.keys(options)) {
1683
- const validOptions = ['initAfterApi']
1684
- if (!['initAfterApi'].includes(option)) {
1685
- throw `For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`
2022
+ const validOptions = []
2023
+ if (!validOptions.includes(option)) {
2024
+ throw new Error(`For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`)
1686
2025
  }
1687
2026
  }
1688
2027
  }
1689
- const { initAfterApi = false } = options;
1690
2028
  this.wasInitialized = false
1691
- this.initAfterApi = initAfterApi
1692
- this.initializerFn = (args) => {
2029
+ this.initializerFn = (args, { dontCallFn } = {}) => {
1693
2030
  const transitoryMode = global.transitoryMode
1694
2031
  global.transitoryMode = false
1695
2032
  // const baseConfig = args.baseConfig
1696
2033
  const currentConfig = args.currentConfig
1697
2034
 
1698
- if (currentConfig.api) {
1699
- currentConfig.api.objects = args.objects
1700
- // GREG42 currentConfig.api.config = () => this
1701
- currentConfig.api.config = () => args.baseConfig
1702
- currentConfig.api.uuid = currentConfig._uuid
2035
+ if (args.isAfterApi) {
2036
+ fn(args)
1703
2037
  }
1704
- // this.instances.forEach( (instance) => client.processInstance(this, instance) )
1705
- fn(args)
1706
2038
  currentConfig.wasInitialized = true
1707
2039
  global.transitoryMode = transitoryMode
1708
2040
  }
@@ -1869,7 +2201,6 @@ class Config {
1869
2201
  }
1870
2202
  this.config.objects.namespaced = {}
1871
2203
  this.resetWasInitialized()
1872
- this.resetMotivations()
1873
2204
 
1874
2205
  // reorder configs base on load ordering
1875
2206
  {
@@ -1895,8 +2226,8 @@ class Config {
1895
2226
  this.config.objects.namespaced[km._uuid] = {}
1896
2227
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
1897
2228
  this.setupNamespace(km)
1898
- // const aw = addWord(km.config.config ? km.config.config : km.config, km.config.uuid)
1899
- const aw = (word, def) => this.addWord(word, def)
2229
+ // const aw = (word, def) => this.addWord(word, def)
2230
+ // const ag = (matchOrGenerator, applyOrNothing) => this.addGenerator(matchOrGenerator, applyOrNothing)
1900
2231
  let config = km.config
1901
2232
 
1902
2233
  if (config.addedArgss) {
@@ -1917,32 +2248,51 @@ class Config {
1917
2248
  }
1918
2249
  config.wasInitialized = false
1919
2250
  // TODO change name of config: to baseConfig:
1920
- const kmFn = (name) => this.getConfig(name)
2251
+ const kmFn = (name) => {
2252
+ const config = this.getConfig(name)
2253
+ return config
2254
+ }
1921
2255
  // const hierarchy = new DigraphInternal((config.config || {}).hierarchy)
1922
- const args = { isModule, addWord: aw, km: kmFn, hierarchy: this.hierarchy, config, baseConfig: this, currentConfig: config, uuid: config._uuid, objects: namespacedObjects, namespace, api: config.api }
1923
- config.initializerFn(args)
1924
- if (config.initAfterApi) {
1925
- // reverse the list
1926
- initAfterApis.unshift({ config, args })
1927
- } else {
1928
- if (interleaved) {
1929
- initAfterApis.unshift(null)
1930
- }
2256
+ const args = new Object(setupInitializerFNArgs(this, {
2257
+ isModule,
2258
+ hierarchy: this.hierarchy,
2259
+ testConfig: config,
2260
+ currentConfig: config,
2261
+ uuid: config._uuid,
2262
+ objects: namespacedObjects,
2263
+ namespace,
2264
+ api: config.api,
2265
+ }))
2266
+
2267
+ const currentConfig = args.currentConfig
2268
+
2269
+ /*
2270
+ if (args.currentConfig.api) {
2271
+ // args.currentConfig.api.objects = args.objects
2272
+ // TODO assign pseudo config?
2273
+ // args.currentConfig.api.config = () => args.baseConfig
2274
+ // args.currentConfig.api.uuid = args.currentConfig._uuid
2275
+ args.currentConfig.wasInitialized = true
1931
2276
  }
1932
- // greg
2277
+ */
2278
+ // debugger
2279
+ // greg55
2280
+ config.initializerFn(args, { dontCallFn: true })
2281
+ initAfterApis.unshift({ config, args })
1933
2282
  if (config._api) {
1934
2283
  if (config._api.initialize) {
1935
2284
  // reverse the list
1936
- inits.unshift( () => config._api.initialize({ config: this, km: kmFn, api: config._api }) )
2285
+ // TODO sync up the args with initialize of config
2286
+ inits.unshift( () => config._api.initialize({ config: this, km: kmFn, ...args, api: config._api }) )
1937
2287
  // config._api.initialize({ config, api: config._api })
1938
2288
  } else {
1939
2289
  if (interleaved) {
1940
2290
  inits.unshift(null)
1941
2291
  }
1942
2292
  }
1943
- config._api.objects = namespacedObjects
1944
- config._api.config = () => this
1945
- config._api.uuid = config._uuid
2293
+ // config._api.objects = namespacedObjects
2294
+ // config._api.config = () => this
2295
+ // config._api.uuid = config._uuid
1946
2296
  } else {
1947
2297
  if (interleaved) {
1948
2298
  inits.unshift(null)
@@ -1984,10 +2334,9 @@ class Config {
1984
2334
  init()
1985
2335
  }
1986
2336
  for (let init of initAfterApis) {
1987
- // init.args.isAfterApi = true
1988
2337
  init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
1989
2338
  }
1990
- this.instances.forEach((instance) => client.processInstance(this, instance))
2339
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
1991
2340
  } else {
1992
2341
  const base = {
1993
2342
  operators: this.config.operators,
@@ -2016,19 +2365,19 @@ class Config {
2016
2365
  }
2017
2366
  // console.log('name -------------', name)
2018
2367
  if (inits[i]) {
2368
+ // greg55
2019
2369
  inits[i]()
2020
2370
  }
2021
2371
  if (initAfterApis[i]) {
2022
2372
  const init = initAfterApis[i]
2023
- init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
2373
+ init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true})
2024
2374
  }
2025
2375
  const instance = this.instances.find((instance) => instance.name == name)
2026
2376
  if (instance) {
2027
- client.processInstance(this, instance)
2377
+ client.loadInstance(this, instance)
2028
2378
  }
2029
2379
  this.hierarchy.edges = this.config.hierarchy
2030
2380
  }
2031
- // this.instances.forEach((instance) => client.processInstance(this, instance))
2032
2381
  }
2033
2382
 
2034
2383
  if (reverseIt) {
@@ -2151,13 +2500,9 @@ class Config {
2151
2500
  }
2152
2501
  const km = (name) => this.getConfig(name)
2153
2502
  if (config instanceof Config) {
2154
- // const aw = addWord(this.config, config.uuid)
2155
- const aw = (word, def) => this.addWord(word, def)
2156
- config.initializerFn({ isModule: this.isModule, addWord: aw, baseConfig: this, km, currentConfig: config, config, objects: nsobjects, namespace, uuid, api: config.api })
2503
+ config.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: config, testConfig: config, objects: nsobjects, namespace, uuid }))
2157
2504
  } else {
2158
- // const aw = addWord(this.config, this.uuid)
2159
- const aw = (word, def) => this.addWord(word, def)
2160
- this.initializerFn({ isModule: this.isModule, addWord: aw, baseConfig: this, km, currentConfig: this, config: this, objects: nsobjects, namespace, uuid, api: this.api })
2505
+ this.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: this, testConfig: this, objects: nsobjects, namespace, uuid }))
2161
2506
  }
2162
2507
  })
2163
2508
  }
@@ -2214,10 +2559,18 @@ class Config {
2214
2559
 
2215
2560
  if (config.priorities) {
2216
2561
  let priorities = config.priorities
2217
- priorities = priorities.map((p) => {
2218
- return p.map((id) => {
2219
- return [toNS(id[0]), id[1]]
2220
- })
2562
+ priorities = priorities.map((cp) => {
2563
+ const { context, choose, ordered } = cp
2564
+ const priority = {
2565
+ context: context.map((id) => {
2566
+ return [toNS(id[0]), id[1]]
2567
+ }),
2568
+ choose,
2569
+ }
2570
+ if (ordered) {
2571
+ priority.ordered = ordered
2572
+ }
2573
+ return priority
2221
2574
  })
2222
2575
  config.priorities = priorities
2223
2576
  }
@@ -2307,14 +2660,14 @@ class Config {
2307
2660
 
2308
2661
  set (property, value) {
2309
2662
  if (!this.config.hasOwnProperty(property)) {
2310
- throw `Setting invalid property ${property}`
2663
+ throw new Error(`Setting invalid property ${property}`)
2311
2664
  }
2312
2665
 
2313
2666
  if ('words' == property) {
2314
2667
  for (let word in value) {
2315
2668
  for (let def of value[word]) {
2316
2669
  if (!def['uuid']) {
2317
- throw `All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)} for the word '${word}'`
2670
+ throw new Error(`All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)} for the word '${word}'`)
2318
2671
  }
2319
2672
  }
2320
2673
  }
@@ -2323,7 +2676,7 @@ class Config {
2323
2676
  if (['operators', 'bridges'].includes(property)) {
2324
2677
  for (let def of value) {
2325
2678
  if (!def['uuid']) {
2326
- throw `All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`
2679
+ throw new Error(`All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`)
2327
2680
  }
2328
2681
  }
2329
2682
  }
@@ -2355,7 +2708,7 @@ class Config {
2355
2708
 
2356
2709
  add (more) {
2357
2710
  if (more === this) {
2358
- throw 'Cannot add an object to itself.'
2711
+ throw new Error('Cannot add an object to itself.')
2359
2712
  }
2360
2713
  if (!(more instanceof Config)) {
2361
2714
  more = new Config(more)
@@ -2416,7 +2769,8 @@ class Config {
2416
2769
  }
2417
2770
 
2418
2771
  // TODO get rid of useOldVersion arg
2419
- addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2772
+ addInternal (more, { addFirst = false, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2773
+ validConfigProps(more)
2420
2774
  if (more instanceof Config) {
2421
2775
  more.initialize({ force: false })
2422
2776
  if (useOldVersion) {
@@ -2426,8 +2780,10 @@ class Config {
2426
2780
  more = _.cloneDeep(more.initConfig)
2427
2781
  }
2428
2782
  }
2783
+ debugConfigProps(more)
2784
+
2429
2785
  if (hcps) {
2430
- handleCalculatedProps(this, more)
2786
+ handleCalculatedProps(this, more, addFirst)
2431
2787
  applyUUID(more, this._uuid)
2432
2788
  }
2433
2789
  for (const key of Object.keys(more)) {
@@ -2452,7 +2808,11 @@ class Config {
2452
2808
  if (!configWords[word]) {
2453
2809
  configWords[word] = []
2454
2810
  }
2455
- configWords[word] = configWords[word].concat(moreWords[word])
2811
+ if (addFirst) {
2812
+ configWords[word] = moreWords[word].concat(configWords[word])
2813
+ } else {
2814
+ configWords[word] = configWords[word].concat(moreWords[word])
2815
+ }
2456
2816
  }
2457
2817
  } else if (key === 'name') {
2458
2818
  /*
@@ -2514,16 +2874,21 @@ class Config {
2514
2874
  this.config[key].splice(iOldOne, 1)
2515
2875
  break;
2516
2876
  }
2517
- }
2877
+ }
2518
2878
  }
2519
2879
  }
2520
2880
  }
2881
+
2521
2882
  // console.log('key', key, 'XXX')
2522
2883
  // console.log('more', JSON.stringify(more, null, 2))
2523
- this.config[key] = this.config[key].concat(more[key])
2884
+ if (addFirst) {
2885
+ this.config[key] = more[key].concat(this.config[key])
2886
+ } else {
2887
+ this.config[key] = this.config[key].concat(more[key])
2888
+ }
2524
2889
  } else {
2525
2890
  if (!(key in this.config)) {
2526
- throw `Unexpected property in config ${key}`
2891
+ throw new Error(`Unexpected property in config ${key}`)
2527
2892
  }
2528
2893
  this.config[key] = more[key]
2529
2894
  }
@@ -2641,7 +3006,7 @@ class Config {
2641
3006
  this.config[key] = more[key].concat(this.config[key])
2642
3007
  } else {
2643
3008
  if (!(key in this.config)) {
2644
- throw `Unexpected property in config ${key}`
3009
+ throw new Error(`Unexpected property in config ${key}`)
2645
3010
  }
2646
3011
  this.config[key] = more[key]
2647
3012
  }
@@ -2651,5 +3016,8 @@ class Config {
2651
3016
  }
2652
3017
 
2653
3018
  module.exports = {
2654
- Config
3019
+ Config,
3020
+ config_toServer,
3021
+ operatorKey_valid,
3022
+ handleBridgeProps,
2655
3023
  }