theprogrammablemind_4wp 9.3.0-beta.6 → 9.3.0-beta.60

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
@@ -4,6 +4,7 @@ const { Config } = require('./src/config')
4
4
  const { loadInstance, setupArgs, gs, processContext, getObjects, setupProcessB, processContextsB } = require('./src/configHelpers')
5
5
  const Digraph = require('./src/digraph')
6
6
  const { project } = require('./src/project')
7
+ const { project:project2 } = require('./src/project2')
7
8
  const fetch = require('node-fetch')
8
9
  const base64 = require('base-64')
9
10
  const deepEqual = require('deep-equal')
@@ -49,8 +50,8 @@ const getConfig_getContextCheck = (testConfig) => {
49
50
  return (testConfig.checks && testConfig.checks.context) || []
50
51
  }
51
52
 
52
- const pickContext = (testConfig) => (context) => {
53
- return project(context, getConfig_getContextCheck(testConfig))
53
+ const pickContext = (contextChecks) => (context) => {
54
+ return project2(context, contextChecks)
54
55
  }
55
56
 
56
57
  const pickObjects = (config, testConfig, getObjects) => {
@@ -68,7 +69,11 @@ const pickObjects = (config, testConfig, getObjects) => {
68
69
  if (!objects) {
69
70
  throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
70
71
  }
71
- projection[km] = project(objects, checks[km])
72
+ if (checks[km] && checks[km].find((check) => check.match && check.apply)) {
73
+ projection[km] = project2(objects, checks[km])
74
+ } else {
75
+ projection[km] = project(objects, checks[km])
76
+ }
72
77
  }
73
78
  return projection
74
79
  }
@@ -260,7 +265,7 @@ const throwErrorHandler = (error) => {
260
265
  throw error
261
266
  }
262
267
 
263
- const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
268
+ const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isProcess, isModule, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
264
269
  if (credentials) {
265
270
  config.server(credentials.server, credentials.key)
266
271
  }
@@ -315,7 +320,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
315
320
  if (queries.length === 0) {
316
321
  break
317
322
  }
318
-
323
+ config.updateData(data)
319
324
  data.utterance = queries[0]
320
325
  data.start_counter = startCounter
321
326
  let json = await doWithRetries(retries, url, queryParams, data)
@@ -352,7 +357,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
352
357
  const summary = { summaries: json.summaries, length: json.contexts.length }
353
358
  summaries.push(summary)
354
359
  const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
355
- await processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
360
+ await processContextsB({ isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
356
361
  if (isTest) {
357
362
  const end = runtime.performance.performance.now()
358
363
  clientSideTime = end - start
@@ -485,7 +490,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
485
490
  setupArgs(args, config)
486
491
  await testConfig.initializer(args)
487
492
  }
488
- const result = await _process(config, test, { errorHandler, isTest: true })
493
+ const result = await _process(config, test, { errorHandler, isTest: true, isProcess: true, isModule: false })
489
494
  result.query = test
490
495
  if (debug) {
491
496
  defaultInnerProcess(config, errorHandler, result)
@@ -515,8 +520,9 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
515
520
  failed_generatedParenthesized = false
516
521
  }
517
522
 
518
- const pickedResultContexts = result.contexts.map(pickContext(testConfig))
519
- const pickedExpectedContexts = expected.contexts.map(pickContext(testConfig))
523
+ const contextChecks = config.getContextChecks()
524
+ const pickedResultContexts = result.contexts.map(pickContext(contextChecks))
525
+ const pickedExpectedContexts = expected.contexts.map(pickContext(contextChecks))
520
526
  const failedCheckedContexts = !matching(pickedResultContexts, pickedExpectedContexts)
521
527
 
522
528
  const expectedGetObjects = (name) => {
@@ -624,7 +630,7 @@ const saveTest = async (testFile, config, test, expected, testConfig, saveDevelo
624
630
  await config.rebuild()
625
631
  const objects = getObjects(config.config.objects)(config.uuid)
626
632
  console.log(test)
627
- const result = await _process(config, test, { isTest: true })
633
+ const result = await _process(config, test, { isTest: true, isProcess: true, isModule: true })
628
634
  // const actualObjects = config.config.objects
629
635
  const actualConfig = getConfigForTest(config, testConfig)
630
636
  const args = {
@@ -880,7 +886,8 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
880
886
  console.log(JSON.stringify(picked, null, 2))
881
887
  }
882
888
 
883
- const pickedResultContexts = responses.contexts.map(pickContext(config.testConfig))
889
+ const contextChecks = config.getContextChecks()
890
+ const pickedResultContexts = responses.contexts.map(pickContext(contextChecks))
884
891
  if (pickedResultContexts.some((context) => Object.keys(context).length > 0)) {
885
892
  console.log('--- Contexts showing only the checked values ---')
886
893
  console.log(JSON.stringify(pickedResultContexts, null, 2))
@@ -1880,7 +1887,7 @@ const knowledgeModuleImpl = async ({
1880
1887
  global.beforeObjects = _.cloneDeep(objects)
1881
1888
  }
1882
1889
  try {
1883
- await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1890
+ await processResults(_process(config, args.query, { commandLineArgs: args, isProcess, isModule: !isProcess, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1884
1891
  } catch (error) {
1885
1892
  console.log('Error', error)
1886
1893
  }
@@ -1909,8 +1916,18 @@ const knowledgeModuleImpl = async ({
1909
1916
  loadForTesting = true
1910
1917
  }
1911
1918
  }
1919
+ if (template) {
1920
+ try {
1921
+ await config.load(rebuildTemplate, template.template, template.instance)
1922
+ } catch (e) {
1923
+ errorHandler(e)
1924
+ }
1925
+ }
1926
+
1912
1927
  // remove test only stuff
1913
1928
  if (!isProcess && !loadForTesting) {
1929
+ config.removeDevelopmentElements(config.config)
1930
+ /*
1914
1931
  config.config.operators = config.config.operators.filter((operator) => {
1915
1932
  if (operator.development) {
1916
1933
  return false
@@ -1925,21 +1942,14 @@ const knowledgeModuleImpl = async ({
1925
1942
  return true
1926
1943
  }
1927
1944
  })
1928
- }
1929
-
1930
- if (template) {
1931
- try {
1932
- await config.load(rebuildTemplate, template.template, template.instance)
1933
- } catch (e) {
1934
- errorHandler(e)
1935
- }
1945
+ */
1936
1946
  }
1937
1947
  }
1938
1948
 
1939
1949
  // no cache 21 minutes + rebuild fails "node tester_rebuild -m colors"
1940
1950
  // cache okay
1941
- const createConfigExport = async () => {
1942
- if (createConfig.cached) {
1951
+ const createConfigExport = async (useCache = true) => {
1952
+ if (useCache && createConfig.cached) {
1943
1953
  return createConfig.cached
1944
1954
  }
1945
1955
  const config = await createConfig()
package/package.json CHANGED
@@ -53,6 +53,7 @@
53
53
  "src/digraph_internal.js",
54
54
  "src/generators.js",
55
55
  "src/project.js",
56
+ "src/project2.js",
56
57
  "src/semantics.js"
57
58
  ],
58
59
  "author": "dev@thinktelligence.com",
@@ -69,6 +70,6 @@
69
70
  "sort-json": "^2.0.0",
70
71
  "uuid": "^8.3.2"
71
72
  },
72
- "version": "9.3.0-beta.6",
73
+ "version": "9.3.0-beta.60",
73
74
  "license": "UNLICENSED"
74
75
  }
package/src/config.js CHANGED
@@ -335,6 +335,22 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
335
335
  config.addPriority({ context: [[bridge.id, bridge.level], after], choose: [0] })
336
336
  }
337
337
  }
338
+ if (bridge.check) {
339
+ if (!config.testConfig) {
340
+ config.testConfig = {}
341
+ }
342
+ if (!config.testConfig.checks) {
343
+ config.testConfig.checks = {}
344
+ }
345
+ if (!config.testConfig?.checks?.context) {
346
+ config.testConfig.checks.context = []
347
+ }
348
+ config.testConfig.checks.context.push({
349
+ match: ({context}) => context.marker == bridge.id,
350
+ exported: true,
351
+ apply: ({context}) => bridge.check,
352
+ })
353
+ }
338
354
  if (bridge.after) {
339
355
  for (let before of bridge.after) {
340
356
  if (typeof before === 'string') {
@@ -473,7 +489,7 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
473
489
  if (moreConfig.bridges) {
474
490
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
475
491
  bridge = { ...bridge }
476
- const valid = ['after', 'conditional', 'associations', 'before', 'bridge', 'development', 'skipable', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
492
+ const valid = ['after', 'conditional', 'associations', 'before', 'bridge', 'check', 'disabled', 'development', 'skipable', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
477
493
  'level', 'optional', 'selector', 'semantic', 'semantics', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
478
494
  helpers.validProps(valid, bridge, 'bridge')
479
495
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
@@ -878,6 +894,7 @@ class Config {
878
894
  getInfo () {
879
895
  const name = this.name
880
896
  const includes = this.configs.slice(1).map((km) => km.config.name)
897
+ includes.sort()
881
898
  const visibleExamples = []
882
899
  for (const test of this.tests) {
883
900
  if (!test.developerTest) {
@@ -1055,8 +1072,8 @@ class Config {
1055
1072
 
1056
1073
  // value is in response field
1057
1074
  // TODO maybe generalize out query+evaluate along the lines of set value and set reference
1058
- async getEvaluator (s, calls, log, context) {
1059
- const instance = await s({ ...context, evaluate: true })
1075
+ async getEvaluator (s, calls, log, context, args) {
1076
+ const instance = await s({ ...args, ...context, evaluate: true })
1060
1077
  calls.touch(instance)
1061
1078
  if (!instance.evalue && !instance.verbatim && !instance.value) {
1062
1079
  this.warningNotEvaluated(log, context)
@@ -1214,43 +1231,6 @@ class Config {
1214
1231
  }
1215
1232
  return bridge
1216
1233
  })
1217
- } else {
1218
- /* done in updateQueries now
1219
- config.generators = (config.generators || []).map((generator) => {
1220
- generator = { ...generator }
1221
- delete generator.where
1222
- generator.match = generator.match.toString()
1223
- generator.apply = generator.apply.toString()
1224
- return generator
1225
- })
1226
- config.semantics = (config.semantics || []).map((semantic) => {
1227
- semantic = { ...semantic }
1228
- delete semantic.where
1229
- semantic.match = semantic.match.toString()
1230
- semantic.apply = semantic.apply.toString()
1231
- return semantic
1232
- })
1233
- config.bridges = (config.bridges || []).map((bridge) => {
1234
- bridge = { ...bridge }
1235
- delete bridge.where
1236
- if (bridge.generatorp) {
1237
- bridge.generatorp = bridge.generatorp.toString()
1238
- }
1239
- if (bridge.generatorr) {
1240
- bridge.generatorr = bridge.generatorr.toString()
1241
- }
1242
- if (bridge.generatorpr) {
1243
- bridge.generatorpr = bridge.generatorpr.toString()
1244
- }
1245
- if (bridge.evaluator) {
1246
- bridge.evaluator = bridge.evaluator.toString()
1247
- }
1248
- if (bridge.semantic) {
1249
- bridge.semantic = bridge.semantic.toString()
1250
- }
1251
- return bridge
1252
- })
1253
- */
1254
1234
  }
1255
1235
  return config
1256
1236
  }
@@ -1328,6 +1308,15 @@ class Config {
1328
1308
  }
1329
1309
  }
1330
1310
 
1311
+ addEnable (key) {
1312
+ this._enable.push(key)
1313
+ }
1314
+
1315
+ updateData (data) {
1316
+ data.enable = this._enable
1317
+ this._enable = []
1318
+ }
1319
+
1331
1320
  toData (data) {
1332
1321
  Object.assign(data, this.config)
1333
1322
  // greg99 delete data.objects
@@ -1577,8 +1566,14 @@ class Config {
1577
1566
  }
1578
1567
 
1579
1568
  removeSemantic (deleteSemantic) {
1580
- const id = deleteSemantic.id || deleteSemantic
1581
- const todo = [id]
1569
+ if (!Array.isArray(deleteSemantic)) {
1570
+ deleteSemantic = [deleteSemantic]
1571
+ }
1572
+ const todo = []
1573
+ for (const ds of deleteSemantic) {
1574
+ const id = ds.id || ds
1575
+ todo.push(id)
1576
+ }
1582
1577
  const seen = new Set()
1583
1578
 
1584
1579
  while (todo.length > 0) {
@@ -1591,6 +1586,7 @@ class Config {
1591
1586
  if (index === -1) {
1592
1587
  continue
1593
1588
  }
1589
+ // TODO change to tiedIs(s)
1594
1590
  for (const tied_id of this.config.semantics[index].tied_ids || []) {
1595
1591
  if (!seen.has(tied_id)) {
1596
1592
  todo.push(tied_id)
@@ -1951,6 +1947,7 @@ class Config {
1951
1947
  config.priorities = config.priorities || []
1952
1948
  }
1953
1949
 
1950
+ this._enable = []
1954
1951
  this._apiKMs = apiKMs
1955
1952
 
1956
1953
  this.clientProcess = clientProcess
@@ -2190,7 +2187,6 @@ class Config {
2190
2187
  this._apiConstructor = constructor
2191
2188
  if (this._apiKMs.length > 0) {
2192
2189
  for (const name of this._apiKMs) {
2193
- debugger
2194
2190
  this.km(name)._api = value[name]
2195
2191
  }
2196
2192
  } else {
@@ -2617,6 +2613,24 @@ class Config {
2617
2613
  })
2618
2614
  }
2619
2615
 
2616
+ getContextChecks() {
2617
+ const allChecks = []
2618
+ for (const name of this.loadOrdering) {
2619
+ const checks = this.kms[name].testConfig?.checks?.context || []
2620
+ for (const check of checks) {
2621
+ if (check.exported) {
2622
+ allChecks.push(check)
2623
+ }
2624
+ }
2625
+ }
2626
+ for (const check of this.testConfig?.checks?.context || []) {
2627
+ if (!check.exported) {
2628
+ allChecks.push(check)
2629
+ }
2630
+ }
2631
+ return allChecks
2632
+ }
2633
+
2620
2634
  // rebuild ({ isModule: mainIsModule = false } = {}) {
2621
2635
  async rebuild ({ isModule: mainIsModule } = {}) {
2622
2636
  if (this._stop_auto_rebuild) {
@@ -2644,6 +2658,7 @@ class Config {
2644
2658
  // reorder configs base on load ordering
2645
2659
  {
2646
2660
  const ordering = this.loadOrder.order(this.configs.map((km) => km.name || km.uuid))
2661
+ this.loadOrdering = ordering
2647
2662
  const oconfigs = []
2648
2663
  for (const nameOrUUID of ordering) {
2649
2664
  for (const km of this.configs) {
@@ -2802,6 +2817,10 @@ class Config {
2802
2817
  }
2803
2818
  }
2804
2819
 
2820
+ if (this.isModule) {
2821
+ this.removeDevelopmentElements(this.config)
2822
+ }
2823
+
2805
2824
  this.valid()
2806
2825
  this.checks()
2807
2826
  }
@@ -3187,7 +3206,7 @@ class Config {
3187
3206
  }
3188
3207
 
3189
3208
  // TODO get rid of useOldVersion arg
3190
- addInternal (more, { uuid, addFirst = false, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps: hcps = false } = {}) {
3209
+ addInternal (more, { uuid, km, addFirst = false, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps: hcps = false } = {}) {
3191
3210
  validConfigProps(more)
3192
3211
  if (more instanceof Config) {
3193
3212
  more.initialize({ force: false })
@@ -3204,6 +3223,20 @@ class Config {
3204
3223
  handleCalculatedProps(this, more, { addFirst, uuid })
3205
3224
  applyUUID(more, uuid || this._uuid)
3206
3225
  }
3226
+ if (km) {
3227
+ if (more.semantics) {
3228
+ more.semantics.map((s) => s.km = km)
3229
+ }
3230
+ if (more.generators) {
3231
+ more.generators.map((g) => g.km = km)
3232
+ }
3233
+ }
3234
+ const normalizeIsA = (edge) => {
3235
+ if (edge.length == 3 || edge.parent || edge.child) {
3236
+ return edge
3237
+ }
3238
+ return [...edge, false]
3239
+ }
3207
3240
  for (const key of Object.keys(more)) {
3208
3241
  const value = more[key]
3209
3242
  // TODO remove name and description on the config bag
@@ -3247,9 +3280,9 @@ class Config {
3247
3280
  const hierarchy = this.config.words.hierarchy
3248
3281
  const moreHierarchy = more.words.hierarchy
3249
3282
  if (addFirst) {
3250
- this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3283
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy.map(normalizeIsA))
3251
3284
  } else {
3252
- this.config.words.hierarchy = hierarchy.concat(moreHierarchy)
3285
+ this.config.words.hierarchy = hierarchy.concat(moreHierarchy.map(normalizeIsA))
3253
3286
  }
3254
3287
  }
3255
3288
  } else if (key === 'name') {
@@ -3321,7 +3354,9 @@ class Config {
3321
3354
  // console.log('more', JSON.stringify(more, null, 2))
3322
3355
  // hierarchy must update in place and does not care about the list order
3323
3356
  if (key === 'hierarchy') {
3324
- this.config[key].push(...more[key])
3357
+ const moreEdges = more[key].map(normalizeIsA)
3358
+ this.config[key].push(...moreEdges)
3359
+ this.hierarchy.addEdges(moreEdges)
3325
3360
  } else {
3326
3361
  if (addFirst) {
3327
3362
  this.config[key] = more[key].concat(this.config[key])
@@ -86,6 +86,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
86
86
  args.objects = config.get('objects')
87
87
  args.getObjects = getObjects(args.objects)
88
88
  }
89
+ args.enable = (key) => {
90
+ config.addEnable(key)
91
+ }
89
92
  if (args.uuid) {
90
93
  args.objects = args.getObjects(args.uuid)
91
94
  }
@@ -140,7 +143,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
140
143
  if (!c) {
141
144
  return
142
145
  }
143
- return config.getEvaluator(args.s, args.calls, logs, c)
146
+ return config.getEvaluator(args.s, args.calls, logs, c, { isModule: args.isModule, isProcess: args.isProcess })
144
147
  }
145
148
  args.gs = gs(args.g)
146
149
  args.gsp = gs(args.gp)
@@ -257,18 +260,18 @@ const setupProcessB = ({ config, initializer, allowDelta = false, rebuildingTemp
257
260
  const setupContexts = (rawContexts) => {
258
261
  let first = true
259
262
  const contexts = []
260
- contexts.push({ marker: 'controlStart', controlRemove: true })
263
+ contexts.push({ marker: 'controlStart', controlRemove: true, isControl: true })
261
264
  let previous
262
265
  for (const context of rawContexts) {
263
266
  if (first) {
264
267
  first = false
265
268
  } else {
266
- contexts.push({ marker: 'controlBetween', controlRemove: true, previous })
269
+ contexts.push({ marker: 'controlBetween', controlRemove: true, isControl: true, previous })
267
270
  }
268
271
  contexts.push(context)
269
272
  previous = context
270
273
  }
271
- contexts.push({ marker: 'controlEnd', controlRemove: true, previous })
274
+ contexts.push({ marker: 'controlEnd', controlRemove: true, isControl: true, previous })
272
275
 
273
276
  let _index = 0
274
277
  const id = (context) => {
@@ -279,7 +282,7 @@ const setupContexts = (rawContexts) => {
279
282
  return contexts
280
283
  }
281
284
 
282
- const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate }) => {
285
+ const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate }) => {
283
286
  // TODO fix this name to contextsPrime
284
287
  const contextsPrime = []
285
288
  const generatedPrime = []
@@ -290,7 +293,7 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
290
293
  const contexts = setupContexts(json.contexts)
291
294
 
292
295
  const objects = config.get('objects')
293
- const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance, contexts }
296
+ const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance, contexts, isProcess, isModule }
294
297
  if (!json.logs) {
295
298
  json.logs = []
296
299
  }
@@ -441,14 +444,14 @@ const loadInstance = async (config, instance) => {
441
444
  */
442
445
 
443
446
  // const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
444
- const hierarchy = config.hierarchy
445
447
  for (const i in (instance.resultss || [])) {
448
+ const hierarchy = config.hierarchy
446
449
  const results = instance.resultss[i]
447
450
  if (results.extraConfig) {
448
451
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
449
452
  const uuid = config.nameToUUID(instance.name)
450
453
  // used to do a CLONE
451
- config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
454
+ config.addInternal(instance.template.configs[i], { uuid, km: instance.name, addFirst: true, handleCalculatedProps: true })
452
455
  } else if (results.apply) {
453
456
  const objects = getObjects(config.get('objects'))(config.uuid)
454
457
  const args = { objects, getObjects: getObjects(objects) }
@@ -468,6 +471,8 @@ const loadInstance = async (config, instance) => {
468
471
  const args = { config, hierarchy, json: results, commandLineArgs: {}, forTemplate: true }
469
472
  args.isInstance = `instance${i}`
470
473
  args.instance = ''
474
+ args.isProcess = !config.isModule
475
+ args.isModule = !!config.isModule
471
476
  await processContextsB(args)
472
477
  if (results.skipSemantics) {
473
478
  config.config.skipSemantics = null
package/src/debug.js CHANGED
@@ -31,12 +31,12 @@ const wasHit = (name) => {
31
31
  return hits[name]
32
32
  }
33
33
 
34
- const counter = (name, breakAt = [], debugBreak = true) => {
34
+ const counter = (name, { breakAt = [], debugBreak = true, tag = '' } = {}) => {
35
35
  if (!counters[name]) {
36
36
  counters[name] = 0
37
37
  }
38
38
  counters[name] += 1
39
- console.log(`counters[${name}] = ${counters[name]}`)
39
+ console.log(`counters[${name}] = ${counters[name]} ${tag}`)
40
40
  unhit(name)
41
41
  if (Array.isArray(breakAt) && breakAt.includes(counters[name])) {
42
42
  if (debugBreak) {
package/src/helpers.js CHANGED
@@ -310,6 +310,7 @@ const validProps = (valids, object, type) => {
310
310
  }
311
311
  }
312
312
  if (!okay) {
313
+ valids.sort()
313
314
  throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids.join(', ')}. The ${type} is ${JSON.stringify(object)}`)
314
315
  }
315
316
  }
package/src/project.js CHANGED
@@ -1,15 +1,38 @@
1
+ function isObject(value) {
2
+ return typeof value === "object" && value !== null;
3
+ }
4
+
5
+ const merge = (value1, value2) => {
6
+ if (Array.isArray(value1) && Array.isArray(value2)) {
7
+ const merged = []
8
+ for (let i = 0; i < value1.length; ++i) {
9
+ merged.push(merge(value1[i], value2[i]))
10
+ }
11
+ return merged
12
+ }
13
+ if (isObject(value1) && isObject(value2)) {
14
+ return Object.assign({}, value1, value2)
15
+ }
16
+ }
1
17
 
2
18
  const project = (object, filter) => {
3
19
  if (!object) {
4
20
  return
5
21
  }
22
+ if (typeof object === 'string' || typeof object === 'number') {
23
+ return object
24
+ }
6
25
 
7
26
  const projection = {}
8
27
  const set = (property, value) => {
9
28
  if (value === null || value === undefined) {
10
29
  return
11
30
  }
12
- projection[property] = value
31
+ if (projection[property]) {
32
+ projection[property] = merge(value, projection[property])
33
+ } else {
34
+ projection[property] = value
35
+ }
13
36
  }
14
37
  if (Array.isArray(filter)) {
15
38
  if (Array.isArray(object)) {
@@ -78,4 +101,4 @@ const project = (object, filter) => {
78
101
  return projection
79
102
  }
80
103
 
81
- module.exports = { project }
104
+ module.exports = { project, merge }
@@ -0,0 +1,54 @@
1
+ function project(source, filters) {
2
+ if (['string', 'number'].includes(typeof source)) {
3
+ return source
4
+ }
5
+
6
+ if (Object.keys(source).length === 0 && filters.length === 0) {
7
+ return {};
8
+ }
9
+
10
+ // Find the applicable filter for the current context
11
+ const filter = filters.find(f => f.match({ context: source }));
12
+ if (!filter) {
13
+ if (Array.isArray(source)) {
14
+ return source.map((element) => project(element, filters))
15
+ }
16
+ return {};
17
+ }
18
+
19
+ // Get the properties to include from the apply function
20
+ let properties = filter.apply(source);
21
+
22
+ // update
23
+ const updatedProperties = []
24
+ for (const property of properties) {
25
+ if (property.properties) {
26
+ for (const moreProperty of source[property.properties] || []) {
27
+ updatedProperties.push(moreProperty)
28
+ }
29
+ } else {
30
+ updatedProperties.push(property)
31
+ }
32
+ }
33
+ properties = updatedProperties
34
+
35
+ // Build the result object
36
+ const result = {};
37
+ properties.forEach(prop => {
38
+ if (source.hasOwnProperty(prop)) {
39
+ // If the property is an object and not null, recursively project it
40
+ if (typeof source[prop] === 'object' && source[prop] !== null) {
41
+ result[prop] = project(source[prop], filters);
42
+ } else {
43
+ // Copy primitive or null properties directly
44
+ result[prop] = source[prop];
45
+ }
46
+ }
47
+ });
48
+
49
+ return result;
50
+ }
51
+
52
+ module.exports = {
53
+ project
54
+ }