theprogrammablemind 7.12.8-beta.0 → 7.12.8-beta.10

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.
Files changed (3) hide show
  1. package/client.js +27 -30
  2. package/package.json +1 -1
  3. package/src/config.js +236 -93
package/client.js CHANGED
@@ -646,17 +646,15 @@ const loadInstance = (config, instance) => {
646
646
  const results = instance.resultss[i]
647
647
  if (results.extraConfig) {
648
648
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
649
- // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
650
649
  const uuid = config.nameToUUID(instance.name)
651
650
  // used to do a CLONE
652
- // config.addInternal(_.cloneDeep(instance.template.queries[i]), { uuid, addFirst: true, handleCalculatedProps: true })
653
- config.addInternal(instance.template.queries[i], { uuid, addFirst: true, handleCalculatedProps: true })
651
+ config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
654
652
  } else if (results.apply) {
655
653
  const objects = config.get('objects')
656
654
  const args = { objects, getObjects: getObjects(objects) }
657
- if (instance.queries) {
655
+ if (instance.configs) {
658
656
  args.isInstance = `instance${i}`
659
- args.instance = instance.queries[i]
657
+ args.instance = instance.configs[i]
660
658
  }
661
659
 
662
660
  const uuid = config.nameToUUID(instance.name)
@@ -824,15 +822,27 @@ const getConfigForTest = (config, testConfig) => {
824
822
  // configForTest[key] = config.config[key]
825
823
  if (key === 'words') {
826
824
  const words = config.config.words
827
- configForTest.words = {}
828
- for (const key of Object.keys(words)) {
825
+ configForTest.words = {
826
+ literals: {},
827
+ patterns: [],
828
+ hierarchy: [],
829
+ }
830
+
831
+ const literals = config.config.words.literals
832
+ for (const key in literals) {
829
833
  const defs = []
830
- for (const def of words[key]) {
834
+ for (const def of literals[key]) {
831
835
  // TODO handle thie uuids the right way
832
836
  defs.push(Object.assign({}, def, { uuid: undefined }))
833
837
  }
834
- configForTest.words[key] = defs
838
+ configForTest.words.literals[key] = defs
835
839
  }
840
+
841
+ const patterns = config.config.words.patterns
842
+ configForTest.words.patterns = patterns.map((pattern) => Object.assign({}, pattern, { uuid: undefined }))
843
+
844
+ const hierarchy = config.config.words.hierarchy
845
+ configForTest.words.hierarchy = hierarchy.map((hierarchy) => Object.assign({}, hierarchy, { uuid: undefined }))
836
846
  } else if (key === 'operators') {
837
847
  configForTest.operators = config.config.operators.map((operator) => Object.assign({}, operator, { uuid: undefined }))
838
848
  } else if (key === 'bridges') {
@@ -1305,12 +1315,12 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1305
1315
  associations: [],
1306
1316
  learned_contextual_priorities: []
1307
1317
  }
1308
- const looper = async (queries) => {
1309
- if (queries.length === 0) {
1318
+ const looper = async (configs) => {
1319
+ if (configs.length === 0) {
1310
1320
  finish()
1311
1321
  return
1312
1322
  }
1313
- const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = queries.shift()
1323
+ const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = configs.shift()
1314
1324
  // queries are strings or { query: "blah", development: true/false }
1315
1325
  if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
1316
1326
  let query = queryOrExtraConfig
@@ -1362,7 +1372,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1362
1372
  accumulators[property].push(results)
1363
1373
  accumulators.associations = accumulators.associations.concat(results.associations)
1364
1374
  accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
1365
- await looper(queries)
1375
+ await looper(configs)
1366
1376
  } catch (e) {
1367
1377
  const error = { errors: [e], query: query.query }
1368
1378
  config.config.skipSemantics = null
@@ -1376,7 +1386,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1376
1386
  setupArgs(args, config, config.logs, hierarchy)
1377
1387
  initFunction(args)
1378
1388
  accumulators[property].push({ apply: queryOrExtraConfig })
1379
- await looper(queries)
1389
+ await looper(configs)
1380
1390
  } else {
1381
1391
  // extra config is def from a time like operators or bridges or words etc
1382
1392
  // it will just get added to the config
@@ -1392,7 +1402,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1392
1402
  throw new Error(`Error processing extra config${where}: ${e.stack}}`)
1393
1403
  }
1394
1404
  accumulators[property].push({ extraConfig: true, ...extraConfig })
1395
- await looper(queries)
1405
+ await looper(configs)
1396
1406
  }
1397
1407
  }
1398
1408
  }
@@ -1432,7 +1442,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1432
1442
  return template
1433
1443
  }
1434
1444
  stabilizeOutput(accumulators)
1435
- runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries.map(updateQueries) }, accumulators), 0, 2))
1445
+ runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ configs: template.configs.map(updateQueries) }, accumulators), 0, 2))
1436
1446
 
1437
1447
  // km tests file
1438
1448
  const testsName = `./${target}.test.json`
@@ -1451,7 +1461,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1451
1461
  }
1452
1462
  let todo = []
1453
1463
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1454
- todo = todo.concat((template.queries || []).map((query, index) => {
1464
+ todo = todo.concat((template.configs || []).map((query, index) => {
1455
1465
  let pr
1456
1466
  if (index < startOfChanges) {
1457
1467
  pr = previousResultss[index]
@@ -1501,19 +1511,6 @@ const knowledgeModuleImpl = async ({
1501
1511
  acceptsAdditionalConfig = false,
1502
1512
  ...rest
1503
1513
  } = {}) => {
1504
- /*
1505
- if (description == 'fastfood related concepts') {
1506
- debugger
1507
- global.old = template.template.queries[91].bridges[0]
1508
- }
1509
- let old
1510
- if (template && template.template && template.template.queries) {
1511
- old = template.template.queries
1512
- template.template.queries = _.cloneDeep(template.template.queries)
1513
- template.wasCopied = true
1514
- }
1515
- */
1516
-
1517
1514
  const unknownArgs = Object.keys(rest)
1518
1515
  if (unknownArgs.length > 0) {
1519
1516
  throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
package/package.json CHANGED
@@ -65,6 +65,6 @@
65
65
  "json-stable-stringify": "^1.0.1",
66
66
  "node-fetch": "^2.6.1"
67
67
  },
68
- "version": "7.12.8-beta.0",
68
+ "version": "7.12.8-beta.10",
69
69
  "license": "UNLICENSED"
70
70
  }
package/src/config.js CHANGED
@@ -26,6 +26,19 @@ const config_toServer = (config) => {
26
26
  // cant change things because copy breaks something
27
27
  }
28
28
 
29
+ const initWords = (words) => {
30
+ if (!words.literals) {
31
+ words.literals = {}
32
+ }
33
+ if (!words.patterns) {
34
+ words.patterns = []
35
+ }
36
+ if (!words.hierarchy) {
37
+ words.hierarchy = []
38
+ }
39
+ return words
40
+ }
41
+
29
42
  const debugPriority = (priority) => {
30
43
  if (global.entodictonDebugPriority) {
31
44
  if (helpers.subPriority(entodictonDebugPriority, priority)) {
@@ -123,6 +136,7 @@ const validConfigProps = (config) => {
123
136
 
124
137
  const setupInitializerFNArgs = (config, args) => {
125
138
  const aw = (word, def) => config.addWord(word, def, args.uuid)
139
+ const ap = (pattern, def) => config.addPattern(pattern, def, args.uuid)
126
140
  const ag = (generator) => config.addGenerator(generator, args.uuid, config.name)
127
141
  const km = (name) => config.getConfig(name)
128
142
  const apis = (name) => config.getConfig(name).api
@@ -130,6 +144,7 @@ const setupInitializerFNArgs = (config, args) => {
130
144
  return {
131
145
  ...args,
132
146
  addWord: aw,
147
+ addPattern: ap,
133
148
  addGenerator: ag,
134
149
  config: config.getPseudoConfig(args.uuid, args.currentConfig),
135
150
  km,
@@ -213,6 +228,9 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
213
228
  config.addHierarchy(child, bridge.id)
214
229
  }
215
230
  }
231
+ if (bridge.operator) {
232
+ config.addOperator(bridge.operator, uuid || config.uuid)
233
+ }
216
234
  if (bridge.parents) {
217
235
  for (const parent of bridge.parents) {
218
236
  config.addHierarchy(bridge.id, parent)
@@ -329,7 +347,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
329
347
  if (bridge.semantic) {
330
348
  const semantic = {
331
349
  where: bridge.semantic.where || bridge.where || client.where(3),
332
- match: ({ context }) => bridge.id == context.marker,
350
+ match: ({ context }) => bridge.id == context.marker && !context.evaluate,
333
351
  apply: (args) => bridge.semantic(args),
334
352
  applyWrapped: bridge.semantic,
335
353
  property: 'semantic'
@@ -348,7 +366,7 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
348
366
  if (moreConfig.bridges) {
349
367
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
350
368
  bridge = { ...bridge }
351
- const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
369
+ const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
352
370
  'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
353
371
  helpers.validProps(valid, bridge, 'bridge')
354
372
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
@@ -409,10 +427,13 @@ const hierarchyCanonical = (element) => {
409
427
  }
410
428
  }
411
429
 
412
- const isValidDef = (word, def, config) => {
430
+ const isValidWordDef = (word, def, config) => {
431
+ // TODO trie
432
+ /*
413
433
  if (!def.id) {
414
434
  throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
415
435
  }
436
+ */
416
437
  /*
417
438
  if (!def.initial) {
418
439
  throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "initial" property: ${JSON.stringify(def)}`
@@ -429,16 +450,20 @@ const hierarchyToCanonical = (edge) => {
429
450
 
430
451
  const addWord = (config, uuid) => ({ word, id, initial }) => {
431
452
  if (!config.words) {
432
- config.words = {}
453
+ config.words = {
454
+ literals: {},
455
+ patterns: [],
456
+ hierarchy: [],
457
+ }
433
458
  }
434
- const words = config.words
459
+ const literals = config.words.literals
435
460
  const def = { id, initial, uuid }
436
- if (words[word]) {
437
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
438
- words[word].unshift(def)
461
+ if (literals[word]) {
462
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
463
+ literals[word].unshift(def)
439
464
  }
440
465
  } else {
441
- words[word] = [def]
466
+ literals[word] = [def]
442
467
  }
443
468
  }
444
469
 
@@ -453,6 +478,7 @@ const normalizeConfig = (config) => {
453
478
  }
454
479
  }
455
480
  }
481
+
456
482
  if (config.bridges) {
457
483
  for (const bridge of config.bridges) {
458
484
  if (!bridge.level) {
@@ -471,6 +497,14 @@ const normalizeConfig = (config) => {
471
497
  }
472
498
  }
473
499
  }
500
+
501
+ if (config.operators) {
502
+ for (let i = 0; i < config.operators.length; ++i) {
503
+ if (typeof config.operators[i] === 'string') {
504
+ config.operators[i] = { pattern: config.operators[i] }
505
+ }
506
+ }
507
+ }
474
508
  }
475
509
  }
476
510
 
@@ -488,8 +522,17 @@ function configDup (config, options) {
488
522
  }
489
523
 
490
524
  function setWordsUUIDs (words, uuid) {
491
- for (const key in words) {
492
- words[key] = words[key].map((o) => Object.assign(o, { uuid }))
525
+ const literals = words.literals
526
+ for (const key in literals) {
527
+ literals[key] = literals[key].map((o) => Object.assign(o, { uuid }))
528
+ }
529
+ const patterns = words.patterns
530
+ for (const pattern of patterns) {
531
+ pattern.defs.map((def) => Object.assign(def, { uuid }))
532
+ }
533
+ const hierarchy = words.hierarchy
534
+ for (const pair of hierarchy) {
535
+ pair.uuid = uuid
493
536
  }
494
537
  }
495
538
 
@@ -740,7 +783,7 @@ class Config {
740
783
  }
741
784
  const templateQueries = []
742
785
  if (this.instances && this.instances.length > 0) {
743
- for (const query of this.instances.slice(-1)[0].queries) {
786
+ for (const query of this.instances.slice(-1)[0].configs) {
744
787
  if (typeof query === 'string') {
745
788
  templateQueries.push(query)
746
789
  }
@@ -764,6 +807,7 @@ class Config {
764
807
  addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
765
808
  removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
766
809
  addWord: (...args) => this.addWord(...args, uuid),
810
+ addPattern: (...args) => this.addPattern(...args, uuid),
767
811
 
768
812
  getHierarchy: (...args) => this.config.hierarchy,
769
813
  getBridges: (...args) => this.config.bridges,
@@ -785,28 +829,6 @@ class Config {
785
829
  }
786
830
  }
787
831
 
788
- // return the config with just the elements from the included KM's
789
- baseConfig () {
790
- const operators = this.config.operators.filter((operator) => {
791
- return operator.uuid !== this.uuid
792
- })
793
- const bridges = this.config.bridges.filter((bridge) => {
794
- return bridge.uuid !== this.uuid
795
- })
796
- const words = {}
797
- for (const word in this.config.words) {
798
- const defs = this.config.words[word].filter((def) => def.uuid !== this.uuid)
799
- if (defs.length > 0) {
800
- words[word] = defs
801
- }
802
- }
803
- return {
804
- operators,
805
- bridges,
806
- words
807
- }
808
- }
809
-
810
832
  getCounter (maybeName = '') {
811
833
  const counter = this.configCounter
812
834
  this.configCounter += 1
@@ -843,7 +865,11 @@ class Config {
843
865
  namespaced: {}
844
866
  },
845
867
  description: '',
846
- words: {}, // Done
868
+ words: {
869
+ literals: {},
870
+ patterns: [],
871
+ hierarchy: [],
872
+ }, // Done
847
873
  floaters: [],
848
874
  implicits: [],
849
875
  flatten: [],
@@ -1102,8 +1128,8 @@ class Config {
1102
1128
  return elements.map(toCanonicalQuery)
1103
1129
  }
1104
1130
 
1105
- const templateQueries = toCanonicalQueries(template.queries || []).map(helpers.updateQueries)
1106
- const instanceQueries = toCanonicalQueries(instance.queries || [])
1131
+ const templateQueries = toCanonicalQueries(template.configs || []).map(helpers.updateQueries)
1132
+ const instanceQueries = toCanonicalQueries(instance.configs || [])
1107
1133
  let sameQueries = true
1108
1134
  let startOfChanges
1109
1135
  for (let iq = 0; iq < templateQueries.length; ++iq) {
@@ -1124,7 +1150,6 @@ class Config {
1124
1150
  if (templateQueries.length < instanceQueries.length) {
1125
1151
  startOfChanges = instanceQueries.length
1126
1152
  }
1127
- // const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
1128
1153
 
1129
1154
  if (debug) {
1130
1155
  if (!(instance && sameQueries && sameFragments)) {
@@ -1133,8 +1158,6 @@ class Config {
1133
1158
  console.log('sameFragments', sameFragments)
1134
1159
  // console.log("templateFragments", templateFragments)
1135
1160
  // console.log("instanceFragments", instanceFragments)
1136
- // console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
1137
- // console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
1138
1161
  }
1139
1162
  }
1140
1163
  if (startOfChanges || instance.resultss) {
@@ -1145,13 +1168,13 @@ class Config {
1145
1168
  }
1146
1169
 
1147
1170
  validifyTemplate (template) {
1148
- if (!template.queries && !template.fragments) {
1149
- throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: queries and fragments`)
1171
+ if (!template.configs && !template.fragments) {
1172
+ throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: configs and fragments`)
1150
1173
  }
1151
- for (const query of template.queries || []) {
1174
+ for (const query of template.configs || []) {
1152
1175
  if (typeof query === 'string') {
1153
1176
  } else if (query instanceof Config) {
1154
- throw new Error(`For the template for ${this.name}, each element in queries should be either a string or a structure with a config (not a Config object).`)
1177
+ throw new Error(`For the template for ${this.name}, each element in configs should be either a string or a structure with a config (not a Config object).`)
1155
1178
  }
1156
1179
  }
1157
1180
  }
@@ -1168,7 +1191,7 @@ class Config {
1168
1191
  this.logs.push(`loading template for ${this.name}`)
1169
1192
  if (options.rebuild) {
1170
1193
  // TODO fix beforeQuery
1171
- template = { fragments: [], queries: [], ...template }
1194
+ template = { fragments: [], configs: [], ...template }
1172
1195
  template.fragments = template.fragments.concat(this.dynamicFragments)
1173
1196
  client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1174
1197
  } else {
@@ -1176,7 +1199,7 @@ class Config {
1176
1199
  // this.initInstances.push({ ...instance, name: config.name })
1177
1200
  const isEmpty = (instance) => {
1178
1201
  const properties = [
1179
- 'queries',
1202
+ 'configs',
1180
1203
  'resultss',
1181
1204
  'fragments',
1182
1205
  'semantics',
@@ -1189,7 +1212,7 @@ class Config {
1189
1212
  for (let i = 0; i < instance.resultss.length; ++i) {
1190
1213
  const result = instance.resultss[i]
1191
1214
  if (result.apply) {
1192
- result.apply = template.queries[i]
1215
+ result.apply = template.configs[i]
1193
1216
  }
1194
1217
  }
1195
1218
  instance.name = this.name
@@ -1429,21 +1452,41 @@ class Config {
1429
1452
 
1430
1453
  addWordInternal (word, def, uuid) {
1431
1454
  if (!this.config.words) {
1432
- this.config.words = {}
1455
+ this.config.words = {
1456
+ literals: {},
1457
+ patterns: [],
1458
+ hierarchy: [],
1459
+ }
1433
1460
  }
1434
- const words = this.config.words
1461
+
1462
+ const literals = this.config.words.literals
1435
1463
  def = Object.assign({}, def, { uuid: uuid || this._uuid })
1436
- if (words[word]) {
1437
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
1438
- words[word].unshift(def)
1464
+ if (literals[word]) {
1465
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
1466
+ literals[word].unshift(def)
1439
1467
  }
1440
1468
  } else {
1441
- words[word] = [def]
1469
+ literals[word] = [def]
1442
1470
  }
1443
1471
 
1444
1472
  this._delta.json.words.push({ action: 'add', word, def })
1445
1473
  }
1446
1474
 
1475
+ addPattern (pattern, def, uuid) {
1476
+ if (!this.config.words) {
1477
+ this.config.words = {
1478
+ literals: {},
1479
+ patterns: [],
1480
+ hierarchy: [],
1481
+ }
1482
+ }
1483
+
1484
+ const patterns = this.config.words.patterns
1485
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
1486
+ patterns.unshift({ pattern, defs: [def] })
1487
+ this._delta.json.words.push({ action: 'add', pattern, defs: [def] })
1488
+ }
1489
+
1447
1490
  getAPI (uuid) {
1448
1491
  if (this._uuid === uuid) {
1449
1492
  return this.api
@@ -1637,13 +1680,35 @@ class Config {
1637
1680
  config.generators = config.generators.filter((element) => !element.development)
1638
1681
  config.semantics = config.semantics.filter((element) => !element.development)
1639
1682
  config.hierarchy = (config.hierarchy).filter((element) => !element.development)
1640
- for (const word in config.words) {
1641
- const defs = config.words[word] || []
1642
- config.words[word] = defs.filter((def) => !def.development)
1643
- if (config.words[word].length == 0) {
1644
- delete config.words[word]
1683
+
1684
+ const literals = config.words.literals
1685
+ for (const word in literals) {
1686
+ const defs = literals[word] || []
1687
+ literals[word] = defs.filter((def) => !def.development)
1688
+ if (literals[word].length == 0) {
1689
+ delete literals[word]
1690
+ }
1691
+ }
1692
+
1693
+ const patterns = config.words.patterns || []
1694
+ const patternsPrime = []
1695
+ for (const pattern of patterns) {
1696
+ let defs = pattern.defs || []
1697
+ defs = defs.filter((def) => !def.development)
1698
+ if (defs.length !== 0) {
1699
+ patternsPrime.push({...pattern, defs})
1645
1700
  }
1646
1701
  }
1702
+ config.words.patterns = patternsPrime
1703
+
1704
+ const hierarchy = config.words.hierarchy || []
1705
+ const hierarchyPrime = []
1706
+ for (const pair of hierarchy) {
1707
+ if (!pair.development) {
1708
+ hierarchyPrime.push(pair)
1709
+ }
1710
+ }
1711
+ config.words.hierarchy = hierarchyPrime
1647
1712
  }
1648
1713
 
1649
1714
  // configs = [ { config, namespace } ... ]
@@ -1657,7 +1722,7 @@ class Config {
1657
1722
 
1658
1723
  config.operators = config.operators || []
1659
1724
  config.bridges = config.bridges || []
1660
- config.words = config.words || {}
1725
+ config.words = config.words || { literals: {}, patterns: [], hierarchy: [] }
1661
1726
  config.generators = config.generators || []
1662
1727
  config.semantics = config.semantics || []
1663
1728
  config.hierarchy = config.hierarchy || []
@@ -1687,7 +1752,7 @@ class Config {
1687
1752
  this.instances = []
1688
1753
  this.logs = []
1689
1754
  this.dynamicFragments = []
1690
- // when running queries any bridges added are marked as transitory so that the associated will ignore those op's
1755
+ // when running configs any bridges added are marked as transitory so that the associated will ignore those op's
1691
1756
  this.transitoryMode = false
1692
1757
 
1693
1758
  // check for duplicate bridges
@@ -1709,11 +1774,8 @@ class Config {
1709
1774
  }
1710
1775
 
1711
1776
  if (config && config.words) {
1712
- for (const word of Object.keys(config.words)) {
1713
- for (const def of config.words[word]) {
1714
- isValidDef(word, def, config)
1715
- }
1716
- }
1777
+ initWords(config.words)
1778
+ isValidWordDef(config.words)
1717
1779
  }
1718
1780
 
1719
1781
  if (config && config.priorities) {
@@ -2029,10 +2091,28 @@ class Config {
2029
2091
  this.config.namespaces = ns
2030
2092
  }
2031
2093
 
2032
- if (this.config.words) {
2033
- const words = this.config.words
2034
- for (const key in words) {
2035
- words[key].forEach((o) => {
2094
+ if (!this.config.words) {
2095
+ this.config.words = {}
2096
+ }
2097
+
2098
+ if (this.config.words.literals) {
2099
+ const literals = this.config.words.literals
2100
+ for (const key in literals) {
2101
+ literals[key].forEach((o) => {
2102
+ if (o.uuid) {
2103
+ if (map[o.uuid]) {
2104
+ o.uuid = map[o.uuid]
2105
+ }
2106
+ } else {
2107
+ o.uuid = this._uuid
2108
+ }
2109
+ })
2110
+ }
2111
+ }
2112
+
2113
+ const mapDefList = (list) => {
2114
+ for (const element of list) {
2115
+ element.defs.forEach((o) => {
2036
2116
  if (o.uuid) {
2037
2117
  if (map[o.uuid]) {
2038
2118
  o.uuid = map[o.uuid]
@@ -2044,6 +2124,22 @@ class Config {
2044
2124
  }
2045
2125
  }
2046
2126
 
2127
+ if (this.config.words.patterns) {
2128
+ mapDefList(this.config.words.patterns)
2129
+ }
2130
+
2131
+ if (this.config.words.hierarchy) {
2132
+ for (const o of this.config.words.hierarchy) {
2133
+ if (o.uuid) {
2134
+ if (map[o.uuid]) {
2135
+ o.uuid = map[o.uuid]
2136
+ }
2137
+ } else {
2138
+ o.uuid = this._uuid
2139
+ }
2140
+ }
2141
+ }
2142
+
2047
2143
  if (this.config.bridges) {
2048
2144
  this.config.bridges.forEach((bridge) => {
2049
2145
  if (bridge.uuid) {
@@ -2216,11 +2312,14 @@ class Config {
2216
2312
  }
2217
2313
  */
2218
2314
 
2219
- for (const key in this.config.words) {
2220
- const values = this.config.words[key]
2221
- if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2222
- debugBreak()
2223
- return false
2315
+ const literals = this.config.words.literals
2316
+ if (literals) {
2317
+ for (const key in literals) {
2318
+ const values = literals[key]
2319
+ if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2320
+ debugBreak()
2321
+ return false
2322
+ }
2224
2323
  }
2225
2324
  }
2226
2325
 
@@ -2434,7 +2533,7 @@ class Config {
2434
2533
  this.config.hierarchy = []
2435
2534
  this.config.priorities = []
2436
2535
  this.config.associations = { positive: [], negative: [] }
2437
- this.config.words = {}
2536
+ this.config.words = initWords({})
2438
2537
 
2439
2538
  for (let i = 0; i < addInternals.length; ++i) {
2440
2539
  let name
@@ -2621,13 +2720,25 @@ class Config {
2621
2720
  }
2622
2721
 
2623
2722
  if (config.words) {
2624
- const words = {}
2625
- for (const word in config.words) {
2626
- words[word] = config.words[word].map((word) => {
2723
+ const literals = {}
2724
+ for (const word in config.words.literals) {
2725
+ literals[word] = config.words.literals[word].map((word) => {
2627
2726
  return Object.assign({}, word, { id: toNS(word.id), uuid })
2628
2727
  })
2629
2728
  }
2630
- config.words = words
2729
+ config.words.literals = literals
2730
+
2731
+ for (const pattern of config.words.patterns) {
2732
+ pattern.defs.forEach((def) => {
2733
+ def.id = toNS(def.id)
2734
+ def.uuid = uuid
2735
+ })
2736
+ }
2737
+
2738
+ for (const pair of config.words.hierarchy) {
2739
+ pair.child = toNS(pair.child)
2740
+ pair.parent = toNS(pair.parent)
2741
+ }
2631
2742
  }
2632
2743
 
2633
2744
  if (config.hierarchy) {
@@ -2748,6 +2859,7 @@ class Config {
2748
2859
  throw new Error(`Setting invalid property ${property}`)
2749
2860
  }
2750
2861
 
2862
+ // TODO trie
2751
2863
  if (property == 'words') {
2752
2864
  for (const word in value) {
2753
2865
  for (const def of value[word]) {
@@ -2895,16 +3007,36 @@ class Config {
2895
3007
  continue
2896
3008
  }
2897
3009
  if (key === 'words') {
2898
- const configWords = this.config.words
2899
- const moreWords = more.words
2900
- for (const word of Object.keys(moreWords)) {
2901
- if (!configWords[word]) {
2902
- configWords[word] = []
3010
+ if (more.words.literals) {
3011
+ const literals = this.config.words.literals
3012
+ const moreLiterals = more.words.literals
3013
+ for (const word of Object.keys(moreLiterals)) {
3014
+ if (!literals[word]) {
3015
+ literals[word] = []
3016
+ }
3017
+ if (addFirst) {
3018
+ literals[word] = moreLiterals[word].concat(literals[word])
3019
+ } else {
3020
+ literals[word] = literals[word].concat(moreLiterals[word])
3021
+ }
3022
+ }
3023
+ }
3024
+ if (more.words.patterns) {
3025
+ const patterns = this.config.words.patterns
3026
+ const morePatterns = more.words.patterns
3027
+ if (addFirst) {
3028
+ this.config.words.patterns = morePatterns.concat(patterns)
3029
+ } else {
3030
+ this.config.words.patterns = patterns.concat(morePatterns)
2903
3031
  }
3032
+ }
3033
+ if (more.words.hierarchy) {
3034
+ const hierarchy = this.config.words.hierarchy
3035
+ const moreHierarchy = more.words.hierarchy
2904
3036
  if (addFirst) {
2905
- configWords[word] = moreWords[word].concat(configWords[word])
3037
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
2906
3038
  } else {
2907
- configWords[word] = configWords[word].concat(moreWords[word])
3039
+ this.config.words.hierarchy = hierarchy.concat(moreHierarchy)
2908
3040
  }
2909
3041
  }
2910
3042
  } else if (key === 'name') {
@@ -3016,14 +3148,25 @@ class Config {
3016
3148
  continue
3017
3149
  }
3018
3150
  if (key === 'words') {
3019
- const configWords = this.config.words
3020
- const moreWords = more.words
3021
- for (const word of Object.keys(moreWords)) {
3022
- if (!configWords[word]) {
3023
- configWords[word] = []
3151
+ if (this.config.words.literals) {
3152
+ const literals = this.config.words.literals
3153
+ const moreLiterals = more.words.literals
3154
+ for (const word of Object.keys(moreLiterals)) {
3155
+ if (!literals[word]) {
3156
+ literals[word] = []
3157
+ }
3158
+ literals[word] = moreLiterals[word].concat(literals[word])
3024
3159
  }
3025
- // configWords[word] = configWords[word].concat(moreWords[word])
3026
- configWords[word] = moreWords[word].concat(configWords[word])
3160
+ }
3161
+ if (this.config.words.patterns) {
3162
+ const patterns = this.config.words.patterns
3163
+ const morePatterns = more.words.patterns
3164
+ this.config.words.patterns = morePatterns.concat(patterns)
3165
+ }
3166
+ if (this.config.words.hierarchy) {
3167
+ const hierarchy = this.config.words.hierarchy
3168
+ const moreHierarchy = more.words.hierarchy
3169
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3027
3170
  }
3028
3171
  } else if (key === 'name') {
3029
3172
  /*