theprogrammablemind 8.0.0-beta.5 → 8.0.0-beta.51

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
@@ -2,9 +2,10 @@
2
2
  const { Semantics, normalizeGenerator } = require('./semantics')
3
3
  const { Generators } = require('./generators')
4
4
  const { v4: uuidv4 } = require('uuid')
5
- const client = require('../client')
5
+ const configHelpers = require('./configHelpers')
6
6
  const DigraphInternal = require('./digraph_internal')
7
7
  const helpers = require('./helpers')
8
+ const { InitCalls } = require('./helpers')
8
9
  const { ecatch } = require('./helpers')
9
10
  const runtime = require('../runtime')
10
11
  const _ = require('lodash')
@@ -254,6 +255,9 @@ const priority_valid = (cp) => {
254
255
  const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
255
256
  ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
256
257
  () => {
258
+ if (bridge.development && config.isModule) {
259
+ return
260
+ }
257
261
  if (!bridge.bridge) {
258
262
  bridge.bridge = '{ ...next(operator) }'
259
263
  }
@@ -262,7 +266,12 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
262
266
  }
263
267
  if (bridge.children) {
264
268
  for (const child of bridge.children) {
265
- config.addHierarchy(child, bridge.id)
269
+ // config.addHierarchy(child, bridge.id)
270
+ if (child.child) {
271
+ config.addHierarchy(child.child, bridge.id, child.instance)
272
+ } else {
273
+ config.addHierarchy(child, bridge.id)
274
+ }
266
275
  }
267
276
  }
268
277
  if (bridge.operator) {
@@ -270,12 +279,20 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
270
279
  }
271
280
  if (bridge.parents) {
272
281
  for (const parent of bridge.parents) {
273
- config.addHierarchy(bridge.id, parent)
282
+ if (parent.parent) {
283
+ config.addHierarchy(bridge.id, parent.parent, parent.instance)
284
+ } else {
285
+ config.addHierarchy(bridge.id, parent)
286
+ }
274
287
  }
275
288
  }
276
289
  if (bridge.isA) {
277
290
  for (const parent of bridge.isA) {
278
- config.addHierarchy(bridge.id, parent)
291
+ if (parent.parent) {
292
+ config.addHierarchy(bridge.id, parent.parent, parent.instance)
293
+ } else {
294
+ config.addHierarchy(bridge.id, parent)
295
+ }
279
296
  }
280
297
  }
281
298
  if (bridge.before) {
@@ -338,8 +355,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
338
355
  const level = bridge.generatorp.level >= 0 ? bridge.generatorp.level : bridge.level + 1
339
356
 
340
357
  const generator = {
341
- where: bridge.generatorp.where || bridge.where || client.where(4),
342
- match: (args) => bridge.id == args.context.marker && args.context.level == level && args.context.paraphrase && match(args),
358
+ where: bridge.generatorp.where || bridge.where || helpers.where(4),
359
+ match: async (args) => bridge.id == args.context.marker && args.context.level == level && args.context.paraphrase && await match(args),
343
360
  apply: (args) => apply(args),
344
361
  applyWrapped: apply,
345
362
  property: 'generatorp'
@@ -355,8 +372,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
355
372
  const apply = typeof bridge.generatorr === 'function' ? bridge.generatorr : bridge.generatorr.apply || bridge.generatorr
356
373
  const level = bridge.generatorr.level >= 0 ? bridge.generatorr.level : bridge.level + 1
357
374
  const generator = {
358
- where: bridge.generatorr.where || bridge.where || client.where(4),
359
- match: (args) => bridge.id == args.context.marker && args.context.level == level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && match(args),
375
+ where: bridge.generatorr.where || bridge.where || helpers.where(4),
376
+ match: async (args) => bridge.id == args.context.marker && args.context.level == level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && await match(args),
360
377
  apply: (args) => apply(args),
361
378
  applyWrapped: apply,
362
379
  property: 'generatorr'
@@ -369,7 +386,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
369
386
  }
370
387
  if (bridge.evaluator) {
371
388
  const semantic = {
372
- where: bridge.evaluator.where || bridge.where || client.where(3),
389
+ where: bridge.evaluator.where || bridge.where || helpers.where(3),
373
390
  match: ({ context }) => bridge.id == context.marker && context.evaluate,
374
391
  apply: (args) => bridge.evaluator(args),
375
392
  applyWrapped: bridge.evaluator,
@@ -383,7 +400,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
383
400
  }
384
401
  if (bridge.semantic) {
385
402
  const semantic = {
386
- where: bridge.semantic.where || bridge.where || client.where(3),
403
+ where: bridge.semantic.where || bridge.where || helpers.where(3),
387
404
  match: ({ context }) => bridge.id == context.marker && !context.evaluate,
388
405
  apply: (args) => bridge.semantic(args),
389
406
  applyWrapped: bridge.semantic,
@@ -551,7 +568,7 @@ function isLetter (char) {
551
568
  }
552
569
  */
553
570
 
554
- function configDup (config, options) {
571
+ async function configDup (config, options) {
555
572
  if (config instanceof Config) {
556
573
  return config.copy(options)
557
574
  }
@@ -691,9 +708,9 @@ class KM {
691
708
  return true
692
709
  }
693
710
 
694
- copy2 (options) {
711
+ async copy2 (options) {
695
712
  // greg -> add a flag to say don't init the api's
696
- const config = configDup(this._config, options)
713
+ const config = await configDup(this._config, options)
697
714
  const km = new KM({
698
715
  config,
699
716
  getCounter: options.getCounter,
@@ -705,10 +722,10 @@ class KM {
705
722
  return km // copy2()
706
723
  }
707
724
 
708
- copy () {
725
+ async copy () {
709
726
  const km = new KM({
710
727
  name: this._name,
711
- config: configDup(this._config),
728
+ config: await configDup(this._config),
712
729
  // _uuid: uuidv4(),
713
730
  _uuid: this._config.getCounter(this._config._name),
714
731
  getCounter: (name) => this._config.getCounter(name),
@@ -760,12 +777,11 @@ const multiApiImpl = (initializer) => {
760
777
  multiApi: true,
761
778
 
762
779
  // multi functions
763
- add: (config, multiApi, api) => {
780
+ add: async (config, multiApi, api, apiConstructor) => {
764
781
  initializer(config, api)
765
782
  const name = api.getName()
766
783
  multiApi.apis[name] = api
767
- // api.objects = config.get('objects')
768
- // api.config = () => config
784
+ multiApi.apiConstructors[name] = apiConstructor
769
785
  multiApi.current = name
770
786
  },
771
787
 
@@ -788,6 +804,9 @@ const multiApiImpl = (initializer) => {
788
804
  apis: {
789
805
  },
790
806
 
807
+ apiConstructors: {
808
+ },
809
+
791
810
  // api functions
792
811
  api: (multiApi) => multiApi.apis[multiApi.current]
793
812
  })
@@ -798,17 +817,6 @@ class Config {
798
817
  return config_toServer(config)
799
818
  }
800
819
 
801
- base () {
802
- const base = new Config()
803
- for (const km of this.configs.reverse()) {
804
- if (km.isSelf) {
805
- continue
806
- }
807
- base.add(km.config)
808
- }
809
- return base
810
- }
811
-
812
820
  getInfo () {
813
821
  const name = this.name
814
822
  const includes = this.configs.slice(1).map((km) => km.config.name)
@@ -852,6 +860,7 @@ class Config {
852
860
  addArgs: (...args) => this.addArgs(...args),
853
861
  getBridge: (...args) => this.getBridge(...args),
854
862
  fragment: (...args) => this.fragment(...args),
863
+ server: (...args) => this.server(...args),
855
864
  exists: (...args) => this.exists(...args),
856
865
  addAPI: (...args) => this.addAPI(...args)
857
866
  }
@@ -988,23 +997,8 @@ class Config {
988
997
 
989
998
  // value is in response field
990
999
  // TODO maybe generalize out query+evaluate along the lines of set value and set reference
991
- /*
992
- getEvaluator (s, log, context) {
993
- const instance = s({ ...context, evaluate: true })
994
- if (!instance.evalue && !instance.verbatim && !instance.value) {
995
- this.warningNotEvaluated(log, context);
996
- }
997
- if (!instance.evalue) {
998
- instance.evalue = instance.value
999
- instance.edefault = true
1000
- }
1001
- delete instance.evaluate
1002
- instance.instance = true;
1003
- return instance
1004
- }
1005
- */
1006
- getEvaluator (s, calls, log, context) {
1007
- const instance = s({ ...context, evaluate: true })
1000
+ async getEvaluator (s, calls, log, context) {
1001
+ const instance = await s({ ...context, evaluate: true })
1008
1002
  calls.touch(instance)
1009
1003
  if (!instance.evalue && !instance.verbatim && !instance.value) {
1010
1004
  this.warningNotEvaluated(log, context)
@@ -1018,19 +1012,21 @@ class Config {
1018
1012
  return instance
1019
1013
  }
1020
1014
 
1021
- fragmentInstantiator (contexts) {
1015
+ fragmentInstantiator (args, contexts) {
1022
1016
  return new Object({
1023
1017
  contexts: () => contexts,
1024
- instantiate: (mappings) => {
1018
+ instantiate: async (mappings) => {
1025
1019
  const instantiated = _.cloneDeep(contexts)
1026
1020
  // const todo = [...instantiated]
1027
1021
  // const todo = [...instantiated]
1028
1022
  const todo = _.clone(instantiated)
1023
+ args = {...args}
1029
1024
  while (todo.length > 0) {
1030
1025
  const context = todo.pop()
1026
+ args.context = context
1031
1027
  for (const mapping of mappings) {
1032
- if (mapping.match({ context })) {
1033
- mapping.apply({ context })
1028
+ if (await mapping.match(args)) {
1029
+ await mapping.apply(args)
1034
1030
  }
1035
1031
  }
1036
1032
  for (const key of Object.keys(context)) {
@@ -1049,11 +1045,21 @@ class Config {
1049
1045
  })
1050
1046
  }
1051
1047
 
1052
- fragment (query) {
1048
+ fragment (args, query) {
1053
1049
  for (const instance of (this.instances || [])) {
1054
1050
  for (const fragment of (instance.fragments || [])) {
1055
1051
  if (fragment.query === query) {
1056
- return this.fragmentInstantiator(fragment.contexts)
1052
+ return this.fragmentInstantiator(args, fragment.contexts)
1053
+ }
1054
+ }
1055
+ for (const fragment of (instance.resultss || [])) {
1056
+ if (fragment.isFragment && fragment.query === query) {
1057
+ return this.fragmentInstantiator(args, fragment.contexts)
1058
+ }
1059
+ }
1060
+ for (const fragment of (this.fragmentsBeingBuilt || [])) {
1061
+ if (fragment.query === query) {
1062
+ return this.fragmentInstantiator(args, fragment.contexts)
1057
1063
  }
1058
1064
  }
1059
1065
  }
@@ -1093,6 +1099,27 @@ class Config {
1093
1099
  } else {
1094
1100
  const config = { ...queryOrConfig }
1095
1101
  delete config.where
1102
+
1103
+ if (config.words && config.words.hierarchy) {
1104
+ config.words.hierarchy = config.words.hierarchy.map( (value) => {
1105
+ value = {...value}
1106
+ delete value.uuid
1107
+ return value
1108
+ })
1109
+ }
1110
+
1111
+ if (config.words && config.words.patterns) {
1112
+ config.words.patterns = config.words.patterns.map( (value) => {
1113
+ value = {...value}
1114
+ value.defs = value.defs.map( (value) => {
1115
+ value = {...value}
1116
+ delete value.uuid
1117
+ return value
1118
+ })
1119
+ return value
1120
+ })
1121
+ }
1122
+
1096
1123
  config.operators = (config.operators || []).map((operator) => {
1097
1124
  if (typeof operator === 'string') {
1098
1125
  return { pattern: operator }
@@ -1120,6 +1147,9 @@ class Config {
1120
1147
  delete bridge.generatorpr
1121
1148
  delete bridge.evaluator
1122
1149
  delete bridge.semantic
1150
+ if (!bridge.bridge) {
1151
+ bridge.bridge = "{ ...next(operator) }"
1152
+ }
1123
1153
  return bridge
1124
1154
  })
1125
1155
  } else {
@@ -1197,7 +1227,9 @@ class Config {
1197
1227
  // console.log("instanceFragments", instanceFragments)
1198
1228
  }
1199
1229
  }
1200
- if (startOfChanges || instance.resultss) {
1230
+ if (startOfChanges) {
1231
+ return { needsRebuild: true, startOfChanges, previousResultss: instance.resultss }
1232
+ } else if (startOfChanges || instance.resultss) {
1201
1233
  return { needsRebuild: !(instance && sameQueries && sameFragments), startOfChanges, previousResultss: instance.resultss }
1202
1234
  } else {
1203
1235
  return { needsRebuild: !(instance && sameQueries && sameFragments) }
@@ -1222,7 +1254,7 @@ class Config {
1222
1254
  }
1223
1255
 
1224
1256
  // loadTemplate
1225
- load (template, instance, options = { rebuild: false, previousResultss: undefined, startOfChanges: undefined }) {
1257
+ async load (rebuildTemplate, template, instance, options = { rebuild: false, previousResultss: undefined, startOfChanges: undefined }) {
1226
1258
  this.validifyTemplate(template)
1227
1259
  instance.template = template
1228
1260
  this.logs.push(`loading template for ${this.name}`)
@@ -1230,7 +1262,7 @@ class Config {
1230
1262
  // TODO fix beforeQuery
1231
1263
  template = { fragments: [], configs: [], ...template }
1232
1264
  template.fragments = template.fragments.concat(this.dynamicFragments)
1233
- client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1265
+ rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1234
1266
  } else {
1235
1267
  // no change
1236
1268
  // this.initInstances.push({ ...instance, name: config.name })
@@ -1255,7 +1287,7 @@ class Config {
1255
1287
  instance.name = this.name
1256
1288
  this.initInstances.push(instance)
1257
1289
  this.instances.push(instance)
1258
- client.loadInstance(this, instance)
1290
+ await configHelpers.loadInstance(this, instance)
1259
1291
  }
1260
1292
  }
1261
1293
  }
@@ -1309,9 +1341,9 @@ class Config {
1309
1341
  }
1310
1342
  }
1311
1343
 
1312
- addHierarchy (child, parent) {
1344
+ addHierarchy (child, parent, instance) {
1313
1345
  if (child && parent || !child || Array.isArray(child) || (typeof child === 'string' && !parent)) {
1314
- this.addHierarchyChildParent(child, parent)
1346
+ this.addHierarchyChildParent(child, parent, instance)
1315
1347
  // this.addHierarchyProperties ({ child, parent })
1316
1348
  } else {
1317
1349
  this.addHierarchyProperties(child)
@@ -1319,26 +1351,32 @@ class Config {
1319
1351
  }
1320
1352
 
1321
1353
  addHierarchyProperties (edge) {
1322
- const { child, parent } = edge
1354
+ const { child, parent, instance } = edge
1323
1355
  if (typeof child !== 'string') {
1324
1356
  throw new Error(`addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`)
1325
1357
  }
1326
1358
  if (typeof parent !== 'string') {
1327
1359
  throw new Error(`addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`)
1328
1360
  }
1361
+ if (instance && typeof instance !== 'boolean') {
1362
+ throw new Error(`addHierarchy expected instance property to be a boolean or undefined. got ${JSON.stringify(instance)}`)
1363
+ }
1329
1364
  debugHierarchy([child, parent])
1330
1365
  this.config.hierarchy.push(edge)
1331
1366
  // TODO greg11 this.hierarchy.addEdge(edge)
1332
- this._delta.json.hierarchy.push([child, parent])
1367
+ this._delta.json.hierarchy.push([child, parent, instance || false])
1333
1368
  }
1334
1369
 
1335
- addHierarchyChildParent (child, parent) {
1370
+ addHierarchyChildParent (child, parent, instance) {
1336
1371
  if (typeof child !== 'string') {
1337
1372
  throw new Error(`addHierarchy expected child to be a string. got ${JSON.stringify(child)}`)
1338
1373
  }
1339
1374
  if (typeof parent !== 'string') {
1340
1375
  throw new Error(`addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`)
1341
1376
  }
1377
+ if (instance && typeof instance !== 'boolean') {
1378
+ throw new Error(`addHierarchy expected instance property to be a boolean or undefined. got ${JSON.stringify(instance)}`)
1379
+ }
1342
1380
  debugHierarchy([child, parent])
1343
1381
  if (this.config.hierarchy.find((element) => {
1344
1382
  const hc = hierarchyCanonical(element)
@@ -1349,9 +1387,9 @@ class Config {
1349
1387
  return
1350
1388
  }
1351
1389
 
1352
- this.config.hierarchy.push([child, parent])
1390
+ this.config.hierarchy.push([child, parent, instance || false])
1353
1391
  // this.hierarchy.addEdge([child, parent])
1354
- this._delta.json.hierarchy.push([child, parent])
1392
+ this._delta.json.hierarchy.push([child, parent, instance || false])
1355
1393
  }
1356
1394
 
1357
1395
  getBridge (id, level) {
@@ -1398,7 +1436,7 @@ class Config {
1398
1436
  }
1399
1437
 
1400
1438
  if (!generator.where) {
1401
- generator.where = client.where(3)
1439
+ generator.where = helpers.where(3)
1402
1440
  }
1403
1441
 
1404
1442
  const generators = this.config.generators
@@ -1421,7 +1459,7 @@ class Config {
1421
1459
  }
1422
1460
 
1423
1461
  if (!semantic.where) {
1424
- semantic.where = client.where(3)
1462
+ semantic.where = helpers.where(3)
1425
1463
  }
1426
1464
 
1427
1465
  const semantics = this.config.semantics
@@ -1608,16 +1646,12 @@ class Config {
1608
1646
  return params
1609
1647
  }
1610
1648
 
1611
- processContexts (contexts, params) {
1612
- client.processContexts(contexts, this.getParams())
1613
- }
1614
-
1615
- processContext (context) {
1616
- return client.processContext(context, this.getParams())
1649
+ async processContext (context) {
1650
+ return await configHelpers.processContext(context, this.getParams())
1617
1651
  }
1618
1652
 
1619
1653
  process (query, options) {
1620
- return client.process(this, query, options)
1654
+ return this.clientProcess(this, query, options)
1621
1655
  }
1622
1656
 
1623
1657
  query (query, options) {
@@ -1758,7 +1792,7 @@ class Config {
1758
1792
  }
1759
1793
 
1760
1794
  // configs = [ { config, namespace } ... ]
1761
- constructor (config, module) {
1795
+ constructor (config, module, clientProcess) {
1762
1796
  if (config instanceof Config) {
1763
1797
  throw new Error('Excepted the config argument to be a hash not a Config object')
1764
1798
  }
@@ -1776,6 +1810,7 @@ class Config {
1776
1810
  config.priorities = config.priorities || []
1777
1811
  }
1778
1812
 
1813
+ this.clientProcess = clientProcess
1779
1814
  this.maxDepth = 20 // for generators and semantics
1780
1815
  this.debugLoops = false // for generators and semantics
1781
1816
 
@@ -1801,24 +1836,6 @@ class Config {
1801
1836
  // when running configs any bridges added are marked as transitory so that the associated will ignore those op's
1802
1837
  this.transitoryMode = false
1803
1838
 
1804
- // check for duplicate bridges
1805
- if (config && config.bridges) {
1806
- let duplicated = new Set()
1807
- const seen = new Set()
1808
- for (const bridge of config.bridges) {
1809
- const id = `${bridge.id}/${bridge.level}`
1810
- if (seen.has(id)) {
1811
- duplicated.add(id)
1812
- } else {
1813
- seen.add(id)
1814
- }
1815
- }
1816
- duplicated = Array.from(duplicated)
1817
- if (duplicated.length > 0) {
1818
- throw new Error(`In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`)
1819
- }
1820
- }
1821
-
1822
1839
  if (config && config.words) {
1823
1840
  initWords(config.words)
1824
1841
  isValidWordDef(config.words)
@@ -1867,6 +1884,7 @@ class Config {
1867
1884
  }
1868
1885
  this.get('objects').namespaced[this._uuid] = {}
1869
1886
  this.valid()
1887
+ this.checks()
1870
1888
  debugConfigProps(this.config)
1871
1889
  }
1872
1890
 
@@ -1878,9 +1896,9 @@ class Config {
1878
1896
  this._stop_auto_rebuild = true
1879
1897
  }
1880
1898
 
1881
- restart_auto_rebuild() {
1899
+ async restart_auto_rebuild() {
1882
1900
  this._stop_auto_rebuild = false
1883
- this.rebuild()
1901
+ await this.rebuild()
1884
1902
  }
1885
1903
 
1886
1904
  getAddedArgs (args) {
@@ -1899,8 +1917,8 @@ class Config {
1899
1917
  }
1900
1918
  }
1901
1919
 
1902
- set multiApi (initializer) {
1903
- this.api = multiApiImpl(initializer)
1920
+ async setMultiApi (initializer) {
1921
+ await this.setApi(() => multiApiImpl(initializer))
1904
1922
  }
1905
1923
 
1906
1924
  get multiApi () {
@@ -1948,31 +1966,38 @@ class Config {
1948
1966
  }
1949
1967
  }
1950
1968
 
1951
- addAPI (api) {
1969
+ async addAPI (api) {
1970
+ // console.trace()
1971
+ // throw "addAPI"
1952
1972
  if (this._api && this._api.multiApi) {
1953
- this._api.add(this, this._api, api)
1973
+ await this._api.add(this, this._api, api)
1954
1974
  } else {
1955
1975
  throw new Error('Can only add apis to a multi-api')
1956
1976
  }
1957
1977
  }
1958
1978
 
1959
- set api (value) {
1979
+ async setApi (constructor) {
1980
+ if (typeof constructor !== 'function') {
1981
+ throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
1982
+ }
1983
+ const value = constructor()
1960
1984
  if (!value.initialize) {
1961
1985
  throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
1962
1986
  }
1963
1987
 
1964
1988
  if (this._api && this._api.multiApi) {
1965
- this._api.add(this, this._api, value)
1966
- } else {
1967
- this._api = _.cloneDeep(value)
1968
- /*
1969
- if (this._api) {
1970
- // this._api.objects = this.config.objects
1971
- // this._api.config = () => this
1972
- // this._api.uuid = this._uuid
1989
+ await this._api.add(this, this._api, value, constructor)
1990
+ const previousApiConstructor = this._apiConstructor
1991
+ this._apiConstructor = (config) => {
1992
+ const api = previousApiConstructor(config)
1993
+ // does this need await?
1994
+ api.add(config, api, constructor(config), constructor)
1995
+ return api
1973
1996
  }
1974
- */
1975
- this.rebuild()
1997
+ } else {
1998
+ this._api = value
1999
+ this._apiConstructor = constructor
2000
+ await this.rebuild()
1976
2001
  }
1977
2002
  }
1978
2003
 
@@ -1992,7 +2017,7 @@ class Config {
1992
2017
  }
1993
2018
 
1994
2019
  // remove all added modules and initialize with the init config
1995
- resetToOne () {
2020
+ async resetToOne () {
1996
2021
  /*
1997
2022
  this.config = _.cloneDeep(this.initConfig)
1998
2023
  this.configs = [this.configs[0]]
@@ -2001,11 +2026,8 @@ class Config {
2001
2026
  */
2002
2027
  this.configs = [this.configs[0]]
2003
2028
  this.defaultConfig()
2004
- if (!this.initializeFn) {
2005
- // TODO move this to the default initializer
2006
- Object.assign(this.config.objects, _.cloneDeep(this.initConfig.objects || {}))
2007
- }
2008
- this.initializeConfigFromConfigs({ others: [], objects: this.config.objects.namespaced, moreNames: [], callInitializers: false })
2029
+ Object.assign(this.config.objects, _.cloneDeep(this.initConfig.objects || {}))
2030
+ await this.initializeConfigFromConfigs({ others: [], objects: this.config.objects.namespaced, moreNames: [], callInitializers: false })
2009
2031
  const map = {}
2010
2032
  for (let i = 0; i < this.configs.length; ++i) {
2011
2033
  map[this.configs[i].uuid] = this.configs[i].uuid
@@ -2027,21 +2049,26 @@ class Config {
2027
2049
  runtime.fs.writeFileSync(fn, JSON.stringify(this.config, 0, 2))
2028
2050
  }
2029
2051
 
2030
- copy (options = { callInitializers: true }) {
2031
- }
2032
-
2033
- copy (options = { callInitializers: true }) {
2052
+ async copy (options = { callInitializers: true }) {
2034
2053
  this.valid()
2035
2054
  const cp = new Config()
2036
2055
  cp.logs = []
2037
2056
  cp.maxDepth = this.maxDepth
2038
2057
  cp.debugLoops = this.debugLoops
2039
2058
  cp.transitoryMode = this.transitoryMode
2040
- cp.configs = this.configs.map((km) => km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
2059
+ // cp.configs = this.configs.map((km) => await km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
2060
+ cp.configs = []
2061
+ for (const km of this.configs) {
2062
+ cp.configs.push(await km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
2063
+ }
2041
2064
  cp._uuid = cp.configs[0]._uuid
2042
2065
  // update uuid here set the uuid in the objects and add error checking
2043
2066
  cp.initializerFn = this.initializerFn
2044
- cp._api = _.cloneDeep(this._api)
2067
+ // cp._api = _.cloneDeep(this._api)
2068
+ if (this._apiConstructor) {
2069
+ cp._api = this._apiConstructor(cp)
2070
+ cp._apiConstructor = this._apiConstructor
2071
+ }
2045
2072
  cp._namespace = this._namespace
2046
2073
  cp._eqClasses = this._eqClasses
2047
2074
  cp.name = this.name
@@ -2058,13 +2085,8 @@ class Config {
2058
2085
  cp.defaultConfig()
2059
2086
  // cp.wasInitialized = false; // since default config GREG
2060
2087
  cp.resetWasInitialized()
2061
- if (!this.initializeFn) {
2062
- // TODO move this to the default initializer
2063
- Object.assign(cp.config.objects, _.cloneDeep(this.initConfig.objects || {}))
2064
- }
2065
- // cp.initializeConfigFromConfigs({ others: [], objects: cp.config.objects.namespaced, moreNames: [], ...options })
2066
- // cp.initializeConfigFromConfigs(Object.assign({ others: [], objects: cp.config.objects.namespaced, moreNames: [] }, { callInitializers: false }))
2067
- cp.initializeConfigFromConfigs(Object.assign({ others: [], objects: cp.config.objects.namespaced, moreNames: [] }, options))
2088
+ Object.assign(cp.config.objects, _.cloneDeep(this.initConfig.objects || {}))
2089
+ await cp.initializeConfigFromConfigs(Object.assign({ others: [], objects: cp.config.objects.namespaced, moreNames: [] }, options))
2068
2090
  const map = {}
2069
2091
  for (let i = 0; i < this.configs.length; ++i) {
2070
2092
  map[this.configs[i].uuid] = cp.configs[i].uuid
@@ -2075,33 +2097,16 @@ class Config {
2075
2097
  // debugger
2076
2098
  }
2077
2099
  if (options.callInitializers) {
2078
- cp.rebuild(options)
2100
+ await cp.rebuild(options) // in copy
2079
2101
  } else {
2080
- // this mess is for duplicate into a KM after resetToOne was called
2081
- /*
2082
- if (cp._api) {
2083
- // cp._api.objects = cp.config.objects
2084
- // cp._api.config = () => (cp instanceof Config) ? cp : cp.config
2085
- // cp._api.uuid = cp._uuid
2086
- }
2087
- */
2088
-
2089
2102
  if (!cp.config.objects) {
2090
2103
  cp.config.objects = { namespaced: {} }
2091
2104
  } else if (!cp.config.objects.namespaced) {
2092
2105
  cp.config.objects.namespaced = {}
2093
2106
  }
2094
2107
  cp.configs.forEach((km) => {
2095
- // const namespace = km.namespace
2096
2108
  cp.config.objects.namespaced[km._uuid] = {}
2097
2109
  })
2098
- /*
2099
- if (cp._uuid == 'concept2') {
2100
- if (!cp.api.objects.defaultTypesForHierarchy) {
2101
- debugger
2102
- }
2103
- }
2104
- */
2105
2110
  }
2106
2111
  cp.valid()
2107
2112
  return cp
@@ -2225,41 +2230,7 @@ class Config {
2225
2230
  }
2226
2231
  }
2227
2232
 
2228
- initializeFromConfigs () {
2229
- // [...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
2230
- [...this.configs].reverse().forEach(({ config, namespace, uuid }) => {
2231
- /*
2232
- let objects = this.get('objects')
2233
- if (namespace) {
2234
- objects = {}
2235
- this.get('objects')['namespaced'][namespace] = objects
2236
- }
2237
- */
2238
- const objects = {}
2239
- if (config instanceof Config) {
2240
- this.get('objects').namespaced[config._uuid] = objects
2241
- /*
2242
- if (config._api) {
2243
- // config._api.objects = objects
2244
- // config._api.config = () => this
2245
- }
2246
- */
2247
- config.initializerFn(setupInitializerFNArgs(this, { testConfig: config, currentConfig: config, objects, namespace, uuid }))
2248
- } else {
2249
- this.get('objects').namespaced[this._uuid] = objects
2250
- /*
2251
- if (config._api) {
2252
- // config._api.objects = objects
2253
- // config._api.config = () => this
2254
- }
2255
- */
2256
- this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, namespace, uuid }))
2257
- }
2258
- })
2259
- this.instances.forEach((instance) => client.loadInstance(this, instance))
2260
- }
2261
-
2262
- initialize ({ force = true } = {}) {
2233
+ initialize23 ({ force = true } = {}) {
2263
2234
  if (force || !this.wasInitialized) {
2264
2235
  const objects = this.config.objects.namespaced[this._uuid]
2265
2236
  this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '' }))
@@ -2267,7 +2238,7 @@ class Config {
2267
2238
  }
2268
2239
  }
2269
2240
 
2270
- initializer (fn, options = {}) {
2241
+ async initializer (fn, options = {}) {
2271
2242
  if (options) {
2272
2243
  for (const option of Object.keys(options)) {
2273
2244
  const validOptions = []
@@ -2289,8 +2260,7 @@ class Config {
2289
2260
  currentConfig.wasInitialized = true
2290
2261
  global.transitoryMode = transitoryMode
2291
2262
  }
2292
- // this.initializeFromConfigs()
2293
- this.rebuild()
2263
+ await this.rebuild()
2294
2264
  }
2295
2265
 
2296
2266
  nsToString (id) {
@@ -2436,7 +2406,7 @@ class Config {
2436
2406
  }
2437
2407
 
2438
2408
  // rebuild ({ isModule: mainIsModule = false } = {}) {
2439
- rebuild ({ isModule: mainIsModule } = {}) {
2409
+ async rebuild ({ isModule: mainIsModule } = {}) {
2440
2410
  if (this._stop_auto_rebuild) {
2441
2411
  return
2442
2412
  }
@@ -2604,7 +2574,7 @@ class Config {
2604
2574
  }
2605
2575
  const instance = this.instances.find((instance) => instance.name == name)
2606
2576
  if (instance) {
2607
- client.loadInstance(this, instance)
2577
+ await configHelpers.loadInstance(this, instance)
2608
2578
  }
2609
2579
  this.hierarchy.edges = this.config.hierarchy
2610
2580
  }
@@ -2612,7 +2582,7 @@ class Config {
2612
2582
 
2613
2583
  this.hierarchy.edges = this.config.hierarchy
2614
2584
  this.valid()
2615
- this.checkBridges()
2585
+ this.checks()
2616
2586
  }
2617
2587
 
2618
2588
  nameToUUID (name) {
@@ -2624,6 +2594,7 @@ class Config {
2624
2594
  // if undefined namespace applies to first loaded config
2625
2595
  // if list of name then namespace applied only to those configs
2626
2596
  // if true then namespace applies to all loaded configs
2597
+ /*
2627
2598
  namespace (moreNames, others) {
2628
2599
  const config = this.copy()
2629
2600
  if (!Array.isArray(moreNames)) {
@@ -2659,6 +2630,7 @@ class Config {
2659
2630
  config.rebuild()
2660
2631
  return config
2661
2632
  }
2633
+ */
2662
2634
 
2663
2635
  setupNamespace (km) {
2664
2636
  let config = km.config
@@ -2677,7 +2649,7 @@ class Config {
2677
2649
 
2678
2650
  // config.initializerFn({ config: this, objects, namespace })
2679
2651
  // this goes through all the configs and sets up this.config
2680
- initializeConfigFromConfigs ({ others, objects, moreNames, callInitializers = true }) {
2652
+ async initializeConfigFromConfigs ({ others, objects, moreNames, callInitializers = true }) {
2681
2653
  // setup the namespace in the configs
2682
2654
  let first = true
2683
2655
  this.configs.forEach((km) => {
@@ -2826,6 +2798,11 @@ class Config {
2826
2798
  }
2827
2799
  }
2828
2800
 
2801
+ checks () {
2802
+ this.checkOperators()
2803
+ this.checkBridges()
2804
+ }
2805
+
2829
2806
  checkOperators () {
2830
2807
  if (!this.config.operators) {
2831
2808
  return
@@ -2846,53 +2823,19 @@ class Config {
2846
2823
  return
2847
2824
  }
2848
2825
 
2849
- /*
2850
- "namespaces": {
2851
- "634a678b-8d92-4464-bf65-943a82f404d8": {
2852
- "ids": [ "tankConcept" ],
2853
- "namespace": [ "ns1" ]
2854
- },
2855
- console.log('before check', JSON.stringify(this._eqClasses, null, 2))
2856
- */
2857
-
2858
- const errors = []
2859
- /*
2860
- const namespaces = this.config.namespaces
2861
- const nsToIds = {}
2862
- for (const uuid in namespaces) {
2863
- const namespace = namespaces[uuid].namespace
2864
- const ns = namespace.join('#')
2865
- if (!nsToIds[ns]) {
2866
- nsToIds[ns] = new Set()
2867
- }
2868
- const ids = nsToIds[ns]
2869
- for (const id of namespaces[uuid].ids) {
2870
- if (ids.has(id)) {
2871
- if (ns === '') {
2872
- const dups = this.config.bridges.filter( (bridge) => bridge.id == id )
2873
- errors.push(`Id '${id}' is defined more than once in the bridges of the base namespace of the KM ${this.name}, Dups are ${JSON.stringify(dups)}`)
2874
- } else {
2875
- errors.push(`Id '${id}' is defined more than once in the bridges of the ${ns} namespace of the KM ${this.name}`)
2876
- }
2877
- } else {
2878
- ids.add(id)
2879
- }
2880
- }
2881
- }
2882
- */
2883
-
2884
- const keyIsPresent = {}
2826
+ let duplicated = new Set()
2827
+ const seen = new Set()
2885
2828
  for (const bridge of this.config.bridges) {
2886
- const key = `${bridge.id}/${bridge.level} (namespace: ${bridge.uuid})`
2887
- if (keyIsPresent[key]) {
2888
- errors.push(new Error(`Id '${key}' is defined more than once in bridges of the base namespace of the KM ${this.name}`))
2829
+ const id = `${bridge.id}/${bridge.level} (namespace: ${bridge.uuid || this.uuid})`
2830
+ if (seen.has(id)) {
2831
+ duplicated.add(id)
2889
2832
  } else {
2890
- keyIsPresent[key] = key
2833
+ seen.add(id)
2891
2834
  }
2892
2835
  }
2893
-
2894
- if (errors.length > 0) {
2895
- throw errors
2836
+ duplicated = Array.from(duplicated)
2837
+ if (duplicated.length > 0) {
2838
+ throw new Error(`In the KM ${this.name}, the following operators are duplicated in the bridges: ${duplicated}`)
2896
2839
  }
2897
2840
  };
2898
2841
 
@@ -2949,25 +2892,29 @@ class Config {
2949
2892
  }
2950
2893
  }
2951
2894
 
2952
- add (...mores) {
2953
- mores.forEach((km) => {
2954
- if (km === this) {
2955
- throw new Error('Cannot add an object to itself.')
2895
+ async add (...createConfigs) {
2896
+ createConfigs.forEach((createConfig, index) => {
2897
+ if (typeof createConfig !== 'function') {
2898
+ throw new Error(`Expected add argument number ${index+1} to be a function that constructs the config.`)
2956
2899
  }
2957
2900
  })
2958
2901
 
2959
- mores = mores.map((km) => {
2960
- if (!(km instanceof Config)) {
2961
- km = new Config(km)
2902
+ const mores = []
2903
+ for (const createConfig of createConfigs) {
2904
+ const more = await createConfig()
2905
+ if (this.name && this.name == more.name) {
2906
+ throw new Error('Cannot add an object to itself for argument number ${index+1}.')
2962
2907
  }
2963
- return km
2964
- })
2965
-
2966
- mores.forEach((more) => {
2908
+ if (this === more) {
2909
+ throw new Error('Cannot add an object to itself.')
2910
+ }
2911
+ mores.push(more)
2912
+ }
2913
+ for (let more of mores) {
2967
2914
  this.valid()
2968
2915
  more.valid()
2969
2916
  // copy so i don't have to copy later
2970
- more = more.copy()
2917
+ more = await more.copy()
2971
2918
  more.server(this._server, this._key, this._queryParams)
2972
2919
 
2973
2920
  const moreConfigs = more.configs.map((km) => km.name || km.uuid)
@@ -2982,9 +2929,6 @@ class Config {
2982
2929
  const moreKMs1 = [new KM({ config: more, getCounter: (name) => this.getCounter(name), uuid: more.uuid, namespace })]
2983
2930
  const moreKMs2 = more.configs.slice(1).map((km) => {
2984
2931
  return km
2985
- // const cp = km.copy()
2986
- // cp.namespace = namespace
2987
- // return cp;
2988
2932
  })
2989
2933
  const moreKMs = moreKMs1.concat(moreKMs2)
2990
2934
  const eqClass = moreKMs.map((km) => km.uuid)
@@ -2998,7 +2942,7 @@ class Config {
2998
2942
  this.configs.push(moreKM)
2999
2943
  }
3000
2944
  }
3001
- more.resetToOne()
2945
+ await more.resetToOne()
3002
2946
  this.config.eqClasses = this._eqClasses
3003
2947
  // greg
3004
2948
  // setup instances
@@ -3013,8 +2957,8 @@ class Config {
3013
2957
  }
3014
2958
  }
3015
2959
  this.instances = noDups
3016
- })
3017
- this.rebuild()
2960
+ }
2961
+ await this.rebuild() // in add(
3018
2962
  this.valid()
3019
2963
  return this
3020
2964
  }
@@ -3170,7 +3114,7 @@ class Config {
3170
3114
  // assumes this is called in reverse order
3171
3115
  addInternalR (more, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false) {
3172
3116
  if (more instanceof Config) {
3173
- more.initialize({ force: false })
3117
+ more.initialize23({ force: false })
3174
3118
  if (useOldVersion) {
3175
3119
  more = more.config
3176
3120
  } else {