theprogrammablemind 9.8.0-beta.9 → 9.9.0

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
@@ -158,13 +158,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
158
158
  if (runtime.fs.existsSync(fn)) {
159
159
  tests = JSON.parse(runtime.fs.readFileSync(fn))
160
160
  }
161
- /*
162
- for (const association of associations) {
163
- association.sort()
164
- }
165
- associations.sort()
166
- */
167
- // tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
168
161
  const results = sortJson({
169
162
  query,
170
163
  summaries,
@@ -189,7 +182,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
189
182
  if (!wasSet) {
190
183
  tests.push(results)
191
184
  }
192
- // fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
193
185
  writeTestFile(fn, tests)
194
186
  }
195
187
 
@@ -258,7 +250,7 @@ const throwErrorHandler = (error) => {
258
250
  throw error
259
251
  }
260
252
 
261
- const _process = async (config, query, { queryNumber, initializer, commandLineArgs, credentials, writeTests, logs, isProcess, isModule, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
253
+ const _process = async (config, query, { isFragment, queryNumber, initializer, commandLineArgs, credentials, writeTests, logs, isProcess, isModule, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
262
254
  if (credentials) {
263
255
  config.server(credentials.server, credentials.key)
264
256
  }
@@ -364,7 +356,7 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
364
356
  const summary = { summaries: json.summaries, length: json.contexts.length }
365
357
  summaries.push(summary)
366
358
  const { updatedContextIdCounter, contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
367
- await processContextsB({ contextIdCounter, logs, calls, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
359
+ await processContextsB({ skipSemantics: isFragment, isFragment, contextIdCounter, logs, calls, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
368
360
  contextIdCounter = updatedContextIdCounter
369
361
  if (isTest) {
370
362
  const end = runtime.performance.performance.now()
@@ -384,7 +376,6 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
384
376
  response.explain_associations_details = (response.explain_associations_details || []).concat(json.explain_associations_details)
385
377
  response.explain_associations_trie = json.explain_associations_trie
386
378
  response.contextual_priorities_ambiguities = json.contextual_priorities_ambiguities
387
- // response.rtf_associations = json.rtf_associations
388
379
 
389
380
  response.contexts = response.contexts.concat(contextsPrime)
390
381
  response.generated = response.generated.concat(generatedPrime)
@@ -902,6 +893,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
902
893
  const km = config.configs.find((km) => km.name === name)
903
894
  return config.config.objects.namespaced[km.uuid] || {}
904
895
  }
896
+
905
897
  const picked = sortJson(pickObjects(config, config.testConfig, actualGetObjects), { depth: 25 })
906
898
  if (!_.isEmpty(picked)) {
907
899
  console.log('--- Object showing only the checked values ---')
@@ -1036,7 +1028,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1036
1028
  await loadInstance(config, { resultss: [results] })
1037
1029
  } else {
1038
1030
  try {
1039
- results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
1031
+ results = await _process(config, query.query, { initializer, rebuildingTemplate: true, isFragment })
1040
1032
  } catch (e) {
1041
1033
  if (e.summaries && e.summaries.length > 0) {
1042
1034
  suggestFix(e.summaries)
@@ -1064,7 +1056,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1064
1056
  results.isFragment = isFragment
1065
1057
  results.skipSemantics = skipSemantics
1066
1058
  results.development = query.development
1067
- results.key = { query: query.query, hierarchy }
1059
+ results.key = { query: query.query, hierarchy, preserve: query.preserve }
1068
1060
  accumulators[property].push(results)
1069
1061
  if (isFragment) {
1070
1062
  config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
package/lines.js CHANGED
@@ -40,7 +40,7 @@ class Lines {
40
40
  this.newRow()
41
41
  let result = ''
42
42
  for (const row of this.rows) {
43
- result += row
43
+ result += row.trimEnd()
44
44
  result += '\n'
45
45
  }
46
46
  return result
package/package.json CHANGED
@@ -18,9 +18,11 @@
18
18
  "test:debug": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
19
19
  "td": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
20
20
  "tod": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
21
+ "toda": "node inspect node_modules/.bin/jest --runInBand -t NEO23A",
21
22
  "lint:fix": "eslint \"**/*.js\" --fix",
22
23
  "lint": "eslint \"**/*.js\"",
23
24
  "to": "node node_modules/.bin/jest --runInBand -t NEO23",
25
+ "toa": "node node_modules/.bin/jest --runInBand -t NEO23A",
24
26
  "tos": "node node_modules/.bin/jest --runInBand -t NEOS23",
25
27
  "test": "jest --config ./jest.config.json",
26
28
  "test:python": "node node_modules/.bin/jest --runInBand -t PYTHON",
@@ -73,6 +75,6 @@
73
75
  "scriptjs": "^2.5.9",
74
76
  "uuid": "^8.3.2"
75
77
  },
76
- "version": "9.8.0-beta.9",
78
+ "version": "9.9.0",
77
79
  "license": "UNLICENSED"
78
80
  }
package/src/config.js CHANGED
@@ -390,7 +390,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
390
390
 
391
391
  if (!bridge.where) {
392
392
  if (bridge.generator || bridge.generatorp || bridge.generatorr || bridge.generator ||
393
- bridge.semantic || bridge.evaluator || bridge.evaluator2 || bridge.semantics) {
393
+ bridge.semantic || bridge.semantics) {
394
394
  throw new Error(`In the KM "${config.name}", for the bridge ${bridge.id} the where property is missing. Use where: where().`)
395
395
  }
396
396
  }
@@ -494,18 +494,10 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
494
494
  applyWrapped: semantic,
495
495
  }
496
496
  } else {
497
- if (property == 'evaluator2') {
498
- semanticDef = {
499
- match: (args) => bridge.id === args.context.marker && match(args),
500
- apply: (args) => apply(args),
501
- applyWrapped: semantic,
502
- }
503
- } else {
504
- semanticDef = {
505
- match: (args) => bridge.id === args.context.marker && !!args.context.evaluate === evaluate && match(args),
506
- apply: (args) => apply(args),
507
- applyWrapped: semantic,
508
- }
497
+ semanticDef = {
498
+ match: (args) => bridge.id === args.context.marker && match(args),
499
+ apply: (args) => apply(args),
500
+ applyWrapped: semantic,
509
501
  }
510
502
  }
511
503
  semanticDef.where = semantic.where || bridge.where || helpers.where(4)
@@ -521,28 +513,10 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
521
513
  }
522
514
  }
523
515
 
524
- if (bridge.evaluator) {
525
- addSemantic(bridge.evaluator, true, 'evaluator')
526
- }
527
-
528
- if (bridge.evaluator2) {
529
- addSemantic(bridge.evaluator2, false, 'evaluator2')
530
- }
531
-
532
516
  if (bridge.semantic) {
533
517
  addSemantic(bridge.semantic, false, 'semantic')
534
518
  }
535
519
 
536
- if (bridge.evaluators) {
537
- const evaluators = [...bridge.evaluators]
538
- evaluators.reverse()
539
- if (evaluators) {
540
- for (const evaluator of evaluators) {
541
- addSemantic(evaluator, true, 'evaluator')
542
- }
543
- }
544
- }
545
-
546
520
  if (bridge.semantics) {
547
521
  const semantics = [...bridge.semantics]
548
522
  semantics.reverse()
@@ -572,9 +546,6 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
572
546
  'convolution',
573
547
  'disabled',
574
548
  'enhanced_associations',
575
- 'evaluator',
576
- 'evaluator2',
577
- 'evaluators',
578
549
  'generatorp',
579
550
  'generatorpr',
580
551
  'generatorr',
@@ -1047,6 +1018,7 @@ class Config {
1047
1018
  return {
1048
1019
  pseudo: true,
1049
1020
  description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
1021
+ nextFragmentContextId: () => this.nextFragmentContextId(),
1050
1022
  addAssociation: (...args) => this.addAssociation(...args),
1051
1023
  addAssociations: (...args) => this.addAssociations(...args),
1052
1024
  addBridge: (...args) => this.addBridge(...args, uuid),
@@ -1261,7 +1233,7 @@ class Config {
1261
1233
 
1262
1234
  warningNotEvaluated (log, value) {
1263
1235
  const description = 'WARNING: for semantics, implement an evaluations handler, set "value" property of the operator to the value.'
1264
- const match = `({context}) => context.marker === '${value.marker}' && context.evaluate && <other conditions as you like>`
1236
+ const match = `({context}) => context.marker === '${value.marker}' && <other conditions as you like>`
1265
1237
  const apply = '({context}) => <do stuff...>; context.value = <value>'
1266
1238
  const input = indent(JSON.stringify(value, null, 2), 2)
1267
1239
  const message = `${description}\nThe semantic would be\n match: ${match}\n apply: ${apply}\nThe input context would be:\n${input}\n`
@@ -1270,18 +1242,15 @@ class Config {
1270
1242
 
1271
1243
  // value is in response field
1272
1244
  // TODO maybe generalize out query+evaluate along the lines of set value and set reference
1273
- async getEvaluator (s, calls, log, context, args) {
1274
- const instance = await s({ ...args, ...context })
1275
- calls.touch(instance)
1276
- if (instance.evalue == null && !instance.verbatim && !instance.value) {
1277
- this.warningNotEvaluated(log, context)
1245
+ async evaluate (args, logs, context) {
1246
+ const apply = (c) => this.getSemantics(logs).apply(args, c)
1247
+ const instance = await apply(context)
1248
+ if (typeof instance !== 'string') {
1249
+ args.calls.touch(instance)
1278
1250
  }
1279
- if (instance.evalue == null) {
1280
- instance.evalue = instance.value
1281
- instance.edefault = true
1251
+ if (instance.evalue == null && !instance.verbatim && !instance.value) {
1252
+ this.warningNotEvaluated(logs, context)
1282
1253
  }
1283
- delete instance.evaluate
1284
- instance.instance = true
1285
1254
  return instance
1286
1255
  }
1287
1256
 
@@ -1312,10 +1281,14 @@ class Config {
1312
1281
  let fi = fragmentInstantiator(args, fragment.contexts)
1313
1282
  if (mappings) {
1314
1283
  fi = await fi
1315
- return fi.instantiate([{
1284
+ const instantiated = await fi.instantiate([{
1316
1285
  match: ({context}) => !!mappings[context.value], // is the value in the mappings
1317
1286
  apply: ({context}) => Object.assign(context, mappings[context.value]),
1318
- }])
1287
+ }], fragment.key?.preserve)
1288
+ if (process.env.DEBUG_CONTEXT_ID && process.env.DEBUG_CONTEXT_ID == instantiated.context_id) {
1289
+ debugger
1290
+ }
1291
+ return instantiated
1319
1292
  } else {
1320
1293
  return fi
1321
1294
  }
@@ -1324,6 +1297,7 @@ class Config {
1324
1297
  }
1325
1298
  }
1326
1299
 
1300
+ /*
1327
1301
  fragmentMapper (args, values, fromModelQuery, toModelQuery) {
1328
1302
  const fromModelFragment = this.getFragment(fromModelQuery)
1329
1303
  console.dir(fromModelFragment)
@@ -1332,6 +1306,7 @@ class Config {
1332
1306
  const mapper = fragmentMapperInstantiator(values, fromModelFragment.contexts, toModelFragment.contexts)
1333
1307
  return mapper
1334
1308
  }
1309
+ */
1335
1310
 
1336
1311
  // { rebuild: false, isModule: false }
1337
1312
  needsRebuild (template, instance, options) {
@@ -1403,6 +1378,7 @@ class Config {
1403
1378
  bridge = { ...bridge },
1404
1379
  bridge.level = bridge.level || 0
1405
1380
  delete bridge.uuid
1381
+ delete bridge.where
1406
1382
  return bridge
1407
1383
  })
1408
1384
  if (options.isModule) {
@@ -1415,9 +1391,6 @@ class Config {
1415
1391
  delete bridge.generatorp
1416
1392
  delete bridge.generatorr
1417
1393
  delete bridge.generatorpr
1418
- delete bridge.evaluator
1419
- delete bridge.evaluator2
1420
- delete bridge.evaluators
1421
1394
  delete bridge.semantic
1422
1395
  delete bridge.semantics
1423
1396
  if (false && !bridge.bridge) {
@@ -2199,6 +2172,12 @@ class Config {
2199
2172
  // await this.demoInitializer(this)
2200
2173
  }
2201
2174
 
2175
+ nextFragmentContextId() {
2176
+ const id = this.fragmentNextContextId
2177
+ this.fragmentNextContextId = this.fragmentNextContextId + 1
2178
+ return id
2179
+ }
2180
+
2202
2181
  // configs = [ { config, namespace } ... ]
2203
2182
  constructor (config, module, clientProcess, apiKMs, rootIsProcess, testingModuleName) {
2204
2183
  if (config instanceof Config) {
@@ -2209,6 +2188,8 @@ class Config {
2209
2188
  apiKMs = []
2210
2189
  }
2211
2190
 
2191
+ this.fragmentNextContextId = 1000
2192
+
2212
2193
  if (config) {
2213
2194
  validConfigProps(config)
2214
2195
 
@@ -1,7 +1,24 @@
1
- const { InitCalls } = require('./helpers')
1
+ const { InitCalls, where } = require('./helpers')
2
2
  const DigraphInternal = require('./digraph_internal')
3
3
  const debug = require('./debug')
4
4
 
5
+ class ErrorReason extends Error {
6
+ constructor (context, stack) {
7
+ super(JSON.stringify(context))
8
+ this.reason = context
9
+ this.stack = stack
10
+ }
11
+
12
+ toString() {
13
+ if (this.reason) {
14
+ return this.reason
15
+ } else {
16
+ return super.toString()
17
+ }
18
+ }
19
+ }
20
+
21
+
5
22
  const gs = (g) => async (contexts, separator, lastSeparator) => {
6
23
  if (!Array.isArray(contexts)) {
7
24
  throw new Error('Expected a list')
@@ -63,13 +80,6 @@ const isA = (hierarchy) => (child, parent, { strict = false } = {}) => {
63
80
  }
64
81
  }
65
82
 
66
- class ErrorReason extends Error {
67
- constructor (context) {
68
- super(JSON.stringify(context))
69
- this.reason = context
70
- }
71
- }
72
-
73
83
  const cleanAssign = (dest, ...srcs) => {
74
84
  for (const key in dest) {
75
85
  let found = false
@@ -93,29 +103,16 @@ class HandlerStack {
93
103
  }
94
104
 
95
105
  push(handler) {
96
- this.handlers.push(handler)
106
+ this.handlers.push(handler.where || handler)
97
107
  }
98
108
 
99
109
  pop() {
100
110
  this.handlers.pop()
101
111
  }
102
112
 
103
- /*
104
113
  async wrap(call, w) {
105
- const s = w
106
114
  this.push(w)
107
- const p = call()
108
- if (p) {
109
- return p.finally(() => {
110
- this.pop()
111
- })
112
- }
113
- }
114
- */
115
-
116
- async wrap(call, w) {
117
- this.push(w)
118
- const p = call()
115
+ const p = await call()
119
116
  if (p && typeof p.finally === 'function') {
120
117
  return p.finally(() => {
121
118
  this.pop()
@@ -210,7 +207,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
210
207
  args.km = (name) => config.getConfig(name)
211
208
  args.api = (name) => config.getConfig(name).api
212
209
  args.error = (context) => {
213
- throw new ErrorReason(context)
210
+ throw new ErrorReason(context, [...args.stack.handlers, where()])
214
211
  }
215
212
  args.kms = config.getConfigs()
216
213
  args.config = config.getPseudoConfig(uuidForScoping, config)
@@ -223,9 +220,11 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
223
220
  args.fragments = (query, mappings) => {
224
221
  return config.fragment(args, query, mappings)
225
222
  }
223
+ /*
226
224
  args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
227
225
  return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
228
226
  }
227
+ */
229
228
  args.breakOnSemantics = false
230
229
  args.theDebugger = {
231
230
  breakOnSemantics: (value) => args.breakOnSemantics = value
@@ -278,24 +277,18 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
278
277
  const { assumed = {}, options = {} } = rest
279
278
  return config.getGenerators(logs).apply(addAssumed(args, assumed, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true }, options)
280
279
  }
281
- if (true) {
282
- args.s = (c, options = {}) => config.getSemantics(logs).apply(args, c, options)
283
- args.e = (c) => {
284
- if (!c) {
285
- return
286
- }
287
- return config.getEvaluator(args.s, args.calls, logs, c, { isModule: args.isModule, isProcess: args.isProcess })
280
+
281
+ args.e = (c, where) => {
282
+ if (!c) {
283
+ return
288
284
  }
289
- } else {
290
- args.e = (c) => {
291
- if (!c) {
292
- return
293
- }
294
- const s = (c, options = {}) => config.getSemantics(logs).apply(args, c, options)
295
- return config.getEvaluator(s, args.calls, logs, c, { isModule: args.isModule, isProcess: args.isProcess })
285
+ if (where) {
286
+ return args.stack.wrap(() => config.evaluate(args, logs, c), where)
287
+ } else {
288
+ return config.evaluate(args, logs, c)
296
289
  }
297
- args.s = args.e
298
290
  }
291
+
299
292
  args.gs = gs(args.g)
300
293
  args.gsp = gs(args.gp)
301
294
  args.gsr = gs(args.gr)
@@ -380,7 +373,7 @@ const processContext = async (context, { objects = {}, config, logs = [] }) => {
380
373
  return { context, generated, paraphrases, responses }
381
374
  }
382
375
 
383
- const setupProcessB = ({ config, initializer, allowDelta = false, rebuildingTemplate = false } = {}) => {
376
+ const setupProcessB = ({ config, initializer, isFragment, allowDelta = false, rebuildingTemplate = false } = {}) => {
384
377
  const key = config._key
385
378
  const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
386
379
  /*
@@ -445,7 +438,7 @@ const setupContexts = (rawContexts) => {
445
438
  return contexts
446
439
  }
447
440
 
448
- const processContextsB = async ({ config, calls, hierarchy, logs, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
441
+ const processContextsB = async ({ skipSemantics, isFragment, config, calls, hierarchy, logs, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
449
442
  // TODO fix this name to contextsPrime
450
443
  const contextsPrime = []
451
444
  const generatedPrime = []
@@ -453,6 +446,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
453
446
  const paraphrasesParenthesizedPrime = []
454
447
  const generatedParenthesizedPrime = []
455
448
  const responsesPrime = []
449
+
456
450
  const contexts = setupContexts(json.contexts)
457
451
 
458
452
  const objects = config.get('objects')
@@ -474,7 +468,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
474
468
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
475
469
  }
476
470
  const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
477
- if (!config.get('skipSemantics')) {
471
+ if (!config.get('skipSemantics') && !skipSemantics) {
478
472
  const semantics = config.getSemantics(logs)
479
473
  try {
480
474
  contextPrime = await semantics.apply(args, context)
@@ -489,17 +483,18 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
489
483
  if (isInstance) {
490
484
  console.log('error', e.error)
491
485
  }
486
+
492
487
  let reason = e.reason
493
488
  if (!reason) {
494
489
  if (e.error) {
495
490
  reason = e.error[0]
496
491
  }
497
492
  }
493
+
498
494
  contextPrime = await semantics.apply(args, {
499
495
  marker: 'error',
500
496
  context,
501
- text: e ? e.toString() : 'not available',
502
- // reason: e.reason,
497
+ text: e.toString(),
503
498
  reason,
504
499
  error: e.stack || e.error
505
500
  })
package/src/fragments.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const _ = require('lodash')
2
+ const debug = require('./debug')
2
3
  const helpers = require('./helpers')
3
4
 
4
5
  function createChangeTracker(obj) {
@@ -28,11 +29,23 @@ function fragmentInstantiator (args, contexts) {
28
29
  contexts: () => {
29
30
  return _.cloneDeep(contexts)
30
31
  },
31
- instantiate: async (mappings) => {
32
+ // preserve property not to be changed.
33
+ instantiate: async (mappings, preserve) => {
34
+ preserve = preserve || []
32
35
  const instantiated = _.cloneDeep(contexts)
33
36
  const todo = [{ context: instantiated, path: [] }]
34
37
  args = { ...args }
35
38
  args.pathEquals = helpers.pathEquals
39
+ const preserved = preserve.map((path) => {
40
+ if (contexts.length == 1) {
41
+ path = ['0', path]
42
+ }
43
+ const value = helpers.getByPath(contexts, path)
44
+ return { path, value }
45
+ })
46
+ for (const context of contexts) {
47
+ context.context_id = args.config.nextFragmentContextId()
48
+ }
36
49
  while (todo.length > 0) {
37
50
  const { context, path } = todo.pop()
38
51
  const { proxy, getChanges } = createChangeTracker(context);
@@ -57,6 +70,9 @@ function fragmentInstantiator (args, contexts) {
57
70
  }
58
71
  }
59
72
  }
73
+ for (const { path, value } of preserved) {
74
+ helpers.setByPath(instantiated, path, value)
75
+ }
60
76
  if (contexts.length == 1 && instantiated.length == 1) {
61
77
  return instantiated[0]
62
78
  } else {
package/src/generators.js CHANGED
@@ -225,18 +225,18 @@ class Generators {
225
225
  const source = `${generator.km}/#${generator.index}`
226
226
  lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
227
227
  lines.newRow()
228
- lines.setElement(0, 2, generator.toString())
228
+ lines.setElement(0, 1, 'DEBUG')
229
+ lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_BREAKAT="${args.calls.current()}"`)
229
230
  lines.newRow()
230
231
  lines.setElement(0, 1, 'STACK')
231
232
  lines.setElement(0, 2, stack)
232
233
  lines.newRow()
234
+ lines.setElement(0, 2, generator.toString())
235
+ lines.newRow()
233
236
  lines.setElement(0, 1, 'TO')
234
237
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
235
238
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
236
239
  lines.newRow()
237
- lines.setElement(0, 1, 'DEBUG')
238
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_BREAKAT="${args.calls.current()}"`)
239
- lines.newRow()
240
240
  lines.setElement(0, 1, 'ERROR')
241
241
  lines.setElement(0, 2, errorMessage)
242
242
  this.logs.push(lines.toString())
@@ -256,19 +256,19 @@ class Generators {
256
256
  lines.setElement(0, 2, generator.toLabel())
257
257
  }
258
258
  lines.newRow()
259
+ lines.setElement(0, 1, 'DEBUG')
260
+ lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}')`)
261
+ lines.newRow()
259
262
  lines.setElement(0, 1, 'APPLIED')
260
263
  lines.setElement(0, 2, generator.toLabel())
261
264
  lines.newRow()
262
- lines.setElement(0, 2, generator.toString())
263
- lines.newRow()
264
265
  lines.setElement(0, 1, 'RESULT')
265
266
  lines.setElement(0, 2, generated + " " + pOrRTag)
266
267
  lines.newRow()
267
268
  lines.setElement(0, 1, 'STACK')
268
269
  lines.setElement(0, 2, stack)
269
270
  lines.newRow()
270
- lines.setElement(0, 1, 'DEBUG')
271
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}')`)
271
+ lines.setElement(0, 2, generator.toString())
272
272
  lines.newRow()
273
273
  lines.setElement(0, 1, 'TO')
274
274
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
package/src/helpers.js CHANGED
@@ -22,12 +22,30 @@ class OverrideCheck {
22
22
  }
23
23
  }
24
24
 
25
- function pathEquals (p1, p2) {
25
+ function pathEquals (p1, p2, n) {
26
+ if (n !== undefined) {
27
+ if (n < 0) {
28
+ p1 = p1.slice(n)
29
+ p2 = p2.slice(n)
30
+ } else {
31
+ p1 = p1.slice(0, n)
32
+ p2 = p2.slice(0, n)
33
+ }
34
+ }
35
+
26
36
  if (p1.length !== p2.length) {
27
37
  return false
28
38
  }
29
39
  for (let i = 0; i < p1.length; ++i) {
30
- if (typeof p2[i] == 'function') {
40
+ if (p1[i].integer) {
41
+ if (!Number.isInteger(p2[i])) {
42
+ return false
43
+ }
44
+ } else if (p2[i].integer) {
45
+ if (!Number.isInteger(p1[i])) {
46
+ return false
47
+ }
48
+ } else if (typeof p2[i] == 'function') {
31
49
  if (!p2[i](p1[i])) {
32
50
  return false
33
51
  }
@@ -72,7 +90,14 @@ function where (goUp = 2) {
72
90
  let match
73
91
  for (line of lines.slice(1)) {
74
92
  // if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
75
- if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('helpers.js:'))) {
93
+ const ignore = [
94
+ 'config.js:',
95
+ 'client.js:',
96
+ 'helpers.js:',
97
+ 'configHelpers.js:',
98
+ ]
99
+ // if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('helpers.js:'))) {
100
+ if(!ignore.some(p => line.includes(p))) {
76
101
  match = regexForm1.exec(line) || regexForm2.exec(line)
77
102
  if (!match) {
78
103
  continue
@@ -477,15 +502,6 @@ const functionsToStrings = (config) => {
477
502
  if (bridge.semantics) {
478
503
  bridge.semantics = bridge.semantics.toString()
479
504
  }
480
- if (bridge.evaluator) {
481
- bridge.evaluator = bridge.evaluator.toString()
482
- }
483
- if (bridge.evaluator2) {
484
- bridge.evaluator2 = bridge.evaluator2.toString()
485
- }
486
- if (bridge.evaluators) {
487
- bridge.evaluators = bridge.evaluators.toString()
488
- }
489
505
  return bridge
490
506
  })
491
507
  }
@@ -718,4 +734,5 @@ module.exports = {
718
734
  watchProperty,
719
735
  pathEquals,
720
736
  OverrideCheck,
737
+ normalizePath,
721
738
  }
package/src/project2.js CHANGED
@@ -1,18 +1,6 @@
1
1
  const debug = require('./debug')
2
2
  const helpers = require('./helpers')
3
3
 
4
- function areFirstNEqual(arr1, arr2, n) {
5
- if (n <= 0) return true;
6
- if (arr1.length < n || arr2.length < n) return false;
7
-
8
- for (let i = 0; i < n; i++) {
9
- if (arr1[i] !== arr2[i]) {
10
- return false;
11
- }
12
- }
13
- return true;
14
- }
15
-
16
4
  function project(source, filters, path=[]) {
17
5
  if (['boolean', 'string', 'number'].includes(typeof source)) {
18
6
  return source
@@ -49,12 +37,16 @@ function project(source, filters, path=[]) {
49
37
  let properties = []
50
38
  for (const filter of selectedFilters) {
51
39
  for (const property of filter.apply(source)) {
52
- properties.push(property)
40
+ if (!properties.includes(property)) {
41
+ properties.push(property)
42
+ }
53
43
  }
54
44
  }
55
45
  if (source?.checks) {
56
46
  for (const check of source.checks) {
57
- properties.push(check)
47
+ if (!properties.includes(check)) {
48
+ properties.push(check)
49
+ }
58
50
  }
59
51
  }
60
52
 
@@ -64,10 +56,14 @@ function project(source, filters, path=[]) {
64
56
  // property that contains a list of properties to be checked
65
57
  if (property.properties) {
66
58
  for (const moreProperty of source[property.properties] || []) {
67
- updatedProperties.push(moreProperty)
59
+ if (!updatedProperties.includes(property)) {
60
+ updatedProperties.push(moreProperty)
61
+ }
68
62
  }
69
63
  } else {
70
- updatedProperties.push(property)
64
+ if (!updatedProperties.includes(property)) {
65
+ updatedProperties.push(property)
66
+ }
71
67
  }
72
68
  }
73
69
  properties = updatedProperties
@@ -75,7 +71,7 @@ function project(source, filters, path=[]) {
75
71
  // Build the result object
76
72
  const result = {};
77
73
  properties.forEach(prop => {
78
- if (prop.path && (prop.path.length === path.length + 1) && areFirstNEqual(path, prop.path, path.length) && source.hasOwnProperty(prop.path[path.length])) {
74
+ if (prop.path && (prop.path.length === path.length + 1) && helpers.pathEquals(path, prop.path, path.length) && source.hasOwnProperty(prop.path[path.length])) {
79
75
  const endProp = prop.path[path.length]
80
76
  if (['boolean', 'string', 'number'].includes(typeof source[endProp])) {
81
77
  result[endProp] = source[endProp]
@@ -109,8 +105,18 @@ function project(source, filters, path=[]) {
109
105
  const instantiatedCheck = []
110
106
  for (const check of prop.check) {
111
107
  if (typeof check.property == 'function') {
112
- for (const sourceKey of source[prop.property].keys()) {
108
+ const keys = (value) => {
109
+ if (Array.isArray(value)) {
110
+ return value.keys()
111
+ } else {
112
+ return Object.keys(value)
113
+ }
114
+ }
115
+ for (const sourceKey of keys(source[prop.property])) {
113
116
  if (check.property(sourceKey)) {
117
+ if (!check.check) {
118
+ throw new Error(`For the property check of the property '${check.property.toString()}', the 'check' (singular) property is missing.`)
119
+ }
114
120
  instantiatedCheck.push({ property: sourceKey, check: check.check })
115
121
  }
116
122
  }
package/src/semantics.js CHANGED
@@ -226,6 +226,7 @@ class Semantics {
226
226
  }
227
227
  contextPrime = await semantic.apply(args, context, s, options)
228
228
  if (continueWasCalled) {
229
+ context = contextPrime
229
230
  continue
230
231
  }
231
232
  if (deferWasCalled) {
@@ -259,14 +260,14 @@ class Semantics {
259
260
  const source = `${semantic.km}/#${semantic.index}`
260
261
  lines.setElement(0, 2, `ERROR while applying (${source}) ${semantic.toLabel()}`)
261
262
  lines.newRow()
262
- lines.setElement(0, 2, semantic.toString())
263
- lines.newRow()
264
263
  lines.setElement(0, 1, 'DEBUG')
265
264
  lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
266
265
  lines.newRow()
267
266
  lines.setElement(0, 1, 'STACK')
268
267
  lines.setElement(0, 2, stack)
269
268
  lines.newRow()
269
+ lines.setElement(0, 2, semantic.toString())
270
+ lines.newRow()
270
271
  lines.setElement(0, 1, 'TO')
271
272
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
272
273
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
@@ -277,6 +278,9 @@ class Semantics {
277
278
  const message = `ERROR while applying (${source}) ${semantic.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
278
279
  // this.logs.push(message)
279
280
  // return [message]
281
+ if (e.reason) {
282
+ throw e
283
+ }
280
284
  args.calls.pop()
281
285
  throw { error: [message], logs: this.logs, reason: e.reason }
282
286
  }
@@ -295,14 +299,14 @@ class Semantics {
295
299
  lines.setElement(0, 1, 'APPLIED')
296
300
  lines.setElement(0, 2, semantic.toLabel())
297
301
  lines.newRow()
298
- lines.setElement(0, 2, semantic.toString())
299
- lines.newRow()
300
302
  lines.setElement(0, 1, 'DEBUG')
301
303
  lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
302
304
  lines.newRow()
303
305
  lines.setElement(0, 1, 'STACK')
304
306
  lines.setElement(0, 2, stack)
305
307
  lines.newRow()
308
+ lines.setElement(0, 2, semantic.toString())
309
+ lines.newRow()
306
310
  lines.setElement(0, 1, 'TO')
307
311
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
308
312
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
@@ -332,7 +336,6 @@ class Semantics {
332
336
  for (const f of finallyList) {
333
337
  await f()
334
338
  }
335
- args.calls.pop()
336
339
  if (!applied && debug) {
337
340
  const widths = Lines.addRemainder([10, 10])
338
341
  const lines = new Lines(widths)
@@ -340,6 +343,9 @@ class Semantics {
340
343
  lines.setElement(0, 1, `#${context.context_id || "?"}`)
341
344
  lines.setElement(0, 2, 'No semantic applied')
342
345
  lines.newRow()
346
+ lines.setElement(0, 1, 'DEBUG')
347
+ lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
348
+ lines.newRow()
343
349
  lines.setElement(0, 1, 'STACK')
344
350
  lines.setElement(0, 2, stack)
345
351
  lines.newRow()
@@ -348,6 +354,7 @@ class Semantics {
348
354
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
349
355
  this.logs.push(lines.toString())
350
356
  }
357
+ args.calls.pop()
351
358
  return contextPrime
352
359
  }
353
360