theprogrammablemind 7.12.8-beta.1 → 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 +222 -91
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.1",
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,
@@ -412,10 +427,13 @@ const hierarchyCanonical = (element) => {
412
427
  }
413
428
  }
414
429
 
415
- const isValidDef = (word, def, config) => {
430
+ const isValidWordDef = (word, def, config) => {
431
+ // TODO trie
432
+ /*
416
433
  if (!def.id) {
417
434
  throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
418
435
  }
436
+ */
419
437
  /*
420
438
  if (!def.initial) {
421
439
  throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "initial" property: ${JSON.stringify(def)}`
@@ -432,16 +450,20 @@ const hierarchyToCanonical = (edge) => {
432
450
 
433
451
  const addWord = (config, uuid) => ({ word, id, initial }) => {
434
452
  if (!config.words) {
435
- config.words = {}
453
+ config.words = {
454
+ literals: {},
455
+ patterns: [],
456
+ hierarchy: [],
457
+ }
436
458
  }
437
- const words = config.words
459
+ const literals = config.words.literals
438
460
  const def = { id, initial, uuid }
439
- if (words[word]) {
440
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
441
- words[word].unshift(def)
461
+ if (literals[word]) {
462
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
463
+ literals[word].unshift(def)
442
464
  }
443
465
  } else {
444
- words[word] = [def]
466
+ literals[word] = [def]
445
467
  }
446
468
  }
447
469
 
@@ -500,8 +522,17 @@ function configDup (config, options) {
500
522
  }
501
523
 
502
524
  function setWordsUUIDs (words, uuid) {
503
- for (const key in words) {
504
- 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
505
536
  }
506
537
  }
507
538
 
@@ -752,7 +783,7 @@ class Config {
752
783
  }
753
784
  const templateQueries = []
754
785
  if (this.instances && this.instances.length > 0) {
755
- for (const query of this.instances.slice(-1)[0].queries) {
786
+ for (const query of this.instances.slice(-1)[0].configs) {
756
787
  if (typeof query === 'string') {
757
788
  templateQueries.push(query)
758
789
  }
@@ -776,6 +807,7 @@ class Config {
776
807
  addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
777
808
  removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
778
809
  addWord: (...args) => this.addWord(...args, uuid),
810
+ addPattern: (...args) => this.addPattern(...args, uuid),
779
811
 
780
812
  getHierarchy: (...args) => this.config.hierarchy,
781
813
  getBridges: (...args) => this.config.bridges,
@@ -797,28 +829,6 @@ class Config {
797
829
  }
798
830
  }
799
831
 
800
- // return the config with just the elements from the included KM's
801
- baseConfig () {
802
- const operators = this.config.operators.filter((operator) => {
803
- return operator.uuid !== this.uuid
804
- })
805
- const bridges = this.config.bridges.filter((bridge) => {
806
- return bridge.uuid !== this.uuid
807
- })
808
- const words = {}
809
- for (const word in this.config.words) {
810
- const defs = this.config.words[word].filter((def) => def.uuid !== this.uuid)
811
- if (defs.length > 0) {
812
- words[word] = defs
813
- }
814
- }
815
- return {
816
- operators,
817
- bridges,
818
- words
819
- }
820
- }
821
-
822
832
  getCounter (maybeName = '') {
823
833
  const counter = this.configCounter
824
834
  this.configCounter += 1
@@ -855,7 +865,11 @@ class Config {
855
865
  namespaced: {}
856
866
  },
857
867
  description: '',
858
- words: {}, // Done
868
+ words: {
869
+ literals: {},
870
+ patterns: [],
871
+ hierarchy: [],
872
+ }, // Done
859
873
  floaters: [],
860
874
  implicits: [],
861
875
  flatten: [],
@@ -1114,8 +1128,8 @@ class Config {
1114
1128
  return elements.map(toCanonicalQuery)
1115
1129
  }
1116
1130
 
1117
- const templateQueries = toCanonicalQueries(template.queries || []).map(helpers.updateQueries)
1118
- const instanceQueries = toCanonicalQueries(instance.queries || [])
1131
+ const templateQueries = toCanonicalQueries(template.configs || []).map(helpers.updateQueries)
1132
+ const instanceQueries = toCanonicalQueries(instance.configs || [])
1119
1133
  let sameQueries = true
1120
1134
  let startOfChanges
1121
1135
  for (let iq = 0; iq < templateQueries.length; ++iq) {
@@ -1136,7 +1150,6 @@ class Config {
1136
1150
  if (templateQueries.length < instanceQueries.length) {
1137
1151
  startOfChanges = instanceQueries.length
1138
1152
  }
1139
- // const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
1140
1153
 
1141
1154
  if (debug) {
1142
1155
  if (!(instance && sameQueries && sameFragments)) {
@@ -1145,8 +1158,6 @@ class Config {
1145
1158
  console.log('sameFragments', sameFragments)
1146
1159
  // console.log("templateFragments", templateFragments)
1147
1160
  // console.log("instanceFragments", instanceFragments)
1148
- // console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
1149
- // console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
1150
1161
  }
1151
1162
  }
1152
1163
  if (startOfChanges || instance.resultss) {
@@ -1157,13 +1168,13 @@ class Config {
1157
1168
  }
1158
1169
 
1159
1170
  validifyTemplate (template) {
1160
- if (!template.queries && !template.fragments) {
1161
- 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`)
1162
1173
  }
1163
- for (const query of template.queries || []) {
1174
+ for (const query of template.configs || []) {
1164
1175
  if (typeof query === 'string') {
1165
1176
  } else if (query instanceof Config) {
1166
- 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).`)
1167
1178
  }
1168
1179
  }
1169
1180
  }
@@ -1180,7 +1191,7 @@ class Config {
1180
1191
  this.logs.push(`loading template for ${this.name}`)
1181
1192
  if (options.rebuild) {
1182
1193
  // TODO fix beforeQuery
1183
- template = { fragments: [], queries: [], ...template }
1194
+ template = { fragments: [], configs: [], ...template }
1184
1195
  template.fragments = template.fragments.concat(this.dynamicFragments)
1185
1196
  client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1186
1197
  } else {
@@ -1188,7 +1199,7 @@ class Config {
1188
1199
  // this.initInstances.push({ ...instance, name: config.name })
1189
1200
  const isEmpty = (instance) => {
1190
1201
  const properties = [
1191
- 'queries',
1202
+ 'configs',
1192
1203
  'resultss',
1193
1204
  'fragments',
1194
1205
  'semantics',
@@ -1201,7 +1212,7 @@ class Config {
1201
1212
  for (let i = 0; i < instance.resultss.length; ++i) {
1202
1213
  const result = instance.resultss[i]
1203
1214
  if (result.apply) {
1204
- result.apply = template.queries[i]
1215
+ result.apply = template.configs[i]
1205
1216
  }
1206
1217
  }
1207
1218
  instance.name = this.name
@@ -1441,21 +1452,41 @@ class Config {
1441
1452
 
1442
1453
  addWordInternal (word, def, uuid) {
1443
1454
  if (!this.config.words) {
1444
- this.config.words = {}
1455
+ this.config.words = {
1456
+ literals: {},
1457
+ patterns: [],
1458
+ hierarchy: [],
1459
+ }
1445
1460
  }
1446
- const words = this.config.words
1461
+
1462
+ const literals = this.config.words.literals
1447
1463
  def = Object.assign({}, def, { uuid: uuid || this._uuid })
1448
- if (words[word]) {
1449
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
1450
- words[word].unshift(def)
1464
+ if (literals[word]) {
1465
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
1466
+ literals[word].unshift(def)
1451
1467
  }
1452
1468
  } else {
1453
- words[word] = [def]
1469
+ literals[word] = [def]
1454
1470
  }
1455
1471
 
1456
1472
  this._delta.json.words.push({ action: 'add', word, def })
1457
1473
  }
1458
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
+
1459
1490
  getAPI (uuid) {
1460
1491
  if (this._uuid === uuid) {
1461
1492
  return this.api
@@ -1649,13 +1680,35 @@ class Config {
1649
1680
  config.generators = config.generators.filter((element) => !element.development)
1650
1681
  config.semantics = config.semantics.filter((element) => !element.development)
1651
1682
  config.hierarchy = (config.hierarchy).filter((element) => !element.development)
1652
- for (const word in config.words) {
1653
- const defs = config.words[word] || []
1654
- config.words[word] = defs.filter((def) => !def.development)
1655
- if (config.words[word].length == 0) {
1656
- 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})
1700
+ }
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)
1657
1709
  }
1658
1710
  }
1711
+ config.words.hierarchy = hierarchyPrime
1659
1712
  }
1660
1713
 
1661
1714
  // configs = [ { config, namespace } ... ]
@@ -1669,7 +1722,7 @@ class Config {
1669
1722
 
1670
1723
  config.operators = config.operators || []
1671
1724
  config.bridges = config.bridges || []
1672
- config.words = config.words || {}
1725
+ config.words = config.words || { literals: {}, patterns: [], hierarchy: [] }
1673
1726
  config.generators = config.generators || []
1674
1727
  config.semantics = config.semantics || []
1675
1728
  config.hierarchy = config.hierarchy || []
@@ -1699,7 +1752,7 @@ class Config {
1699
1752
  this.instances = []
1700
1753
  this.logs = []
1701
1754
  this.dynamicFragments = []
1702
- // 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
1703
1756
  this.transitoryMode = false
1704
1757
 
1705
1758
  // check for duplicate bridges
@@ -1721,11 +1774,8 @@ class Config {
1721
1774
  }
1722
1775
 
1723
1776
  if (config && config.words) {
1724
- for (const word of Object.keys(config.words)) {
1725
- for (const def of config.words[word]) {
1726
- isValidDef(word, def, config)
1727
- }
1728
- }
1777
+ initWords(config.words)
1778
+ isValidWordDef(config.words)
1729
1779
  }
1730
1780
 
1731
1781
  if (config && config.priorities) {
@@ -2041,10 +2091,28 @@ class Config {
2041
2091
  this.config.namespaces = ns
2042
2092
  }
2043
2093
 
2044
- if (this.config.words) {
2045
- const words = this.config.words
2046
- for (const key in words) {
2047
- 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) => {
2048
2116
  if (o.uuid) {
2049
2117
  if (map[o.uuid]) {
2050
2118
  o.uuid = map[o.uuid]
@@ -2056,6 +2124,22 @@ class Config {
2056
2124
  }
2057
2125
  }
2058
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
+
2059
2143
  if (this.config.bridges) {
2060
2144
  this.config.bridges.forEach((bridge) => {
2061
2145
  if (bridge.uuid) {
@@ -2228,11 +2312,14 @@ class Config {
2228
2312
  }
2229
2313
  */
2230
2314
 
2231
- for (const key in this.config.words) {
2232
- const values = this.config.words[key]
2233
- if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2234
- debugBreak()
2235
- 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
+ }
2236
2323
  }
2237
2324
  }
2238
2325
 
@@ -2446,7 +2533,7 @@ class Config {
2446
2533
  this.config.hierarchy = []
2447
2534
  this.config.priorities = []
2448
2535
  this.config.associations = { positive: [], negative: [] }
2449
- this.config.words = {}
2536
+ this.config.words = initWords({})
2450
2537
 
2451
2538
  for (let i = 0; i < addInternals.length; ++i) {
2452
2539
  let name
@@ -2633,13 +2720,25 @@ class Config {
2633
2720
  }
2634
2721
 
2635
2722
  if (config.words) {
2636
- const words = {}
2637
- for (const word in config.words) {
2638
- 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) => {
2639
2726
  return Object.assign({}, word, { id: toNS(word.id), uuid })
2640
2727
  })
2641
2728
  }
2642
- 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
+ }
2643
2742
  }
2644
2743
 
2645
2744
  if (config.hierarchy) {
@@ -2760,6 +2859,7 @@ class Config {
2760
2859
  throw new Error(`Setting invalid property ${property}`)
2761
2860
  }
2762
2861
 
2862
+ // TODO trie
2763
2863
  if (property == 'words') {
2764
2864
  for (const word in value) {
2765
2865
  for (const def of value[word]) {
@@ -2907,16 +3007,36 @@ class Config {
2907
3007
  continue
2908
3008
  }
2909
3009
  if (key === 'words') {
2910
- const configWords = this.config.words
2911
- const moreWords = more.words
2912
- for (const word of Object.keys(moreWords)) {
2913
- if (!configWords[word]) {
2914
- 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)
2915
3031
  }
3032
+ }
3033
+ if (more.words.hierarchy) {
3034
+ const hierarchy = this.config.words.hierarchy
3035
+ const moreHierarchy = more.words.hierarchy
2916
3036
  if (addFirst) {
2917
- configWords[word] = moreWords[word].concat(configWords[word])
3037
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
2918
3038
  } else {
2919
- configWords[word] = configWords[word].concat(moreWords[word])
3039
+ this.config.words.hierarchy = hierarchy.concat(moreHierarchy)
2920
3040
  }
2921
3041
  }
2922
3042
  } else if (key === 'name') {
@@ -3028,14 +3148,25 @@ class Config {
3028
3148
  continue
3029
3149
  }
3030
3150
  if (key === 'words') {
3031
- const configWords = this.config.words
3032
- const moreWords = more.words
3033
- for (const word of Object.keys(moreWords)) {
3034
- if (!configWords[word]) {
3035
- 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])
3036
3159
  }
3037
- // configWords[word] = configWords[word].concat(moreWords[word])
3038
- 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)
3039
3170
  }
3040
3171
  } else if (key === 'name') {
3041
3172
  /*