theprogrammablemind_4wp 7.5.8-beta.74 → 7.5.8-beta.77

Sign up to get free protection for your applications and to get access to all the features.
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.74",
67
+ "version": "7.5.8-beta.77",
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