theprogrammablemind 7.5.8-beta.73 → 7.5.8-beta.76

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/client.js CHANGED
@@ -10,12 +10,12 @@ const _ = require('lodash')
10
10
  const stringify = require('json-stable-stringify')
11
11
  const Lines = require('./lines')
12
12
  const flattens = require('./src/flatten')
13
- const { appendNoDups, InitCalls, updateQueries } = require('./src/helpers')
13
+ const { appendNoDups, InitCalls, updateQueries, safeNoDups } = require('./src/helpers')
14
14
  const runtime = require('./runtime')
15
15
  const sortJson = runtime.sortJson
16
16
 
17
- const getConfig_getObjectCheck = (testConfig) => {
18
- return (testConfig.checks && testConfig.checks.objects) || testConfig.check || []
17
+ const getConfig_getObjectsCheck = (testConfig) => {
18
+ return (testConfig.checks && testConfig.checks.objects) || []
19
19
  }
20
20
 
21
21
  const getConfig_getContextCheck = (testConfig) => {
@@ -26,6 +26,10 @@ const pickContext = (testConfig) => (context) => {
26
26
  return project(context, getConfig_getContextCheck(testConfig))
27
27
  }
28
28
 
29
+ const pickObjects = (testConfig, objects) => {
30
+ return project(objects, getConfig_getObjectsCheck(testConfig))
31
+ }
32
+
29
33
  const getAsk = (config) => (uuid) => (asks) => {
30
34
  for (let ask of asks) {
31
35
  config.addSemantic({
@@ -64,6 +68,12 @@ const getAsk = (config) => (uuid) => (asks) => {
64
68
  })
65
69
  }
66
70
 
71
+ const sameJSON = (json1, json2) => {
72
+ const sjson1 = sortJson(json1, { depth: 25 })
73
+ const sjson2 = sortJson(json2, { depth: 25 })
74
+ return JSON.stringify(sjson1) == JSON.stringify(sjson2)
75
+ }
76
+
67
77
  const vimdiff = (actualJSON, expectedJSON) => {
68
78
  const path = '.'
69
79
  const actual = sortJson(actualJSON, { depth: 25 })
@@ -424,7 +434,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
424
434
  if (isInstance) {
425
435
  console.log('error', e.error)
426
436
  }
427
- contextPrime = semantics.apply(args, { marker: 'error', context, reason: e.reason })
437
+ contextPrime = semantics.apply(args, { marker: 'error', context, reason: e.reason, error: e.stack })
428
438
  }
429
439
  }
430
440
  if (contextPrime.controlRemove) {
@@ -570,10 +580,22 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
570
580
  }
571
581
  }
572
582
 
573
- // instance template
583
+ // instance template loadTemplate
574
584
  const loadInstance = (config, instance) => {
575
585
  const transitoryMode = global.transitoryMode
576
586
  global.transitoryMode = false
587
+
588
+ if (instance && (instance.associations || instance.learned_contextual_priorities)) {
589
+ if (!config.config.retrain) {
590
+ if (instance.associations) {
591
+ config.addAssociations(instance.associations)
592
+ }
593
+ if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
594
+ config.addContextualPriorities(instance.learned_contextual_priorities)
595
+ }
596
+ }
597
+ }
598
+
577
599
  const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
578
600
  // for (const results of (instance.resultss || [])) {
579
601
  for (const i in (instance.resultss || [])) {
@@ -583,7 +605,13 @@ const loadInstance = (config, instance) => {
583
605
  // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
584
606
  config.addInternal(instance.template.queries[i], { addFirst: true, handleCalculatedProps: true } )
585
607
  } else {
608
+ if (results.skipSemantics) {
609
+ config.config.skipSemantics = results.skipSemantics
610
+ }
586
611
  processContextsB({ config, hierarchy, json: results/*, generators, semantics */, commandLineArgs: {}, isInstance: `instance${i}`, instance: instance.queries[i] })
612
+ if (results.skipSemantics) {
613
+ config.config.skipSemantics = null
614
+ }
587
615
  }
588
616
  }
589
617
  global.transitoryMode = transitoryMode
@@ -670,6 +698,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
670
698
  const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
671
699
  processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
672
700
  response.associations = json.associations
701
+ response.learned_contextual_priorities = json.learned_contextual_priorities
673
702
  response.hierarchy = json.hierarchy
674
703
  response.load_cache_time += json.load_cache_time
675
704
  appendNoDups(response.logs, json.logs)
@@ -797,33 +826,13 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
797
826
  const pickedExpectedContexts = expected.contexts.map(pickContext(testConfig))
798
827
  const failedCheckedContexts = !matching(pickedResultContexts, pickedExpectedContexts)
799
828
 
800
- const pickEm = (getObjects) => {
801
- const picked = {}
802
- for (let prop of getConfig_getObjectCheck(testConfig)) {
803
- if (prop.km) {
804
- c = config.getConfig(prop.km)
805
- o = getObjects(prop.km)
806
- picked[prop.km] = {}
807
- for (let p of getConfig_getObjectCheck(c.testConfig)) {
808
- if (p.km) {
809
- continue
810
- }
811
- picked[p] = o[p]
812
- }
813
- } else {
814
- picked[prop] = getObjects(testConfigName)[prop]
815
- }
816
- }
817
- return picked
818
- }
819
829
  const expectedGetObjects = (name) => {
820
830
  if (!name) {
821
831
  name = config.name
822
832
  }
823
833
  return expected.objects.namespaced[expected.objects.nameToUUID[name]]
824
834
  }
825
- sortJson(pickEm(expectedGetObjects), { depth: 25 })
826
- const expected_checked = sortJson(pickEm(expectedGetObjects), { depth: 25 })
835
+ const expected_checked = sortJson(pickObjects(testConfig, objects), { depth: 25 })
827
836
  const actualGetObjects = (name) => {
828
837
  if (!name) {
829
838
  name = config.name
@@ -831,7 +840,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
831
840
  const km = config.configs.find( (km) => km.name == name )
832
841
  return config.config.objects.namespaced[km.uuid]
833
842
  }
834
- const actual_checked = sortJson(pickEm(actualGetObjects), { depth: 25 })
843
+ const actual_checked = sortJson(pickObjects(testConfig, actualGetObjects(testConfigName)), { depth: 25 })
835
844
  const failed_checked = !matching(actual_objects, expected_objects)
836
845
 
837
846
  const failed_checks = !matching(actual_objects, expected_objects)
@@ -1155,7 +1164,8 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
1155
1164
  console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
1156
1165
  }
1157
1166
  }
1158
- const picked = pickEm()
1167
+ const objects = config.get('objects').namespaced[config.uuid]
1168
+ const picked = sortJson(pickObjects(config.testConfig, objects), { depth: 25 })
1159
1169
  if (!_.isEmpty(picked)) {
1160
1170
  console.log('--- Object showing only the checked values ---')
1161
1171
  console.log(JSON.stringify(picked, null, 2))
@@ -1207,13 +1217,14 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
1207
1217
  }
1208
1218
  }
1209
1219
 
1210
- // loadTemplate BuiltTemplate
1220
+ // builtTemplate saveInstance
1211
1221
  const rebuildTemplate = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
1212
1222
  const accumulators = {
1213
1223
  resultss: [],
1214
1224
  fragments: [],
1215
1225
  semantics: [],
1216
1226
  associations: [],
1227
+ learned_contextual_priorities: [],
1217
1228
  }
1218
1229
  const looper = async (queries) => {
1219
1230
  if (queries.length === 0) {
@@ -1241,7 +1252,6 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
1241
1252
  }
1242
1253
  }
1243
1254
  }
1244
-
1245
1255
  try {
1246
1256
  const results = await _process(config, query.query, {initializer, rebuildingTemplate: true})
1247
1257
  if (config.config.debug) {
@@ -1258,10 +1268,12 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
1258
1268
  global.transitoryMode = transitoryMode
1259
1269
  config.config.skipSemantics = null
1260
1270
  results.query = query.query
1271
+ results.skipSemantics = skipSemantics
1261
1272
  results.development = query.development
1262
1273
  results.key = { query: query.query, hierarchy }
1263
1274
  accumulators[property].push(results)
1264
1275
  accumulators.associations = accumulators.associations.concat(results.associations)
1276
+ accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
1265
1277
  await looper(queries)
1266
1278
  } catch(e) {
1267
1279
  const error = { errors: [e], query: query.query };
@@ -1306,6 +1318,7 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
1306
1318
  delete result.version
1307
1319
  result.hierarchy.sort()
1308
1320
  stabilizeAssociations(result.associations)
1321
+ result.learned_contextual_priorities = safeNoDups(result.learned_contextual_priorities)
1309
1322
  }
1310
1323
  }
1311
1324
  }
@@ -1326,14 +1339,14 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
1326
1339
 
1327
1340
  const toProperties = (queryStringOrProperties) => {
1328
1341
  if (typeof queryStringOrProperties == 'string') {
1329
- return { query: queryStringOrProperties}
1342
+ return { query: queryStringOrProperties }
1330
1343
  } else {
1331
1344
  return queryStringOrProperties
1332
1345
  }
1333
1346
  }
1334
1347
  let todo = []
1335
- todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false } }))
1336
- todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } }))
1348
+ todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1349
+ todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false || query.skipSemantics} }))
1337
1350
  todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
1338
1351
  todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
1339
1352
  await looper(Object.assign([], todo))
@@ -1439,7 +1452,7 @@ const knowledgeModule = async ({
1439
1452
  parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
1440
1453
  parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
1441
1454
  parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
1442
- parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server. for example --print wb' })
1455
+ parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server x == contextual priorities. for example --print wb' })
1443
1456
  parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
1444
1457
  parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
1445
1458
  parser.add_argument('-dl', '--debugLoops', { action: 'store_true', help: 'When running with the --debugLoops flag the logs calls to semantics and generators will be immediately written to the console '})
@@ -1552,26 +1565,6 @@ const knowledgeModule = async ({
1552
1565
 
1553
1566
  config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
1554
1567
 
1555
- if (template) {
1556
- const needsRebuild = config.needsRebuild(template.template, template.instance, options)
1557
- if (needsRebuild) {
1558
- console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
1559
-
1560
- }
1561
- config.load(template.template, template.instance, { rebuild: needsRebuild })
1562
- if (config.name == 'ui') {
1563
- console.log('config.COUNTER', config.COUNTER)
1564
- debugger
1565
- }
1566
- if (needsRebuild) {
1567
- return
1568
- }
1569
- }
1570
-
1571
- if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
1572
- config.addAssociationsFromTests(config.tests);
1573
- }
1574
-
1575
1568
  let configPrinted = false
1576
1569
  const printConfig = () => {
1577
1570
  if (configPrinted) {
@@ -1636,6 +1629,11 @@ const knowledgeModule = async ({
1636
1629
  console.log(JSON.stringify(priority))
1637
1630
  }
1638
1631
  }
1632
+ if (args.print.includes('x')) {
1633
+ for (let contextual_priority of config.config.contextual_priorities) {
1634
+ console.log(JSON.stringify(contextual_priority))
1635
+ }
1636
+ }
1639
1637
  if (args.print.includes('h')) {
1640
1638
  for (let edge of config.config.hierarchy) {
1641
1639
  console.log(JSON.stringify(edge))
@@ -1663,6 +1661,24 @@ const knowledgeModule = async ({
1663
1661
  }
1664
1662
  }
1665
1663
 
1664
+ if (template) {
1665
+ const needsRebuild = config.needsRebuild(template.template, template.instance, options)
1666
+ if (needsRebuild) {
1667
+ console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
1668
+ options.rebuild = true
1669
+ config.config.rebuild = true
1670
+ }
1671
+ config.load(template.template, template.instance, { rebuild: needsRebuild })
1672
+ printConfig()
1673
+ if (needsRebuild) {
1674
+ return
1675
+ }
1676
+ }
1677
+
1678
+ if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
1679
+ config.addAssociationsFromTests(config.tests);
1680
+ }
1681
+
1666
1682
  if (args.retrain) {
1667
1683
  config.config.retrain = true
1668
1684
  }
@@ -1718,7 +1734,7 @@ const knowledgeModule = async ({
1718
1734
  if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
1719
1735
  hasError = true
1720
1736
  }
1721
- if (JSON.stringify(result.expected.checkedContexts) !== JSON.stringify(result.actual.checkedContexts)) {
1737
+ if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
1722
1738
  hasError = true
1723
1739
  }
1724
1740
  }
@@ -1784,7 +1800,7 @@ const knowledgeModule = async ({
1784
1800
  newError = true
1785
1801
  headerShown = true
1786
1802
  }
1787
- if (JSON.stringify(result.expected.checkedContexts) !== JSON.stringify(result.actual.checkedContexts)) {
1803
+ if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
1788
1804
  if (!headerShown) {
1789
1805
  console.log(' Failure')
1790
1806
  }
package/package.json CHANGED
@@ -64,6 +64,6 @@
64
64
  "json-stable-stringify": "^1.0.1",
65
65
  "node-fetch": "^2.6.1"
66
66
  },
67
- "version": "7.5.8-beta.73",
67
+ "version": "7.5.8-beta.76",
68
68
  "license": "ISC"
69
69
  }
package/src/config.js CHANGED
@@ -23,11 +23,13 @@ const indent = (string, indent) => {
23
23
  }
24
24
 
25
25
  const config_toServer = (config) => {
26
+ /*
26
27
  if (config.contextual_priorities) {
27
28
  config.contextual_priorities = config.contextual_priorities.map((cp) => {
28
29
  return [cp.context, cp.choose]
29
30
  })
30
31
  }
32
+ */
31
33
  }
32
34
 
33
35
  const debugPriority = (priority) => {
@@ -48,7 +50,7 @@ const debugAssociation = (association) => {
48
50
 
49
51
  const debugContextualPriority = (contextual_priority) => {
50
52
  if (global.entodictonDebugContextualPriority) {
51
- if (helpers.safeEquals(entodictonDebugContextualPriority, contextual_priorities)) {
53
+ if (helpers.safeEquals(entodictonDebugContextualPriority, contextual_priority)) {
52
54
  debugger; // debug hierarchy hit
53
55
  }
54
56
  }
@@ -79,6 +81,9 @@ const debugOperator = (operator) => {
79
81
  }
80
82
 
81
83
  const debugConfigProps = (config) => {
84
+ if (!config) {
85
+ return
86
+ }
82
87
  const checkProps = [
83
88
  { property: 'priorities', check: (v) => debugPriority(v) },
84
89
  { property: 'association', check: (v) => debugAssociation(v) },
@@ -149,20 +154,6 @@ const setupInitializerFNArgs = (config, args) => {
149
154
  }
150
155
  }
151
156
 
152
- const contextual_priorities_toServer = (cp) => {
153
- if (cp.context && cp.choose) {
154
- return [cp.context, cp.choose]
155
- }
156
- return cp
157
- }
158
-
159
- const contextual_priorities_toClient = (cp) => {
160
- if (cp.context && cp.choose) {
161
- return cp
162
- }
163
- return { context: cp[0], choose: cp[1] }
164
- }
165
-
166
157
  const operatorKey_valid = (key) => {
167
158
  if (
168
159
  !_.isArray(key) ||
@@ -254,7 +245,7 @@ const handleBridgeProps = (config, bridge, addFirst) => {
254
245
  if (typeof after == 'string') {
255
246
  after = [after, 0]
256
247
  }
257
- config.addPriorities([[bridge.id, bridge.level], after])
248
+ config.addPriorities({ "context": [[bridge.id, bridge.level], after], "choose": [0] })
258
249
  }
259
250
  }
260
251
  if (bridge.after) {
@@ -262,7 +253,7 @@ const handleBridgeProps = (config, bridge, addFirst) => {
262
253
  if (typeof before == 'string') {
263
254
  before = [before, 0]
264
255
  }
265
- config.addPriorities([before, [bridge.id, bridge.level]])
256
+ config.addPriorities({ "context": [before, [bridge.id, bridge.level]], "choose": [0] })
266
257
  }
267
258
  }
268
259
  if (bridge.words) {
@@ -407,6 +398,7 @@ if (runtime.process.env.DEBUG_BRIDGE) {
407
398
  global.entodictonDebugBridge = runtime.process.env.DEBUG_BRIDGE.split('/')
408
399
  if (global.entodictonDebugBridge.length !== 2) {
409
400
  console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
401
+ process.exit(-1)
410
402
  }
411
403
  global.entodictonDebugBridge[1] = parseInt(global.entodictonDebugBridge[1])
412
404
  }
@@ -762,6 +754,7 @@ class Config {
762
754
  addArgs: (...args) => this.addArgs(...args),
763
755
  getBridge: (...args) => this.getBridge(...args),
764
756
  fragment: (...args) => this.fragment(...args),
757
+ exists: (...args) => this.exists(...args),
765
758
  addAPI: (...args) => this.addAPI(...args),
766
759
  }
767
760
  }
@@ -1060,9 +1053,16 @@ class Config {
1060
1053
  this.validifyTemplate(template)
1061
1054
  instance.template = template
1062
1055
  this.logs.push(`loading template for ${this.name}`)
1063
- if (instance && instance.associations && !options.rebuild) {
1064
- this.addAssociations(instance.associations)
1056
+ /*
1057
+ if (instance && (instance.associations || instance.learned_contextual_priorities) && !options.rebuild) {
1058
+ if (instance.associations) {
1059
+ this.addAssociations(instance.associations)
1060
+ }
1061
+ if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
1062
+ this.addContextualPriorities(instance.learned_contextual_priorities)
1063
+ }
1065
1064
  }
1065
+ */
1066
1066
  if (options.rebuild) {
1067
1067
  // TODO fix beforeQuery
1068
1068
  template = { fragments: [], queries: [], ...template }
@@ -1105,13 +1105,18 @@ class Config {
1105
1105
  }
1106
1106
  }
1107
1107
 
1108
-
1109
1108
  addAssociations (associations) {
1110
1109
  for (let association of associations) {
1111
1110
  this.addAssociation(association)
1112
1111
  }
1113
1112
  }
1114
1113
 
1114
+ addContextualPriorities (cps) {
1115
+ for (let cp of cps) {
1116
+ this.addContextualPriority(cp)
1117
+ }
1118
+ }
1119
+
1115
1120
  debugConfig() {
1116
1121
  }
1117
1122
 
@@ -1146,8 +1151,7 @@ class Config {
1146
1151
  debugContextualPriority(contextual_priority)
1147
1152
  contextual_priority_valid(contextual_priority)
1148
1153
  this.config.contextual_priorities.push(contextual_priority)
1149
- const cpServer = contextual_priorities_toServer(contextual_priority)
1150
- this._delta.json.contextual_priorities.push({ action: 'add', contextual_priority: cpServer })
1154
+ this._delta.json.contextual_priorities.push({ action: 'add', contextual_priority: contextual_priority })
1151
1155
  }
1152
1156
 
1153
1157
  addHierarchy (child, parent) {
@@ -1212,7 +1216,8 @@ class Config {
1212
1216
 
1213
1217
  debugBridge(bridge)
1214
1218
  if (bridge.allowDups) {
1215
- if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1219
+ // if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level && b.bridge == bridge.bridge )) {
1220
+ if (bridges.find( (b) => b.id == bridge.id && b.level == bridge.level)) {
1216
1221
  return;
1217
1222
  }
1218
1223
  }
@@ -1641,6 +1646,7 @@ class Config {
1641
1646
  }
1642
1647
  this.get('objects').namespaced[this._uuid] = {}
1643
1648
  this.valid()
1649
+ debugConfigProps(this.config)
1644
1650
  }
1645
1651
 
1646
1652
  addArgs(moreArgs) {
@@ -2535,9 +2541,7 @@ class Config {
2535
2541
  if (config.priorities) {
2536
2542
  let priorities = config.priorities
2537
2543
  priorities = priorities.map((p) => {
2538
- return p.map((id) => {
2539
- return [toNS(id[0]), id[1]]
2540
- })
2544
+ return { ...p, context: p.context.map( (id) => [toNS(id[0]), id[1]] )}
2541
2545
  })
2542
2546
  config.priorities = priorities
2543
2547
  }
@@ -2545,12 +2549,13 @@ class Config {
2545
2549
  if (config.contextual_priorities) {
2546
2550
  let contextual_priorities = config.contextual_priorities
2547
2551
  contextual_priorities = contextual_priorities.map((cp) => {
2548
- const { context, choose } = cp
2552
+ const { context, choose, ordered } = cp
2549
2553
  return {
2550
2554
  context: context.map((id) => {
2551
2555
  return [toNS(id[0]), id[1]]
2552
2556
  }),
2553
- choose
2557
+ choose,
2558
+ ordered
2554
2559
  }
2555
2560
  })
2556
2561
  config.contextual_priorities = contextual_priorities
package/src/helpers.js CHANGED
@@ -43,6 +43,16 @@ const appendNoDups = (l1, l2) => {
43
43
  }
44
44
  }
45
45
 
46
+ const safeNoDups = (list) => {
47
+ noDups = []
48
+ for (const element of list) {
49
+ if (!noDups.find((e) => safeEquals(e, element))) {
50
+ noDups.push(element)
51
+ }
52
+ }
53
+ return noDups
54
+ }
55
+
46
56
  const safeEquals = (v1, v2) => {
47
57
  if (typeof v1 !== typeof v2) {
48
58
  return false
@@ -331,6 +341,7 @@ module.exports = {
331
341
  mapInPlace,
332
342
  validProps,
333
343
  args,
344
+ safeNoDups,
334
345
  safeEquals,
335
346
  appendNoDups,
336
347
  hashIndexesGet,
package/src/project.js CHANGED
@@ -5,6 +5,12 @@ const project = (object, filter) => {
5
5
  }
6
6
 
7
7
  let projection = {}
8
+ const set = (property, value) => {
9
+ if (value === null || value === undefined) {
10
+ return
11
+ }
12
+ projection[property] = value
13
+ }
8
14
  if (Array.isArray(filter)) {
9
15
  if (Array.isArray(object)) {
10
16
  return object.map( element => project(element, filter) )
@@ -15,7 +21,7 @@ const project = (object, filter) => {
15
21
  for (const propertyList in properties.propertyLists) {
16
22
  if (object[propertyList]) {
17
23
  for (const property of object[propertyList]) {
18
- projection[property] = project(object[property], properties.propertyLists[propertyList])
24
+ set(property, project(object[property], properties.propertyLists[propertyList]))
19
25
  }
20
26
  }
21
27
  }
@@ -24,16 +30,32 @@ const project = (object, filter) => {
24
30
  for (const listProperty in properties.valueLists) {
25
31
  const old = object[listProperty]
26
32
  if (Array.isArray(old)) {
27
- projection[listProperty] = old.map((element) => project(element, properties.valueLists[listProperty]))
33
+ set(listProperty, old.map((element) => project(element, properties.valueLists[listProperty])))
28
34
  } else {
29
- projection[listProperty] = project(old, properties.valueLists[listProperty])
35
+ set(listProperty, project(old, properties.valueLists[listProperty]))
30
36
  }
31
37
  }
32
38
  }
33
39
  if (properties.properties) {
34
40
  for (const property in properties.properties) {
35
41
  const old = object[property]
36
- projection[property] = project(old, properties.properties[property])
42
+ set(property, project(old, properties.properties[property]))
43
+ }
44
+ }
45
+ if (properties.property) {
46
+ const property = properties.property
47
+ if (properties.isPropertyList) {
48
+ debugger
49
+ if (!Array.isArray(object[property])) {
50
+ return projection
51
+ }
52
+ for (const propertyRef of object[property]) {
53
+ const old = object[propertyRef]
54
+ set(propertyRef, project(old, properties.filter))
55
+ }
56
+ } else {
57
+ const old = object[property]
58
+ set(property, project(old, properties.filter))
37
59
  }
38
60
  }
39
61
  } else {
@@ -41,14 +63,14 @@ const project = (object, filter) => {
41
63
  properties = [properties]
42
64
  }
43
65
  for (const property of properties) {
44
- projection[property] = object[property]
66
+ set(property, object[property])
45
67
  }
46
68
  }
47
69
  }
48
70
  }
49
71
  } else if (typeof filter == 'object') {
50
72
  for (const property of Object.keys(filter)) {
51
- projection[property] = project(object[property], filter[property])
73
+ set(property, project(object[property], filter[property]))
52
74
  }
53
75
  }
54
76
  return projection