theprogrammablemind 9.8.0 → 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
@@ -12,7 +12,7 @@ const _ = require('lodash')
12
12
  const stringify = require('json-stable-stringify')
13
13
  const Lines = require('./lines')
14
14
  const flattens = require('./src/flatten')
15
- const { helpDebugHierarchy, sortJson, appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps, OverrideCheck, } = require('./src/helpers')
15
+ const { helpDebugHierarchy, sortJson, appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps, OverrideCheck, removeProp, } = require('./src/helpers')
16
16
  const runtime = require('./runtime')
17
17
  const db = require('./src/debug')
18
18
 
@@ -59,20 +59,11 @@ const pickObjects = (config, testConfig, getObjects) => {
59
59
  throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
60
60
  }
61
61
 
62
- if (false) {
63
- if (checks[km] && checks[km].find((check) => check.match && check.apply)) {
64
- projection[km] = project2(objects, checks[km])
65
- } else {
66
- projection[km] = project(objects, checks[km])
67
- }
68
- } else {
69
- const lastIndex = contextChecks.length - 1
70
- const last = contextChecks[lastIndex]
71
- contextChecks[lastIndex] = { match: last.match, apply: () => [...new Set([...(checks[km] || []), ...last.apply()])] }
62
+ const lastIndex = contextChecks.length - 1
63
+ const last = contextChecks[lastIndex]
64
+ contextChecks[lastIndex] = { match: last.match, apply: () => [...new Set([...(checks[km] || []), ...last.apply()])] }
72
65
 
73
- // projection[km] = project2(objects, [...checks[km], ...contextChecks])
74
- projection[km] = project2(objects, contextChecks)
75
- }
66
+ projection[km] = project2(objects, contextChecks)
76
67
  }
77
68
  return projection
78
69
  }
@@ -167,13 +158,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
167
158
  if (runtime.fs.existsSync(fn)) {
168
159
  tests = JSON.parse(runtime.fs.readFileSync(fn))
169
160
  }
170
- /*
171
- for (const association of associations) {
172
- association.sort()
173
- }
174
- associations.sort()
175
- */
176
- // tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
177
161
  const results = sortJson({
178
162
  query,
179
163
  summaries,
@@ -198,7 +182,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
198
182
  if (!wasSet) {
199
183
  tests.push(results)
200
184
  }
201
- // fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
202
185
  writeTestFile(fn, tests)
203
186
  }
204
187
 
@@ -267,7 +250,7 @@ const throwErrorHandler = (error) => {
267
250
  throw error
268
251
  }
269
252
 
270
- 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 } = {}) => {
271
254
  if (credentials) {
272
255
  config.server(credentials.server, credentials.key)
273
256
  }
@@ -373,7 +356,7 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
373
356
  const summary = { summaries: json.summaries, length: json.contexts.length }
374
357
  summaries.push(summary)
375
358
  const { updatedContextIdCounter, contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
376
- 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 */ })
377
360
  contextIdCounter = updatedContextIdCounter
378
361
  if (isTest) {
379
362
  const end = runtime.performance.performance.now()
@@ -390,9 +373,9 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
390
373
  response.trace = response.trace.concat(json.trace)
391
374
  response.version = json.version
392
375
  response.explain_priorities = json.explain_priorities
393
- response.explain_associations = json.explain_associations
376
+ response.explain_associations_details = (response.explain_associations_details || []).concat(json.explain_associations_details)
377
+ response.explain_associations_trie = json.explain_associations_trie
394
378
  response.contextual_priorities_ambiguities = json.contextual_priorities_ambiguities
395
- // response.rtf_associations = json.rtf_associations
396
379
 
397
380
  response.contexts = response.contexts.concat(contextsPrime)
398
381
  response.generated = response.generated.concat(generatedPrime)
@@ -895,8 +878,11 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
895
878
  }
896
879
  }
897
880
 
898
- if (responses.explain_associations) {
899
- console.log(responses.explain_associations)
881
+ if (responses.explain_associations_details) {
882
+ console.log(responses.explain_associations_trie)
883
+ for (const l of responses.explain_associations_details) {
884
+ console.log(l)
885
+ }
900
886
  }
901
887
 
902
888
  // const objects = config.get('objects').namespaced[config.uuid]
@@ -907,6 +893,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
907
893
  const km = config.configs.find((km) => km.name === name)
908
894
  return config.config.objects.namespaced[km.uuid] || {}
909
895
  }
896
+
910
897
  const picked = sortJson(pickObjects(config, config.testConfig, actualGetObjects), { depth: 25 })
911
898
  if (!_.isEmpty(picked)) {
912
899
  console.log('--- Object showing only the checked values ---')
@@ -1041,7 +1028,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1041
1028
  await loadInstance(config, { resultss: [results] })
1042
1029
  } else {
1043
1030
  try {
1044
- results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
1031
+ results = await _process(config, query.query, { initializer, rebuildingTemplate: true, isFragment })
1045
1032
  } catch (e) {
1046
1033
  if (e.summaries && e.summaries.length > 0) {
1047
1034
  suggestFix(e.summaries)
@@ -1069,7 +1056,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1069
1056
  results.isFragment = isFragment
1070
1057
  results.skipSemantics = skipSemantics
1071
1058
  results.development = query.development
1072
- results.key = { query: query.query, hierarchy }
1059
+ results.key = { query: query.query, hierarchy, preserve: query.preserve }
1073
1060
  accumulators[property].push(results)
1074
1061
  if (isFragment) {
1075
1062
  config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
@@ -1135,6 +1122,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1135
1122
  const stabilizeOutput = (template) => {
1136
1123
  // stabilizeAssociations(template.associations)
1137
1124
  const stabilize = (results) => {
1125
+ removeProp(results, (_, k) => k === "context_id")
1138
1126
  for (let i = 0; i < results.length; ++i) {
1139
1127
  const result = results[i]
1140
1128
  if (result.apply) {
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { Semantics, Semantic } = require('./src/semantics')
2
2
  const { Generators, Generator } = require('./src/generators')
3
3
  const { Config } = require('./src/config')
4
- const { w, where, OverrideCheck, setByPath, getByPath } = require('./src/helpers')
4
+ const { w, where, OverrideCheck, setByPath, getByPath, removeProp } = require('./src/helpers')
5
5
  const Digraph = require('./src/digraph')
6
6
  const client = require('./client')
7
7
  const flattens = require('./src/flatten')
@@ -32,4 +32,5 @@ module.exports = {
32
32
  unflatten: unflatten.unflatten,
33
33
  debug,
34
34
  OverrideCheck,
35
+ removeProp,
35
36
  }
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",
78
+ "version": "9.9.0",
77
79
  "license": "UNLICENSED"
78
80
  }
package/src/config.js CHANGED
@@ -295,9 +295,6 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
295
295
  if (bridge.scope && config.isModule) {
296
296
  return
297
297
  }
298
- if (false && !bridge.bridge) {
299
- bridge.bridge = '{ ...next(operator) }'
300
- }
301
298
  if (!bridge.level) {
302
299
  bridge.level = 0
303
300
  }
@@ -391,6 +388,13 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
391
388
  }
392
389
  */
393
390
 
391
+ if (!bridge.where) {
392
+ if (bridge.generator || bridge.generatorp || bridge.generatorr || bridge.generator ||
393
+ bridge.semantic || bridge.semantics) {
394
+ throw new Error(`In the KM "${config.name}", for the bridge ${bridge.id} the where property is missing. Use where: where().`)
395
+ }
396
+ }
397
+
394
398
  const addUUID = (obj) => { return { ...obj, uuid: uuid || config.uuid } }
395
399
 
396
400
  if (bridge.generators) {
@@ -469,7 +473,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
469
473
  }
470
474
  }
471
475
 
472
- const addSemantic = (semantic, evaluate) => {
476
+ const addSemantic = (semantic, evaluate, property) => {
473
477
  const match = semantic.match || (() => true)
474
478
  let apply = semantic
475
479
  // if I do apply === semantic.apply or semantic there is one function that has apply defined for some reason even though not explicitly set
@@ -491,13 +495,13 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
491
495
  }
492
496
  } else {
493
497
  semanticDef = {
494
- match: (args) => bridge.id === args.context.marker && !!args.context.evaluate === evaluate && match(args),
498
+ match: (args) => bridge.id === args.context.marker && match(args),
495
499
  apply: (args) => apply(args),
496
500
  applyWrapped: semantic,
497
501
  }
498
502
  }
499
503
  semanticDef.where = semantic.where || bridge.where || helpers.where(4)
500
- semanticDef.property = evaluate ? 'evaluator' : 'semantic'
504
+ semanticDef.property = property
501
505
  if (semantic.priority) {
502
506
  semanticDef.priority = semantic.priority
503
507
  }
@@ -509,22 +513,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
509
513
  }
510
514
  }
511
515
 
512
- if (bridge.evaluator) {
513
- addSemantic(bridge.evaluator, true)
514
- }
515
-
516
516
  if (bridge.semantic) {
517
- addSemantic(bridge.semantic, false)
518
- }
519
-
520
- if (bridge.evaluators) {
521
- const evaluators = [...bridge.evaluators]
522
- evaluators.reverse()
523
- if (evaluators) {
524
- for (const evaluator of evaluators) {
525
- addSemantic(evaluator, true)
526
- }
527
- }
517
+ addSemantic(bridge.semantic, false, 'semantic')
528
518
  }
529
519
 
530
520
  if (bridge.semantics) {
@@ -556,8 +546,6 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
556
546
  'convolution',
557
547
  'disabled',
558
548
  'enhanced_associations',
559
- 'evaluator',
560
- 'evaluators',
561
549
  'generatorp',
562
550
  'generatorpr',
563
551
  'generatorr',
@@ -996,9 +984,10 @@ class Config {
996
984
 
997
985
  async fixtures () {
998
986
  if (this.testConfig?.fixtures) {
999
- const args = {}
987
+ const args = {
988
+ }
1000
989
  args.uuid = this._uuid
1001
- configHelpers.setupArgs(args, this)
990
+ configHelpers.setupArgs(args, this, this.logs)
1002
991
  return this.testConfig.fixtures(args)
1003
992
  }
1004
993
  }
@@ -1029,6 +1018,7 @@ class Config {
1029
1018
  return {
1030
1019
  pseudo: true,
1031
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(),
1032
1022
  addAssociation: (...args) => this.addAssociation(...args),
1033
1023
  addAssociations: (...args) => this.addAssociations(...args),
1034
1024
  addBridge: (...args) => this.addBridge(...args, uuid),
@@ -1043,6 +1033,7 @@ class Config {
1043
1033
  addPattern: (...args) => this.addPattern(...args, uuid),
1044
1034
  updateBridge: (...args) => this.updateBridge(...args),
1045
1035
  processContext: (...args) => this.processContext(...args),
1036
+ logs: this.logs,
1046
1037
 
1047
1038
  semantics: () => this.config.semantics,
1048
1039
  getConfigs: () => this.configs,
@@ -1242,7 +1233,7 @@ class Config {
1242
1233
 
1243
1234
  warningNotEvaluated (log, value) {
1244
1235
  const description = 'WARNING: for semantics, implement an evaluations handler, set "value" property of the operator to the value.'
1245
- 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>`
1246
1237
  const apply = '({context}) => <do stuff...>; context.value = <value>'
1247
1238
  const input = indent(JSON.stringify(value, null, 2), 2)
1248
1239
  const message = `${description}\nThe semantic would be\n match: ${match}\n apply: ${apply}\nThe input context would be:\n${input}\n`
@@ -1251,18 +1242,15 @@ class Config {
1251
1242
 
1252
1243
  // value is in response field
1253
1244
  // TODO maybe generalize out query+evaluate along the lines of set value and set reference
1254
- async getEvaluator (s, calls, log, context, args) {
1255
- const instance = await s({ ...args, ...context, evaluate: true })
1256
- calls.touch(instance)
1257
- if (instance.evalue == null && !instance.verbatim && !instance.value) {
1258
- 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)
1259
1250
  }
1260
- if (instance.evalue == null) {
1261
- instance.evalue = instance.value
1262
- instance.edefault = true
1251
+ if (instance.evalue == null && !instance.verbatim && !instance.value) {
1252
+ this.warningNotEvaluated(logs, context)
1263
1253
  }
1264
- delete instance.evaluate
1265
- instance.instance = true
1266
1254
  return instance
1267
1255
  }
1268
1256
 
@@ -1293,10 +1281,14 @@ class Config {
1293
1281
  let fi = fragmentInstantiator(args, fragment.contexts)
1294
1282
  if (mappings) {
1295
1283
  fi = await fi
1296
- return fi.instantiate([{
1284
+ const instantiated = await fi.instantiate([{
1297
1285
  match: ({context}) => !!mappings[context.value], // is the value in the mappings
1298
1286
  apply: ({context}) => Object.assign(context, mappings[context.value]),
1299
- }])
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
1300
1292
  } else {
1301
1293
  return fi
1302
1294
  }
@@ -1305,6 +1297,7 @@ class Config {
1305
1297
  }
1306
1298
  }
1307
1299
 
1300
+ /*
1308
1301
  fragmentMapper (args, values, fromModelQuery, toModelQuery) {
1309
1302
  const fromModelFragment = this.getFragment(fromModelQuery)
1310
1303
  console.dir(fromModelFragment)
@@ -1313,6 +1306,7 @@ class Config {
1313
1306
  const mapper = fragmentMapperInstantiator(values, fromModelFragment.contexts, toModelFragment.contexts)
1314
1307
  return mapper
1315
1308
  }
1309
+ */
1316
1310
 
1317
1311
  // { rebuild: false, isModule: false }
1318
1312
  needsRebuild (template, instance, options) {
@@ -1384,6 +1378,7 @@ class Config {
1384
1378
  bridge = { ...bridge },
1385
1379
  bridge.level = bridge.level || 0
1386
1380
  delete bridge.uuid
1381
+ delete bridge.where
1387
1382
  return bridge
1388
1383
  })
1389
1384
  if (options.isModule) {
@@ -1396,8 +1391,6 @@ class Config {
1396
1391
  delete bridge.generatorp
1397
1392
  delete bridge.generatorr
1398
1393
  delete bridge.generatorpr
1399
- delete bridge.evaluator
1400
- delete bridge.evaluators
1401
1394
  delete bridge.semantic
1402
1395
  delete bridge.semantics
1403
1396
  if (false && !bridge.bridge) {
@@ -2179,6 +2172,12 @@ class Config {
2179
2172
  // await this.demoInitializer(this)
2180
2173
  }
2181
2174
 
2175
+ nextFragmentContextId() {
2176
+ const id = this.fragmentNextContextId
2177
+ this.fragmentNextContextId = this.fragmentNextContextId + 1
2178
+ return id
2179
+ }
2180
+
2182
2181
  // configs = [ { config, namespace } ... ]
2183
2182
  constructor (config, module, clientProcess, apiKMs, rootIsProcess, testingModuleName) {
2184
2183
  if (config instanceof Config) {
@@ -2189,6 +2188,8 @@ class Config {
2189
2188
  apiKMs = []
2190
2189
  }
2191
2190
 
2191
+ this.fragmentNextContextId = 1000
2192
+
2192
2193
  if (config) {
2193
2194
  validConfigProps(config)
2194
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,13 +103,25 @@ 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
 
113
+ async wrap(call, w) {
114
+ this.push(w)
115
+ const p = await call()
116
+ if (p && typeof p.finally === 'function') {
117
+ return p.finally(() => {
118
+ this.pop()
119
+ })
120
+ }
121
+ this.pop()
122
+ return p
123
+ }
124
+
103
125
  toString() {
104
126
  let str = ''
105
127
  for (let i = this.handlers.length - 1; i >= 0; --i) {
@@ -185,7 +207,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
185
207
  args.km = (name) => config.getConfig(name)
186
208
  args.api = (name) => config.getConfig(name).api
187
209
  args.error = (context) => {
188
- throw new ErrorReason(context)
210
+ throw new ErrorReason(context, [...args.stack.handlers, where()])
189
211
  }
190
212
  args.kms = config.getConfigs()
191
213
  args.config = config.getPseudoConfig(uuidForScoping, config)
@@ -198,15 +220,15 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
198
220
  args.fragments = (query, mappings) => {
199
221
  return config.fragment(args, query, mappings)
200
222
  }
223
+ /*
201
224
  args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
202
225
  return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
203
226
  }
227
+ */
204
228
  args.breakOnSemantics = false
205
229
  args.theDebugger = {
206
230
  breakOnSemantics: (value) => args.breakOnSemantics = value
207
231
  }
208
- if (!logs) {
209
- }
210
232
  args.log = (message) => logs.push(message)
211
233
 
212
234
  args.addWord = (word, def) => config.addWord(word, def, args.uuid)
@@ -221,7 +243,6 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
221
243
  return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
222
244
  }
223
245
 
224
- args.s = (c, options = {}) => config.getSemantics(logs).apply(args, c, options)
225
246
  args.g = (c, rest = {}) => {
226
247
  // if (JSON.stringify(rest) !== '{}' && !(rest.assumed || rest.options)) {
227
248
  // debugger
@@ -256,12 +277,18 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
256
277
  const { assumed = {}, options = {} } = rest
257
278
  return config.getGenerators(logs).apply(addAssumed(args, assumed, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true }, options)
258
279
  }
259
- args.e = (c) => {
280
+
281
+ args.e = (c, where) => {
260
282
  if (!c) {
261
283
  return
262
284
  }
263
- return config.getEvaluator(args.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)
289
+ }
264
290
  }
291
+
265
292
  args.gs = gs(args.g)
266
293
  args.gsp = gs(args.gp)
267
294
  args.gsr = gs(args.gr)
@@ -346,7 +373,7 @@ const processContext = async (context, { objects = {}, config, logs = [] }) => {
346
373
  return { context, generated, paraphrases, responses }
347
374
  }
348
375
 
349
- const setupProcessB = ({ config, initializer, allowDelta = false, rebuildingTemplate = false } = {}) => {
376
+ const setupProcessB = ({ config, initializer, isFragment, allowDelta = false, rebuildingTemplate = false } = {}) => {
350
377
  const key = config._key
351
378
  const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
352
379
  /*
@@ -411,7 +438,7 @@ const setupContexts = (rawContexts) => {
411
438
  return contexts
412
439
  }
413
440
 
414
- 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 }) => {
415
442
  // TODO fix this name to contextsPrime
416
443
  const contextsPrime = []
417
444
  const generatedPrime = []
@@ -419,6 +446,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
419
446
  const paraphrasesParenthesizedPrime = []
420
447
  const generatedParenthesizedPrime = []
421
448
  const responsesPrime = []
449
+
422
450
  const contexts = setupContexts(json.contexts)
423
451
 
424
452
  const objects = config.get('objects')
@@ -440,7 +468,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
440
468
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
441
469
  }
442
470
  const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
443
- if (!config.get('skipSemantics')) {
471
+ if (!config.get('skipSemantics') && !skipSemantics) {
444
472
  const semantics = config.getSemantics(logs)
445
473
  try {
446
474
  contextPrime = await semantics.apply(args, context)
@@ -455,17 +483,18 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
455
483
  if (isInstance) {
456
484
  console.log('error', e.error)
457
485
  }
486
+
458
487
  let reason = e.reason
459
488
  if (!reason) {
460
489
  if (e.error) {
461
490
  reason = e.error[0]
462
491
  }
463
492
  }
493
+
464
494
  contextPrime = await semantics.apply(args, {
465
495
  marker: 'error',
466
496
  context,
467
- text: e ? e.toString() : 'not available',
468
- // reason: e.reason,
497
+ text: e.toString(),
469
498
  reason,
470
499
  error: e.stack || e.error
471
500
  })
@@ -578,14 +607,14 @@ const loadInstance = async (config, instance) => {
578
607
  // used to do a CLONE
579
608
  config.addInternal(instance.template.configs[i], { uuid, km: instance.name, addFirst: true, handleCalculatedProps: true })
580
609
  } else if (results.apply) {
581
- const objects = getObjects(config.get('objects'))(config.uuid)
610
+ const uuid = config.nameToUUID(instance.name)
611
+ const objects = getObjects(config.get('objects'))(uuid)
582
612
  const args = { objects, getObjects: getObjects(objects) }
583
613
  if (instance.configs) {
584
614
  args.isInstance = `instance${i}`
585
615
  args.instance = instance.configs[i]
586
616
  }
587
617
 
588
- const uuid = config.nameToUUID(instance.name)
589
618
  setupArgs(args, config, config.logs, hierarchy, uuid)
590
619
  if (config.name == instance.name) {
591
620
  args.isModule = !!config.isModule
@@ -609,6 +638,7 @@ const loadInstance = async (config, instance) => {
609
638
  args.instance = ''
610
639
  args.isProcess = !config.isModule
611
640
  args.isModule = !!config.isModule
641
+ args.logs = config.logs
612
642
  if (instance.name == config.testConfig.testModuleName) {
613
643
  args.isTesting = true
614
644
  }
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) {
@@ -23,17 +24,28 @@ function createChangeTracker(obj) {
23
24
  };
24
25
  }
25
26
 
26
-
27
27
  function fragmentInstantiator (args, contexts) {
28
28
  return new Object({
29
29
  contexts: () => {
30
30
  return _.cloneDeep(contexts)
31
31
  },
32
- instantiate: async (mappings) => {
32
+ // preserve property not to be changed.
33
+ instantiate: async (mappings, preserve) => {
34
+ preserve = preserve || []
33
35
  const instantiated = _.cloneDeep(contexts)
34
36
  const todo = [{ context: instantiated, path: [] }]
35
37
  args = { ...args }
36
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
+ }
37
49
  while (todo.length > 0) {
38
50
  const { context, path } = todo.pop()
39
51
  const { proxy, getChanges } = createChangeTracker(context);
@@ -58,6 +70,9 @@ function fragmentInstantiator (args, contexts) {
58
70
  }
59
71
  }
60
72
  }
73
+ for (const { path, value } of preserved) {
74
+ helpers.setByPath(instantiated, path, value)
75
+ }
61
76
  if (contexts.length == 1 && instantiated.length == 1) {
62
77
  return instantiated[0]
63
78
  } else {
package/src/generators.js CHANGED
@@ -125,7 +125,7 @@ class Generator {
125
125
  args.g = args.gp
126
126
  }
127
127
  return await debug.hitScoped(args.callId, async () => {
128
- if ((options.debug || {}).apply || process.env.DEBUG_CALLID == args.callId || callId === this.callId) {
128
+ if ((options.debug || {}).apply || process.env.DEBUG_BREAKAT == args.callId || callId === this.callId) {
129
129
  debugger // eslint-disable-line no-debugger
130
130
  }
131
131
  return await this._apply(args) // DEBUG: This is the line you want to step into
@@ -184,6 +184,9 @@ class Generators {
184
184
  let generated = ''
185
185
  let applied = false
186
186
  const stack = args.calls.push()
187
+ const pOrRTag = assumed.isResponse ? "(RESPONSE)" : "(PARAPHRASE)"
188
+ const finallyList = []; // called after the generator is processed
189
+ args._finally = (call) => finallyList.unshift(call)
187
190
  for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
188
191
  const generator = this.generators[igenerator]
189
192
  if (await generator.matches(args, objects, context, hierarchy, config, options)) {
@@ -194,7 +197,7 @@ class Generators {
194
197
  console.error("TPMKMS_TRACE", debug.counter("TPMKMS_TRACE"))
195
198
  console.error(generator.toLabel())
196
199
  console.error(generator.toString())
197
- console.log(`To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_CALLID="${args.calls.current()}"`)
200
+ console.log(`To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_BREAKAT="${args.calls.current()}"`)
198
201
  }
199
202
 
200
203
  try {
@@ -218,21 +221,22 @@ class Generators {
218
221
  const widths = Lines.addRemainder([10, 10])
219
222
  const lines = new Lines(widths)
220
223
  lines.setElement(0, 0, 'Generator')
224
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
221
225
  const source = `${generator.km}/#${generator.index}`
222
226
  lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
223
227
  lines.newRow()
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()}"`)
230
+ lines.newRow()
231
+ lines.setElement(0, 1, 'STACK')
232
+ lines.setElement(0, 2, stack)
233
+ lines.newRow()
224
234
  lines.setElement(0, 2, generator.toString())
225
235
  lines.newRow()
226
236
  lines.setElement(0, 1, 'TO')
227
237
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
228
238
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
229
239
  lines.newRow()
230
- lines.setElement(0, 1, 'STACK')
231
- lines.setElement(0, 2, stack)
232
- lines.newRow()
233
- lines.setElement(0, 1, 'DEBUG')
234
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_CALLID="${args.calls.current()}"`)
235
- lines.newRow()
236
240
  lines.setElement(0, 1, 'ERROR')
237
241
  lines.setElement(0, 2, errorMessage)
238
242
  this.logs.push(lines.toString())
@@ -246,24 +250,25 @@ class Generators {
246
250
  const widths = Lines.addRemainder([10, 10])
247
251
  const lines = new Lines(widths)
248
252
  lines.setElement(0, 0, 'Generator')
253
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
249
254
  if (generator.index > -1 && generator.km) {
250
255
  // lines.setElement(0, 2, `KM '${generator.km}' ordinal: ${generator.index}`)
251
256
  lines.setElement(0, 2, generator.toLabel())
252
257
  }
253
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()
254
262
  lines.setElement(0, 1, 'APPLIED')
255
263
  lines.setElement(0, 2, generator.toLabel())
256
264
  lines.newRow()
257
- lines.setElement(0, 2, generator.toString())
258
- lines.newRow()
259
265
  lines.setElement(0, 1, 'RESULT')
260
- lines.setElement(0, 2, generated)
266
+ lines.setElement(0, 2, generated + " " + pOrRTag)
261
267
  lines.newRow()
262
268
  lines.setElement(0, 1, 'STACK')
263
269
  lines.setElement(0, 2, stack)
264
270
  lines.newRow()
265
- lines.setElement(0, 1, 'DEBUG')
266
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}')`)
271
+ lines.setElement(0, 2, generator.toString())
267
272
  lines.newRow()
268
273
  lines.setElement(0, 1, 'TO')
269
274
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
@@ -274,11 +279,15 @@ class Generators {
274
279
  break
275
280
  }
276
281
  }
282
+ for (const f of finallyList) {
283
+ await f()
284
+ }
277
285
  args.calls.pop()
278
286
  if (!applied && config.getDebug()) {
279
287
  const widths = Lines.addRemainder([10, 10])
280
288
  const lines = new Lines(widths)
281
289
  lines.setElement(0, 0, 'Generator')
290
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
282
291
  lines.setElement(0, 2, 'No generator applied')
283
292
  lines.newRow()
284
293
  lines.setElement(0, 1, 'STACK')
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,12 +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.evaluators) {
484
- bridge.evaluators = bridge.evaluators.toString()
485
- }
486
505
  return bridge
487
506
  })
488
507
  }
@@ -627,7 +646,60 @@ function setByPath(obj, path, value) {
627
646
 
628
647
  const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'["cat", "mammel"]\''
629
648
 
649
+ // removeProp.js
650
+ function removeProp(obj, testFn, { maxDepth = Infinity, seen = new WeakSet() } = {}) {
651
+ if (!obj || typeof obj !== 'object' || maxDepth <= 0) return obj;
652
+ if (seen.has(obj)) return obj;
653
+ seen.add(obj);
654
+
655
+ if (Array.isArray(obj)) {
656
+ // ---- ARRAY: process each element (but don't remove elements unless testFn says so)
657
+ let writeIdx = 0;
658
+ for (let i = 0; i < obj.length; i++) {
659
+ const element = obj[i];
660
+ const shouldRemoveElement = testFn(element, i, obj);
661
+
662
+ if (shouldRemoveElement) {
663
+ // Remove the whole array element
664
+ if (element && typeof element === 'object') {
665
+ // Still walk inside it in case testFn wants side effects
666
+ removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
667
+ }
668
+ // Skip writing it back
669
+ } else {
670
+ // Keep element, but walk into it to remove inner props
671
+ removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
672
+ if (writeIdx !== i) {
673
+ obj[writeIdx] = element;
674
+ }
675
+ writeIdx++;
676
+ }
677
+ }
678
+ obj.length = writeIdx;
679
+ return obj;
680
+ }
681
+
682
+ // ---- OBJECT: iterate over own keys
683
+ const keys = Reflect.ownKeys(obj);
684
+ for (const key of keys) {
685
+ const val = obj[key];
686
+ const shouldRemove = testFn(val, key, obj);
687
+
688
+ if (shouldRemove) {
689
+ delete obj[key];
690
+ if (val && typeof val === 'object') {
691
+ removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
692
+ }
693
+ } else {
694
+ removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
695
+ }
696
+ }
697
+
698
+ return obj;
699
+ }
700
+
630
701
  module.exports = {
702
+ removeProp,
631
703
  helpDebugHierarchy,
632
704
 
633
705
  stableId,
@@ -662,4 +734,5 @@ module.exports = {
662
734
  watchProperty,
663
735
  pathEquals,
664
736
  OverrideCheck,
737
+ normalizePath,
665
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
@@ -78,7 +78,7 @@ class Semantic {
78
78
  return await debug.hitScoped(args.callId, async () => {
79
79
  const matches = await this.matcher(args)
80
80
  if (matches) {
81
- if ((options.debug || {}).match || args.callId === this.callId || process.env.DEBUG_CALLID == args.callId) {
81
+ if ((options.debug || {}).match || args.callId === this.callId || process.env.DEBUG_BREAKAT == args.callId) {
82
82
  debugger // eslint-disable-line no-debugger
83
83
  await this.matcher(args) // DEBUG: This is the line you step into
84
84
  }
@@ -101,7 +101,7 @@ class Semantic {
101
101
  this.fixUpArgs(args, contextPrime)
102
102
 
103
103
  return await debug.hitScoped(args.callId, async () => {
104
- if ((options.debug || {}).apply || args.callId === this.callId || process.env.DEBUG_CALLID == args.callId) {
104
+ if ((options.debug || {}).apply || args.callId === this.callId || process.env.DEBUG_BREAKAT == args.callId) {
105
105
  debugger // eslint-disable-line no-debugger // STEP ABOUT THREE TIMES TO THE DEBUG LINE
106
106
  }
107
107
  if (args.breakOnSemantics) {
@@ -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) {
@@ -255,27 +256,31 @@ class Semantics {
255
256
  const widths = Lines.addRemainder([10, 10])
256
257
  const lines = new Lines(widths)
257
258
  lines.setElement(0, 0, 'Semantic')
259
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
258
260
  const source = `${semantic.km}/#${semantic.index}`
259
261
  lines.setElement(0, 2, `ERROR while applying (${source}) ${semantic.toLabel()}`)
260
262
  lines.newRow()
261
- lines.setElement(0, 2, semantic.toString())
262
- lines.newRow()
263
263
  lines.setElement(0, 1, 'DEBUG')
264
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_CALLID="${args.calls.current()}"`)
264
+ lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
265
+ lines.newRow()
266
+ lines.setElement(0, 1, 'STACK')
267
+ lines.setElement(0, 2, stack)
268
+ lines.newRow()
269
+ lines.setElement(0, 2, semantic.toString())
265
270
  lines.newRow()
266
271
  lines.setElement(0, 1, 'TO')
267
272
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
268
273
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
269
274
  lines.newRow()
270
- lines.setElement(0, 1, 'STACK')
271
- lines.setElement(0, 2, stack)
272
- lines.newRow()
273
275
  lines.setElement(0, 1, 'ERROR')
274
276
  lines.setElement(0, 2, errorMessage)
275
277
  this.logs.push(lines.toString())
276
278
  const message = `ERROR while applying (${source}) ${semantic.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
277
279
  // this.logs.push(message)
278
280
  // return [message]
281
+ if (e.reason) {
282
+ throw e
283
+ }
279
284
  args.calls.pop()
280
285
  throw { error: [message], logs: this.logs, reason: e.reason }
281
286
  }
@@ -285,6 +290,7 @@ class Semantics {
285
290
  const widths = Lines.addRemainder([10, 10])
286
291
  const lines = new Lines(widths)
287
292
  lines.setElement(0, 0, 'Semantic')
293
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
288
294
  if (semantic.index > -1 && semantic.km) {
289
295
  // lines.setElement(0, 2, `KM '${semantic.km}' ordinal: ${semantic.index} ${ semantic.notes ? semantic.nodes : '' }`)
290
296
  lines.setElement(0, 2, semantic.toLabel())
@@ -293,18 +299,18 @@ class Semantics {
293
299
  lines.setElement(0, 1, 'APPLIED')
294
300
  lines.setElement(0, 2, semantic.toLabel())
295
301
  lines.newRow()
296
- lines.setElement(0, 2, semantic.toString())
297
- lines.newRow()
298
302
  lines.setElement(0, 1, 'DEBUG')
299
- lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_CALLID="${args.calls.current()}"`)
303
+ lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
304
+ lines.newRow()
305
+ lines.setElement(0, 1, 'STACK')
306
+ lines.setElement(0, 2, stack)
307
+ lines.newRow()
308
+ lines.setElement(0, 2, semantic.toString())
300
309
  lines.newRow()
301
310
  lines.setElement(0, 1, 'TO')
302
311
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
303
312
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
304
313
  lines.newRow()
305
- lines.setElement(0, 1, 'STACK')
306
- lines.setElement(0, 2, stack)
307
- lines.newRow()
308
314
  lines.setElement(0, 1, 'RESULT')
309
315
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
310
316
  lines.setElement(1, 2, JSON.stringify(contextPrime, null, 2))
@@ -330,13 +336,16 @@ class Semantics {
330
336
  for (const f of finallyList) {
331
337
  await f()
332
338
  }
333
- args.calls.pop()
334
339
  if (!applied && debug) {
335
340
  const widths = Lines.addRemainder([10, 10])
336
341
  const lines = new Lines(widths)
337
342
  lines.setElement(0, 0, 'Semantic')
343
+ lines.setElement(0, 1, `#${context.context_id || "?"}`)
338
344
  lines.setElement(0, 2, 'No semantic applied')
339
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()
340
349
  lines.setElement(0, 1, 'STACK')
341
350
  lines.setElement(0, 2, stack)
342
351
  lines.newRow()
@@ -345,6 +354,7 @@ class Semantics {
345
354
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
346
355
  this.logs.push(lines.toString())
347
356
  }
357
+ args.calls.pop()
348
358
  return contextPrime
349
359
  }
350
360