theprogrammablemind 7.5.8 → 7.6.0

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
  }
@@ -749,13 +1143,15 @@ class Config {
749
1143
  }
750
1144
  }
751
1145
 
752
-
753
1146
  addAssociations (associations) {
754
1147
  for (let association of associations) {
755
1148
  this.addAssociation(association)
756
1149
  }
757
1150
  }
758
1151
 
1152
+ debugConfig() {
1153
+ }
1154
+
759
1155
  addAssociation (association) {
760
1156
  if (!this.config.associations) {
761
1157
  this.config.associations = {
@@ -763,24 +1159,30 @@ class Config {
763
1159
  positive: []
764
1160
  }
765
1161
  }
766
- if (global.entodictonDebugAssociation) {
767
- if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
768
- debugger; // debug association hit
769
- }
770
- }
1162
+ debugAssociation(association)
771
1163
  this.config.associations.positive.push(association)
772
1164
  this._delta.json.associations.push({ action: 'add', association })
773
1165
  }
774
1166
 
775
1167
  // TODO add more error checking to these like addHierarchy has
776
- addPriorities (priorities) {
1168
+ // TODO change name from priorities to priority
1169
+ // [ context: <list of [id, level]>, choose: [<indexes of prioritized operator>], [ordered: [true|false]] ]
1170
+ addPriority (priority) {
777
1171
  if (!this.config.priorities) {
778
1172
  this.config.priorities = []
779
1173
  }
780
- this.config.priorities.push(priorities)
781
- this._delta.json.priorities.push({ action: 'add', priorities })
1174
+ debugPriority(priority)
1175
+ priority_valid(priority)
1176
+ this.config.priorities.push(priority)
1177
+ this._delta.json.priorities.push({ action: 'add', priority })
782
1178
  }
783
-
1179
+
1180
+ addPriorities (priorities) {
1181
+ for (let priority of priorities) {
1182
+ this.addPriority(priority)
1183
+ }
1184
+ }
1185
+
784
1186
  addHierarchy (child, parent) {
785
1187
  if (child && parent || !child || Array.isArray(child) || (typeof child == 'string' && !parent)) {
786
1188
  this.addHierarchyChildParent(child, parent)
@@ -793,16 +1195,12 @@ class Config {
793
1195
  addHierarchyProperties (edge) {
794
1196
  const { child, parent } = edge
795
1197
  if (typeof child !== 'string') {
796
- throw `addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`
1198
+ throw new Error(`addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`)
797
1199
  }
798
1200
  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
- }
1201
+ throw new Error(`addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`)
805
1202
  }
1203
+ debugHierarchy([child, parent])
806
1204
  this.config.hierarchy.push(edge)
807
1205
  // TODO greg11 this.hierarchy.addEdge(edge)
808
1206
  this._delta.json.hierarchy.push([child, parent])
@@ -810,18 +1208,12 @@ class Config {
810
1208
 
811
1209
  addHierarchyChildParent (child, parent) {
812
1210
  if (typeof child !== 'string') {
813
- throw `addHierarchy expected child to be a string. got ${JSON.stringify(child)}`
1211
+ throw new Error(`addHierarchy expected child to be a string. got ${JSON.stringify(child)}`)
814
1212
  }
815
1213
  if (typeof parent !== 'string') {
816
- throw `addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`
1214
+ throw new Error(`addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`)
817
1215
  }
818
-
819
- if (global.entodictonDebugHierarchy) {
820
- if (helpers.safeEquals(global.entodictonDebugHierarchy, [child, parent])) {
821
- debugger; // debug hierarchy hit
822
- }
823
- }
824
-
1216
+ debugHierarchy([child, parent])
825
1217
  if (this.config.hierarchy.find( (element) => {
826
1218
  const hc = hierarchyCanonical(element)
827
1219
  if (child == hc.child && parent == hc.parent) {
@@ -837,24 +1229,24 @@ class Config {
837
1229
  }
838
1230
 
839
1231
  getBridge (id, level) {
840
- return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1232
+ if (level) {
1233
+ return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1234
+ } else {
1235
+ return this.config.bridges.find( (bridge) => bridge.id == id)
1236
+ }
841
1237
  }
842
1238
 
843
- addBridge (bridge) {
1239
+ addBridge (bridge, uuid) {
844
1240
  if (!this.config.bridges) {
845
1241
  this.config.bridges = []
846
1242
  }
847
1243
  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
-
1244
+ const def = Object.assign({}, bridge, { uuid: uuid || this._uuid })
1245
+
1246
+ debugBridge(bridge)
856
1247
  if (bridge.allowDups) {
857
- if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1248
+ // if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1249
+ if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level)) {
858
1250
  return;
859
1251
  }
860
1252
  }
@@ -867,17 +1259,12 @@ class Config {
867
1259
  this._delta.json.bridges.push({ action: 'add', bridge: def })
868
1260
  }
869
1261
 
870
- addGenerator (match, apply) {
871
- let generator = match
872
- if ((typeof match === 'function') && (typeof apply === 'function')) {
873
- generator = { match, apply }
874
- }
875
-
1262
+ addGenerator (generator, uuid, name) {
876
1263
  if (!(typeof generator.match === 'function')) {
877
- throw 'addGenerator: Expected matcher to be a function'
1264
+ throw new Error('addGenerator: Expected matcher to be a function')
878
1265
  }
879
1266
  if (!(typeof generator.apply === 'function')) {
880
- throw 'addGenerator: Expected action to be a function'
1267
+ throw new Error('addGenerator: Expected action to be a function')
881
1268
  }
882
1269
 
883
1270
  if (!this.config.generators) {
@@ -889,22 +1276,18 @@ class Config {
889
1276
  }
890
1277
 
891
1278
  const generators = this.config.generators
892
- Object.assign(generator, { uuid: this._uuid, km: this.name, index: generators.length })
1279
+ Object.assign(generator, { uuid: uuid || this._uuid, km: name || this.name, index: generators.length })
893
1280
  // used to be unshift
894
1281
  generators.unshift(generator)
895
1282
  }
896
1283
 
897
- addSemantic (match, apply) {
898
- let semantic = match
899
- if ((typeof match === 'function') && (typeof apply === 'function')) {
900
- semantic = { match, apply }
901
- }
902
-
1284
+ addSemantic (semantic, uuid, name) {
903
1285
  if (!(typeof semantic.match === 'function')) {
904
- throw 'addSemantic: Expected match to be a function'
1286
+ throw new Error('addSemantic: Expected match to be a function')
905
1287
  }
1288
+
906
1289
  if (!(typeof semantic.apply === 'function')) {
907
- throw 'addSemantic: Expected apply to be a function'
1290
+ throw new Error('addSemantic: Expected apply to be a function')
908
1291
  }
909
1292
 
910
1293
  if (!this.config.semantics) {
@@ -916,11 +1299,18 @@ class Config {
916
1299
  }
917
1300
 
918
1301
  const semantics = this.config.semantics
919
- Object.assign(semantic, { uuid: this._uuid, km: this.name, index: semantics.length })
1302
+ Object.assign(semantic, { uuid: uuid || semantic.uuid || this._uuid, km: name || this.name, index: semantics.length, id: semantic.id || uuidv4() })
920
1303
  semantics.unshift(semantic)
921
1304
  }
922
1305
 
923
- addOperator (objectOrPattern) {
1306
+ removeSemantic(deleteSemantic) {
1307
+ const index = this.config.semantics.findIndex( (semantic) => semantic.id === deleteSemantic.id )
1308
+ if (index >= 0) {
1309
+ this.config.semantics.splice(index, 1)
1310
+ }
1311
+ }
1312
+
1313
+ addOperator (objectOrPattern, uuid) {
924
1314
  if (!this.config.operators) {
925
1315
  this.config.operators = []
926
1316
  }
@@ -929,16 +1319,12 @@ class Config {
929
1319
 
930
1320
  let operator;
931
1321
  if (typeof objectOrPattern === 'string') {
932
- operator = { pattern: objectOrPattern, uuid: this._uuid }
1322
+ operator = { pattern: objectOrPattern, uuid: uuid || this._uuid }
933
1323
  } else {
934
- operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
1324
+ operator = Object.assign({}, objectOrPattern, { uuid: uuid || this._uuid })
935
1325
  }
936
1326
 
937
- if (global.entodictonDebugOperator) {
938
- if (operator.pattern === global.entodictonDebugOperator) {
939
- debugger; // debug operator hit
940
- }
941
- }
1327
+ debugOperator(operator)
942
1328
 
943
1329
  if (operator.allowDups) {
944
1330
  if (operators.find( (o) => o.pattern == operator.pattern )) {
@@ -952,16 +1338,16 @@ class Config {
952
1338
  this._delta.json.operators.push({ action: 'add', operator })
953
1339
  }
954
1340
 
955
- addWord (word, def) {
956
- this.addWordInternal(word, def)
1341
+ addWord (word, def, uuid) {
1342
+ this.addWordInternal(word, def, uuid)
957
1343
  }
958
1344
 
959
- addWordInternal (word, def) {
1345
+ addWordInternal (word, def, uuid) {
960
1346
  if (!this.config.words) {
961
1347
  this.config.words = {}
962
1348
  }
963
1349
  const words = this.config.words
964
- def = Object.assign({}, def, { uuid: this._uuid })
1350
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
965
1351
  if (words[word]) {
966
1352
  if (!words[word].some((e) => helpers.safeEquals(e, def))) {
967
1353
  words[word].unshift(def)
@@ -1178,37 +1564,11 @@ class Config {
1178
1564
  // configs = [ { config, namespace } ... ]
1179
1565
  constructor (config, module) {
1180
1566
  if (config instanceof Config) {
1181
- throw 'Excepted the config argument to be a hash not a Config object'
1567
+ throw new Error('Excepted the config argument to be a hash not a Config object')
1182
1568
  }
1183
1569
 
1184
1570
  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')
1571
+ validConfigProps(config)
1212
1572
 
1213
1573
  config.operators = config.operators || []
1214
1574
  config.bridges = config.bridges || []
@@ -1259,7 +1619,7 @@ class Config {
1259
1619
  }
1260
1620
  duplicated = Array.from(duplicated)
1261
1621
  if (duplicated.length > 0) {
1262
- throw `In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`
1622
+ throw new Error(`In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`)
1263
1623
  }
1264
1624
  }
1265
1625
 
@@ -1271,6 +1631,10 @@ class Config {
1271
1631
  }
1272
1632
  }
1273
1633
 
1634
+ if (config && config.priorities) {
1635
+ priorities_valid(config.priorities)
1636
+ }
1637
+
1274
1638
  normalizeConfig(config)
1275
1639
 
1276
1640
  // set the default server so stuff just works
@@ -1286,7 +1650,6 @@ class Config {
1286
1650
  if (config) {
1287
1651
  this.name = config.name
1288
1652
  }
1289
- this.motivations = []
1290
1653
  this.loadOrder = new DigraphInternal()
1291
1654
  this.wasInitialized = false
1292
1655
  this.configs = []
@@ -1311,6 +1674,7 @@ class Config {
1311
1674
  }
1312
1675
  this.get('objects').namespaced[this._uuid] = {}
1313
1676
  this.valid()
1677
+ debugConfigProps(this.config)
1314
1678
  }
1315
1679
 
1316
1680
  addArgs(moreArgs) {
@@ -1341,7 +1705,10 @@ class Config {
1341
1705
  }
1342
1706
 
1343
1707
  delta () {
1344
- return { cacheKey: this._delta.cacheKey, json: this._delta.json }
1708
+ return {
1709
+ cacheKey: this._delta.cacheKey,
1710
+ json: this._delta.json
1711
+ }
1345
1712
  }
1346
1713
 
1347
1714
  resetDelta (cacheKey) {
@@ -1374,24 +1741,26 @@ class Config {
1374
1741
  if (this._api && this._api.multiApi) {
1375
1742
  this._api.add(this, this._api, api)
1376
1743
  } else {
1377
- throw "Can only add apis to a multi-api";
1744
+ throw new Error("Can only add apis to a multi-api")
1378
1745
  }
1379
1746
  }
1380
1747
 
1381
1748
  set api (value) {
1382
1749
  if (!value.initialize) {
1383
- throw `Expected the API to have an initialize function for ${this.name}.`
1750
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
1384
1751
  }
1385
1752
 
1386
1753
  if (this._api && this._api.multiApi) {
1387
1754
  this._api.add(this, this._api, value)
1388
1755
  } else {
1389
1756
  this._api = _.cloneDeep(value)
1757
+ /*
1390
1758
  if (this._api) {
1391
- this._api.objects = this.config.objects
1392
- this._api.config = () => this
1393
- this._api.uuid = this._uuid
1759
+ // this._api.objects = this.config.objects
1760
+ // this._api.config = () => this
1761
+ // this._api.uuid = this._uuid
1394
1762
  }
1763
+ */
1395
1764
  this.rebuild()
1396
1765
  }
1397
1766
  }
@@ -1434,40 +1803,6 @@ class Config {
1434
1803
  // this.valid() init was not run because the kms are not all setup yet
1435
1804
  }
1436
1805
 
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
1806
  // TODO add more details
1472
1807
  equal(config) {
1473
1808
  if (JSON.stringify(this.config) != JSON.stringify(config.config)) {
@@ -1481,6 +1816,9 @@ class Config {
1481
1816
  runtime.fs.writeFileSync(fn, JSON.stringify(this.config, 0, 2))
1482
1817
  }
1483
1818
 
1819
+ copy (options = { callInitializers: true }) {
1820
+ }
1821
+
1484
1822
  copy (options = { callInitializers: true }) {
1485
1823
  this.valid()
1486
1824
  const cp = new Config()
@@ -1490,15 +1828,14 @@ class Config {
1490
1828
  cp.transitoryMode = this.transitoryMode
1491
1829
  cp.configs = this.configs.map((km) => km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
1492
1830
  cp._uuid = cp.configs[0]._uuid
1831
+ // update uuid here set the uuid in the objects and add error checking
1493
1832
  cp.initializerFn = this.initializerFn
1494
- cp.initAfterApi = this.initAfterApi
1495
1833
  cp._api = _.cloneDeep(this._api)
1496
1834
  cp._namespace = this._namespace
1497
1835
  cp._eqClasses = this._eqClasses
1498
1836
  cp.name = this.name
1499
1837
  cp.description = this.description
1500
1838
  cp.tests = this.tests
1501
- cp.motivations = [...this.motivations]
1502
1839
  cp.isModule = this.isModule
1503
1840
  cp.loadedForTesting = this.loadedForTesting
1504
1841
  cp.initInstances = this.initInstances.slice()
@@ -1523,25 +1860,38 @@ class Config {
1523
1860
  }
1524
1861
  cp.mapUUIDs(map)
1525
1862
 
1863
+ if (cp._uuid == 'concept2') {
1864
+ // debugger
1865
+ }
1526
1866
  if (options.callInitializers) {
1527
1867
  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
- }
1868
+ } else {
1869
+ // this mess is for duplicate into a KM after resetToOne was called
1870
+ /*
1871
+ if (cp._api) {
1872
+ // cp._api.objects = cp.config.objects
1873
+ // cp._api.config = () => (cp instanceof Config) ? cp : cp.config
1874
+ // cp._api.uuid = cp._uuid
1875
+ }
1876
+ */
1534
1877
 
1535
- if (!cp.config.objects) {
1536
- cp.config.objects = { namespaced: {} }
1537
- } else if (!cp.config.objects.namespaced) {
1538
- cp.config.objects.namespaced = {}
1878
+ if (!cp.config.objects) {
1879
+ cp.config.objects = { namespaced: {} }
1880
+ } else if (!cp.config.objects.namespaced) {
1881
+ cp.config.objects.namespaced = {}
1882
+ }
1883
+ cp.configs.forEach((km) => {
1884
+ // const namespace = km.namespace
1885
+ cp.config.objects.namespaced[km._uuid] = {}
1886
+ })
1887
+ /*
1888
+ if (cp._uuid == 'concept2') {
1889
+ if (!cp.api.objects.defaultTypesForHierarchy) {
1890
+ debugger
1891
+ }
1892
+ }
1893
+ */
1539
1894
  }
1540
- cp.configs.forEach((km) => {
1541
- // const namespace = km.namespace
1542
- cp.config.objects.namespaced[km._uuid] = {}
1543
- })
1544
-
1545
1895
  cp.valid()
1546
1896
  return cp
1547
1897
  }
@@ -1641,38 +1991,33 @@ class Config {
1641
1991
  }
1642
1992
  */
1643
1993
  const objects = {}
1644
- const km = (name) => this.getConfig(name)
1645
1994
  if (config instanceof Config) {
1646
- // const aw = addWord(this.config, config.uuid)
1647
- const aw = (word, def) => this.addWord(word, def)
1648
1995
  this.get('objects').namespaced[config._uuid] = objects
1996
+ /*
1649
1997
  if (config._api) {
1650
- config._api.objects = objects
1651
- config._api.config = () => this
1998
+ // config._api.objects = objects
1999
+ // config._api.config = () => this
1652
2000
  }
1653
- config.initializerFn({ addWord: aw, km, config, baseConfig: this, currentConfig: config, objects, namespace, uuid, api: config.api })
2001
+ */
2002
+ config.initializerFn(setupInitializerFNArgs(this, { testConfig: config, currentConfig: config, objects, namespace, uuid }))
1654
2003
  } else {
1655
- // const aw = addWord(this.config, this.uuid)
1656
- const aw = (word, def) => this.addWord(word, def)
1657
2004
  this.get('objects').namespaced[this._uuid] = objects
2005
+ /*
1658
2006
  if (config._api) {
1659
- config._api.objects = objects
1660
- config._api.config = () => this
2007
+ // config._api.objects = objects
2008
+ // config._api.config = () => this
1661
2009
  }
1662
- this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects, namespace, uuid, api: this.api })
2010
+ */
2011
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, namespace, uuid }))
1663
2012
  }
1664
2013
  })
1665
- this.instances.forEach((instance) => client.processInstance(this, instance))
2014
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
1666
2015
  }
1667
2016
 
1668
2017
  initialize ({ force = true } = {}) {
1669
2018
  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
2019
  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 })
2020
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '' }))
1676
2021
  this.wasInitialized = true
1677
2022
  }
1678
2023
  }
@@ -1680,29 +2025,22 @@ class Config {
1680
2025
  initializer (fn, options = {}) {
1681
2026
  if (options) {
1682
2027
  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}`
2028
+ const validOptions = []
2029
+ if (!validOptions.includes(option)) {
2030
+ throw new Error(`For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`)
1686
2031
  }
1687
2032
  }
1688
2033
  }
1689
- const { initAfterApi = false } = options;
1690
2034
  this.wasInitialized = false
1691
- this.initAfterApi = initAfterApi
1692
- this.initializerFn = (args) => {
2035
+ this.initializerFn = (args, { dontCallFn } = {}) => {
1693
2036
  const transitoryMode = global.transitoryMode
1694
2037
  global.transitoryMode = false
1695
2038
  // const baseConfig = args.baseConfig
1696
2039
  const currentConfig = args.currentConfig
1697
2040
 
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
2041
+ if (args.isAfterApi) {
2042
+ fn(args)
1703
2043
  }
1704
- // this.instances.forEach( (instance) => client.processInstance(this, instance) )
1705
- fn(args)
1706
2044
  currentConfig.wasInitialized = true
1707
2045
  global.transitoryMode = transitoryMode
1708
2046
  }
@@ -1869,7 +2207,6 @@ class Config {
1869
2207
  }
1870
2208
  this.config.objects.namespaced = {}
1871
2209
  this.resetWasInitialized()
1872
- this.resetMotivations()
1873
2210
 
1874
2211
  // reorder configs base on load ordering
1875
2212
  {
@@ -1895,8 +2232,8 @@ class Config {
1895
2232
  this.config.objects.namespaced[km._uuid] = {}
1896
2233
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
1897
2234
  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)
2235
+ // const aw = (word, def) => this.addWord(word, def)
2236
+ // const ag = (matchOrGenerator, applyOrNothing) => this.addGenerator(matchOrGenerator, applyOrNothing)
1900
2237
  let config = km.config
1901
2238
 
1902
2239
  if (config.addedArgss) {
@@ -1917,32 +2254,51 @@ class Config {
1917
2254
  }
1918
2255
  config.wasInitialized = false
1919
2256
  // TODO change name of config: to baseConfig:
1920
- const kmFn = (name) => this.getConfig(name)
2257
+ const kmFn = (name) => {
2258
+ const config = this.getConfig(name)
2259
+ return config
2260
+ }
1921
2261
  // 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
- }
2262
+ const args = new Object(setupInitializerFNArgs(this, {
2263
+ isModule,
2264
+ hierarchy: this.hierarchy,
2265
+ testConfig: config,
2266
+ currentConfig: config,
2267
+ uuid: config._uuid,
2268
+ objects: namespacedObjects,
2269
+ namespace,
2270
+ api: config.api,
2271
+ }))
2272
+
2273
+ const currentConfig = args.currentConfig
2274
+
2275
+ /*
2276
+ if (args.currentConfig.api) {
2277
+ // args.currentConfig.api.objects = args.objects
2278
+ // TODO assign pseudo config?
2279
+ // args.currentConfig.api.config = () => args.baseConfig
2280
+ // args.currentConfig.api.uuid = args.currentConfig._uuid
2281
+ args.currentConfig.wasInitialized = true
1931
2282
  }
1932
- // greg
2283
+ */
2284
+ // debugger
2285
+ // greg55
2286
+ config.initializerFn(args, { dontCallFn: true })
2287
+ initAfterApis.unshift({ config, args })
1933
2288
  if (config._api) {
1934
2289
  if (config._api.initialize) {
1935
2290
  // reverse the list
1936
- inits.unshift( () => config._api.initialize({ config: this, km: kmFn, api: config._api }) )
2291
+ // TODO sync up the args with initialize of config
2292
+ inits.unshift( () => config._api.initialize({ config: this, km: kmFn, ...args, api: config._api }) )
1937
2293
  // config._api.initialize({ config, api: config._api })
1938
2294
  } else {
1939
2295
  if (interleaved) {
1940
2296
  inits.unshift(null)
1941
2297
  }
1942
2298
  }
1943
- config._api.objects = namespacedObjects
1944
- config._api.config = () => this
1945
- config._api.uuid = config._uuid
2299
+ // config._api.objects = namespacedObjects
2300
+ // config._api.config = () => this
2301
+ // config._api.uuid = config._uuid
1946
2302
  } else {
1947
2303
  if (interleaved) {
1948
2304
  inits.unshift(null)
@@ -1984,10 +2340,9 @@ class Config {
1984
2340
  init()
1985
2341
  }
1986
2342
  for (let init of initAfterApis) {
1987
- // init.args.isAfterApi = true
1988
2343
  init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
1989
2344
  }
1990
- this.instances.forEach((instance) => client.processInstance(this, instance))
2345
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
1991
2346
  } else {
1992
2347
  const base = {
1993
2348
  operators: this.config.operators,
@@ -2016,19 +2371,19 @@ class Config {
2016
2371
  }
2017
2372
  // console.log('name -------------', name)
2018
2373
  if (inits[i]) {
2374
+ // greg55
2019
2375
  inits[i]()
2020
2376
  }
2021
2377
  if (initAfterApis[i]) {
2022
2378
  const init = initAfterApis[i]
2023
- init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
2379
+ init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true})
2024
2380
  }
2025
2381
  const instance = this.instances.find((instance) => instance.name == name)
2026
2382
  if (instance) {
2027
- client.processInstance(this, instance)
2383
+ client.loadInstance(this, instance)
2028
2384
  }
2029
2385
  this.hierarchy.edges = this.config.hierarchy
2030
2386
  }
2031
- // this.instances.forEach((instance) => client.processInstance(this, instance))
2032
2387
  }
2033
2388
 
2034
2389
  if (reverseIt) {
@@ -2151,13 +2506,9 @@ class Config {
2151
2506
  }
2152
2507
  const km = (name) => this.getConfig(name)
2153
2508
  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 })
2509
+ config.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: config, testConfig: config, objects: nsobjects, namespace, uuid }))
2157
2510
  } 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 })
2511
+ this.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: this, testConfig: this, objects: nsobjects, namespace, uuid }))
2161
2512
  }
2162
2513
  })
2163
2514
  }
@@ -2214,10 +2565,18 @@ class Config {
2214
2565
 
2215
2566
  if (config.priorities) {
2216
2567
  let priorities = config.priorities
2217
- priorities = priorities.map((p) => {
2218
- return p.map((id) => {
2219
- return [toNS(id[0]), id[1]]
2220
- })
2568
+ priorities = priorities.map((cp) => {
2569
+ const { context, choose, ordered } = cp
2570
+ const priority = {
2571
+ context: context.map((id) => {
2572
+ return [toNS(id[0]), id[1]]
2573
+ }),
2574
+ choose,
2575
+ }
2576
+ if (ordered) {
2577
+ priority.ordered = ordered
2578
+ }
2579
+ return priority
2221
2580
  })
2222
2581
  config.priorities = priorities
2223
2582
  }
@@ -2307,14 +2666,14 @@ class Config {
2307
2666
 
2308
2667
  set (property, value) {
2309
2668
  if (!this.config.hasOwnProperty(property)) {
2310
- throw `Setting invalid property ${property}`
2669
+ throw new Error(`Setting invalid property ${property}`)
2311
2670
  }
2312
2671
 
2313
2672
  if ('words' == property) {
2314
2673
  for (let word in value) {
2315
2674
  for (let def of value[word]) {
2316
2675
  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}'`
2676
+ 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
2677
  }
2319
2678
  }
2320
2679
  }
@@ -2323,7 +2682,7 @@ class Config {
2323
2682
  if (['operators', 'bridges'].includes(property)) {
2324
2683
  for (let def of value) {
2325
2684
  if (!def['uuid']) {
2326
- throw `All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`
2685
+ throw new Error(`All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`)
2327
2686
  }
2328
2687
  }
2329
2688
  }
@@ -2355,7 +2714,7 @@ class Config {
2355
2714
 
2356
2715
  add (more) {
2357
2716
  if (more === this) {
2358
- throw 'Cannot add an object to itself.'
2717
+ throw new Error('Cannot add an object to itself.')
2359
2718
  }
2360
2719
  if (!(more instanceof Config)) {
2361
2720
  more = new Config(more)
@@ -2416,7 +2775,8 @@ class Config {
2416
2775
  }
2417
2776
 
2418
2777
  // TODO get rid of useOldVersion arg
2419
- addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2778
+ addInternal (more, { addFirst = false, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2779
+ validConfigProps(more)
2420
2780
  if (more instanceof Config) {
2421
2781
  more.initialize({ force: false })
2422
2782
  if (useOldVersion) {
@@ -2426,8 +2786,10 @@ class Config {
2426
2786
  more = _.cloneDeep(more.initConfig)
2427
2787
  }
2428
2788
  }
2789
+ debugConfigProps(more)
2790
+
2429
2791
  if (hcps) {
2430
- handleCalculatedProps(this, more)
2792
+ handleCalculatedProps(this, more, addFirst)
2431
2793
  applyUUID(more, this._uuid)
2432
2794
  }
2433
2795
  for (const key of Object.keys(more)) {
@@ -2452,7 +2814,11 @@ class Config {
2452
2814
  if (!configWords[word]) {
2453
2815
  configWords[word] = []
2454
2816
  }
2455
- configWords[word] = configWords[word].concat(moreWords[word])
2817
+ if (addFirst) {
2818
+ configWords[word] = moreWords[word].concat(configWords[word])
2819
+ } else {
2820
+ configWords[word] = configWords[word].concat(moreWords[word])
2821
+ }
2456
2822
  }
2457
2823
  } else if (key === 'name') {
2458
2824
  /*
@@ -2514,16 +2880,21 @@ class Config {
2514
2880
  this.config[key].splice(iOldOne, 1)
2515
2881
  break;
2516
2882
  }
2517
- }
2883
+ }
2518
2884
  }
2519
2885
  }
2520
2886
  }
2887
+
2521
2888
  // console.log('key', key, 'XXX')
2522
2889
  // console.log('more', JSON.stringify(more, null, 2))
2523
- this.config[key] = this.config[key].concat(more[key])
2890
+ if (addFirst) {
2891
+ this.config[key] = more[key].concat(this.config[key])
2892
+ } else {
2893
+ this.config[key] = this.config[key].concat(more[key])
2894
+ }
2524
2895
  } else {
2525
2896
  if (!(key in this.config)) {
2526
- throw `Unexpected property in config ${key}`
2897
+ throw new Error(`Unexpected property in config ${key}`)
2527
2898
  }
2528
2899
  this.config[key] = more[key]
2529
2900
  }
@@ -2641,7 +3012,7 @@ class Config {
2641
3012
  this.config[key] = more[key].concat(this.config[key])
2642
3013
  } else {
2643
3014
  if (!(key in this.config)) {
2644
- throw `Unexpected property in config ${key}`
3015
+ throw new Error(`Unexpected property in config ${key}`)
2645
3016
  }
2646
3017
  this.config[key] = more[key]
2647
3018
  }
@@ -2651,5 +3022,8 @@ class Config {
2651
3022
  }
2652
3023
 
2653
3024
  module.exports = {
2654
- Config
3025
+ Config,
3026
+ config_toServer,
3027
+ operatorKey_valid,
3028
+ handleBridgeProps,
2655
3029
  }