theprogrammablemind 7.5.8 → 7.6.0-beta.1

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/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
  }