theprogrammablemind_4wp 9.1.1-beta.0 → 9.1.1-beta.10

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,9 +12,10 @@ 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 { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries } = require('./src/helpers')
15
+ const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps } = require('./src/helpers')
16
16
  const runtime = require('./runtime')
17
17
  const sortJson = runtime.sortJson
18
+ const debug = require('./src/debug')
18
19
 
19
20
  const getConfig_getObjectsCheck = (config, testConfig) => {
20
21
  let testConfigName = config.name
@@ -477,6 +478,11 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
477
478
 
478
479
  const objects = getObjects(config.config.objects)(config.uuid)
479
480
  try {
481
+ if (testConfig.initializer) {
482
+ const args = {}
483
+ setupArgs(args, config)
484
+ await testConfig.initializer(args)
485
+ }
480
486
  const result = await _process(config, test, { errorHandler, isTest: true })
481
487
  result.query = test
482
488
  if (debug) {
@@ -820,7 +826,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
820
826
  }
821
827
  console.log(responses.trace)
822
828
 
823
- if (false) {
829
+ if (true) {
824
830
  if (global.beforeObjects) {
825
831
  console.log('objects', runtime.jsonDiff.diffString(global.beforeObjects, config.get('objects')))
826
832
  } else {
@@ -931,6 +937,19 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
931
937
  learned_contextual_priorities: []
932
938
  }
933
939
  config.fragmentsBeingBuilt = []
940
+
941
+ const toProperties = (queryStringOrProperties) => {
942
+ if (typeof queryStringOrProperties === 'string') {
943
+ return { query: queryStringOrProperties }
944
+ } else {
945
+ return queryStringOrProperties
946
+ }
947
+ }
948
+ const fragmentToTodo = (query, index) => {
949
+ const pr = instance.fragments[index]
950
+ return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
951
+ }
952
+
934
953
  const looper = async (configs) => {
935
954
  if (configs.length === 0) {
936
955
  finish()
@@ -1024,7 +1043,17 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1024
1043
  const objects = config.get('objects')
1025
1044
  const args = { objects, getObjects: getObjects(objects) }
1026
1045
  setupArgs(args, config, config.logs, config.hierarchy)
1046
+ // this watch stuff was for allowing fragment to be made in the template load. that is not a good idea
1047
+ // because needs rebuild would need to run the rebuild to know if a rebuild was needed. the fragment creates
1048
+ // need to go in the intializer
1049
+ // const new_fragments = []
1050
+ // config.watchNewFragments(new_fragments)
1027
1051
  await initFunction(args)
1052
+ /*
1053
+ if (new_fragments.length > 0) {
1054
+ configs = configs.concat(new_fragments.map(fragmentToTodo))
1055
+ }
1056
+ */
1028
1057
  accumulators[property].push({ apply: queryOrExtraConfig })
1029
1058
  await looper(configs)
1030
1059
  } else {
@@ -1093,13 +1122,6 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1093
1122
  }
1094
1123
  }
1095
1124
 
1096
- const toProperties = (queryStringOrProperties) => {
1097
- if (typeof queryStringOrProperties === 'string') {
1098
- return { query: queryStringOrProperties }
1099
- } else {
1100
- return queryStringOrProperties
1101
- }
1102
- }
1103
1125
  let todo = []
1104
1126
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1105
1127
  /*
@@ -1115,14 +1137,17 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1115
1137
  for (let configsIndex = 0; configsIndex < template.configs.length; ++configsIndex) {
1116
1138
  const query = template.configs[configsIndex]
1117
1139
  // account for things for example associations being added to the config while debugginer
1118
- const pr = previousResultss.find((pr) => pr.query == query)
1140
+ const pr = previousResultss && previousResultss.find((pr) => pr.query == query)
1119
1141
  todo.push({ property: 'resultss', query, previousResults: pr, skipSemantics: false || query.skipSemantics })
1120
1142
  }
1121
1143
  }
1144
+ todo = todo.concat((template.fragments || []).map(fragmentToTodo))
1145
+ /*
1122
1146
  todo = todo.concat((template.fragments || []).map((query, index) => {
1123
1147
  const pr = instance.fragments[index]
1124
1148
  return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
1125
1149
  }))
1150
+ */
1126
1151
  todo = todo.concat((template.semantics || []).map((definition) => {
1127
1152
  return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true }
1128
1153
  }))
@@ -1136,6 +1161,7 @@ const checkTemplate = (template) => {
1136
1161
  if (template.checks) {
1137
1162
  throw new Error("The 'checks' property should be in the 'test' property not the 'template' property")
1138
1163
  }
1164
+ validProps([ 'fragments', 'configs' ], template.template, 'template.template')
1139
1165
  }
1140
1166
 
1141
1167
  const checkTest = (testConfig) => {
@@ -1156,7 +1182,7 @@ const checkTest = (testConfig) => {
1156
1182
  const knowledgeModuleImpl = async ({
1157
1183
  includes,
1158
1184
  config: configStruct,
1159
- api,
1185
+ api, apiKMs,
1160
1186
  initializer,
1161
1187
  terminator,
1162
1188
  multiApiInitializer,
@@ -1188,8 +1214,31 @@ const knowledgeModuleImpl = async ({
1188
1214
  throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
1189
1215
  }
1190
1216
 
1217
+ const setupConfig = (config) => {
1218
+ if (!config.name) {
1219
+ throw new Error("config must have 'name' set to the knowledge module name.")
1220
+ }
1221
+
1222
+ config.description = description
1223
+ if (typeof testConfig === 'object') {
1224
+ if (testConfig.contents) {
1225
+ config.tests = testConfig.contents
1226
+ test = testConfig.name
1227
+ }
1228
+ } else {
1229
+ if (runtime.fs && runtime.fs.existsSync(test)) {
1230
+ config.tests = JSON.parse(runtime.fs.readFileSync(test))
1231
+ } else {
1232
+ config.tests = []
1233
+ }
1234
+ }
1235
+ config.setTestConfig(testConfig)
1236
+ }
1237
+
1191
1238
  const createConfig = async () => {
1192
- const config = new Config(configStruct, moduleFromJSFile, _process)
1239
+ const config = new Config(configStruct, moduleFromJSFile, _process, apiKMs)
1240
+ setupConfig(config)
1241
+ config.expect_template = !!template
1193
1242
  config.setTerminator(terminator)
1194
1243
  config.stop_auto_rebuild()
1195
1244
  await config.add(...(includes || []))
@@ -1216,27 +1265,6 @@ const knowledgeModuleImpl = async ({
1216
1265
 
1217
1266
  const isProcess = require.main === moduleFromJSFile
1218
1267
 
1219
- const setupConfig = (config) => {
1220
- if (!config.name) {
1221
- throw new Error("config must have 'name' set to the knowledge module name.")
1222
- }
1223
-
1224
- config.description = description
1225
- if (typeof testConfig === 'object') {
1226
- if (testConfig.contents) {
1227
- config.tests = testConfig.contents
1228
- test = testConfig.name
1229
- }
1230
- } else {
1231
- if (runtime.fs && runtime.fs.existsSync(test)) {
1232
- config.tests = JSON.parse(runtime.fs.readFileSync(test))
1233
- } else {
1234
- config.tests = []
1235
- }
1236
- }
1237
- config.setTestConfig(testConfig)
1238
- }
1239
-
1240
1268
  if (isProcess) {
1241
1269
  let config
1242
1270
  try {
@@ -1298,7 +1326,6 @@ const knowledgeModuleImpl = async ({
1298
1326
  if (args.rebuildTemplateFull) {
1299
1327
  args.rebuildTemplate = true
1300
1328
  }
1301
-
1302
1329
  config = await createConfig()
1303
1330
 
1304
1331
  // dont debug the load of the KM's if rebuild template is on since we want to debug the template rebuild not the load
@@ -1306,7 +1333,7 @@ const knowledgeModuleImpl = async ({
1306
1333
  global.pauseDebugging = true
1307
1334
  }
1308
1335
 
1309
- setupConfig(config)
1336
+ // setupConfig(config)
1310
1337
  processResults = processResults({ config, errorHandler })
1311
1338
 
1312
1339
  if (args.rebuildTemplate) {
@@ -1542,6 +1569,7 @@ const knowledgeModuleImpl = async ({
1542
1569
  }
1543
1570
  try {
1544
1571
  await config.load(rebuildTemplate, template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1572
+ config.fixtures()
1545
1573
  } catch (e) {
1546
1574
  console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
1547
1575
  runtime.process.exit(-1)
@@ -1841,6 +1869,7 @@ const knowledgeModuleImpl = async ({
1841
1869
  config.terminate()
1842
1870
  }
1843
1871
  }
1872
+ moduleFromJSFile.exports = createConfig
1844
1873
  } else {
1845
1874
  const initConfig = async (config) => {
1846
1875
  if (template) {
@@ -1910,6 +1939,11 @@ const test = (name) => {
1910
1939
  }
1911
1940
  */
1912
1941
 
1942
+ // for testing
1943
+ const getRequireMain = () => {
1944
+ return require.main
1945
+ }
1946
+
1913
1947
  const ensureTestFile = (module, name, type) => {
1914
1948
  const isProcess = require.main === module
1915
1949
  if (isProcess) {
@@ -1931,6 +1965,7 @@ const knowledgeModule = async (...args) => {
1931
1965
  module.exports = {
1932
1966
  process: _process,
1933
1967
  stableId,
1968
+ getRequireMain, // for testing
1934
1969
  ensureTestFile,
1935
1970
  rebuildTemplate,
1936
1971
  processContext,
package/package.json CHANGED
@@ -9,7 +9,8 @@
9
9
  "eslint-plugin-node": "^11.1.0",
10
10
  "eslint-plugin-promise": "^5.1.0",
11
11
  "globals": "^16.0.0",
12
- "jest": "^29.7.0"
12
+ "jest": "^29.7.0",
13
+ "argparse": "^2.0.1"
13
14
  },
14
15
  "scripts": {
15
16
  "to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
@@ -47,6 +48,7 @@
47
48
  "src/config.js",
48
49
  "src/configHelpers.js",
49
50
  "src/copy.js",
51
+ "src/debug.js",
50
52
  "src/digraph.js",
51
53
  "src/digraph_internal.js",
52
54
  "src/generators.js",
@@ -67,6 +69,6 @@
67
69
  "sort-json": "^2.0.0",
68
70
  "uuid": "^8.3.2"
69
71
  },
70
- "version": "9.1.1-beta.0",
72
+ "version": "9.1.1-beta.10",
71
73
  "license": "UNLICENSED"
72
74
  }
package/src/config.js CHANGED
@@ -9,6 +9,7 @@ const { InitCalls } = require('./helpers')
9
9
  const { ecatch } = require('./helpers')
10
10
  const runtime = require('../runtime')
11
11
  const _ = require('lodash')
12
+ const db = require('./debug')
12
13
 
13
14
  const debugBreak = () => {
14
15
  // debugger
@@ -844,14 +845,6 @@ const multiApiImpl = (initializer) => {
844
845
  }
845
846
  },
846
847
 
847
- /*
848
- set objects (value) {
849
- for (const key in Object.keys(this.apis)) {
850
- this.apis[key].objects = value
851
- }
852
- },
853
- */
854
-
855
848
  // "product1": apiInstance(testData1),
856
849
  apis: {
857
850
  },
@@ -869,6 +862,14 @@ class Config {
869
862
  return config_toServer(config)
870
863
  }
871
864
 
865
+ async fixtures () {
866
+ if (this.testConfig?.fixtures) {
867
+ const args = {}
868
+ configHelpers.setupArgs(args, this)
869
+ return this.testConfig.fixtures(args)
870
+ }
871
+ }
872
+
872
873
  getInfo () {
873
874
  const name = this.name
874
875
  const includes = this.configs.slice(1).map((km) => km.config.name)
@@ -1363,12 +1364,22 @@ class Config {
1363
1364
  this.instances.push(instance)
1364
1365
  await configHelpers.loadInstance(this, instance)
1365
1366
  }
1367
+ this.expect_template = false
1366
1368
  }
1367
1369
  }
1368
1370
 
1371
+ watchNewFragments (list) {
1372
+ this.addFragmentWatcher = list
1373
+ }
1374
+
1369
1375
  addFragments (fragments) {
1370
1376
  // only run this if not loading as module write error if loading as module and different
1371
1377
  this.dynamicFragments = this.dynamicFragments.concat(fragments)
1378
+ if (this.addFragmentWatcher) {
1379
+ for (const fragment of fragments) {
1380
+ this.addFragmentWatcher.push(fragment)
1381
+ }
1382
+ }
1372
1383
  }
1373
1384
 
1374
1385
  objects () {
@@ -1839,6 +1850,17 @@ class Config {
1839
1850
  }
1840
1851
  }
1841
1852
 
1853
+ get kms () {
1854
+ const kms = {}
1855
+ kms[this.name] = this
1856
+ for (const config of this.configs) {
1857
+ if (config.config instanceof Config) {
1858
+ kms[config.config.name] = config.config
1859
+ }
1860
+ }
1861
+ return kms
1862
+ }
1863
+
1842
1864
  removeDevelopmentElements (config) {
1843
1865
  if (!config) {
1844
1866
  return
@@ -1897,11 +1919,15 @@ class Config {
1897
1919
  }
1898
1920
 
1899
1921
  // configs = [ { config, namespace } ... ]
1900
- constructor (config, module, clientProcess) {
1922
+ constructor (config, module, clientProcess, apiKMs) {
1901
1923
  if (config instanceof Config) {
1902
1924
  throw new Error('Excepted the config argument to be a hash not a Config object')
1903
1925
  }
1904
1926
 
1927
+ if (!apiKMs) {
1928
+ apiKMs = []
1929
+ }
1930
+
1905
1931
  if (config) {
1906
1932
  validConfigProps(config)
1907
1933
 
@@ -1915,6 +1941,8 @@ class Config {
1915
1941
  config.priorities = config.priorities || []
1916
1942
  }
1917
1943
 
1944
+ this._apiKMs = apiKMs
1945
+
1918
1946
  this.clientProcess = clientProcess
1919
1947
  this.maxDepth = 20 // for generators and semantics
1920
1948
  this.debugLoops = false // for generators and semantics
@@ -1923,7 +1951,7 @@ class Config {
1923
1951
  this.resetDelta()
1924
1952
 
1925
1953
  this.addedArgss = []
1926
- let isProcess = require.main === module
1954
+ const isProcess = require.main === module
1927
1955
  if (global.theprogrammablemind && config) {
1928
1956
  if (global.theprogrammablemind.loadForTesting[config.name]) {
1929
1957
  isProcess = true
@@ -2069,6 +2097,10 @@ class Config {
2069
2097
  }
2070
2098
  }
2071
2099
 
2100
+ set api (api) {
2101
+ this._api = api
2102
+ }
2103
+
2072
2104
  async addAPI (api) {
2073
2105
  // console.trace()
2074
2106
  // throw "addAPI"
@@ -2079,6 +2111,7 @@ class Config {
2079
2111
  }
2080
2112
  }
2081
2113
 
2114
+ // constructors is a constructor
2082
2115
  async setApi (constructor) {
2083
2116
  if (typeof constructor !== 'function') {
2084
2117
  throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
@@ -2100,6 +2133,12 @@ class Config {
2100
2133
  } else {
2101
2134
  this._api = value
2102
2135
  this._apiConstructor = constructor
2136
+ for (const name of this._apiKMs) {
2137
+ if (this.name == name) {
2138
+ continue
2139
+ }
2140
+ this.km(name).setApi(() => this._api)
2141
+ }
2103
2142
  await this.rebuild()
2104
2143
  }
2105
2144
  }
@@ -2167,10 +2206,10 @@ class Config {
2167
2206
  // update uuid here set the uuid in the objects and add error checking
2168
2207
  cp.initializerFn = this.initializerFn
2169
2208
  cp.terminatorFn = this.terminatorFn
2170
- // cp._api = _.cloneDeep(this._api)
2171
2209
  if (this._apiConstructor) {
2172
2210
  cp._api = this._apiConstructor(cp)
2173
2211
  cp._apiConstructor = this._apiConstructor
2212
+ cp._apiKMs = this._apiKMs
2174
2213
  }
2175
2214
  cp._namespace = this._namespace
2176
2215
  cp._eqClasses = this._eqClasses
@@ -2588,6 +2627,7 @@ class Config {
2588
2627
  currentConfig: config,
2589
2628
  uuid: config._uuid,
2590
2629
  objects: namespacedObjects,
2630
+ globals: this.config.objects,
2591
2631
  namespace,
2592
2632
  api: config.api
2593
2633
  }))
@@ -2682,6 +2722,13 @@ class Config {
2682
2722
  }
2683
2723
 
2684
2724
  this.hierarchy.edges = this.config.hierarchy
2725
+
2726
+ if (!this.isModule) {
2727
+ if (this.template || !this.expect_template) {
2728
+ await this.fixtures()
2729
+ }
2730
+ }
2731
+
2685
2732
  this.valid()
2686
2733
  this.checks()
2687
2734
  }
@@ -81,6 +81,13 @@ const cleanAssign = (dest, ...srcs) => {
81
81
  }
82
82
 
83
83
  const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
84
+ if (!args.objects) {
85
+ args.objects = config.get('objects')
86
+ args.getObjects = getObjects(args.objects)
87
+ }
88
+ if (!hierarchy) {
89
+ hierarchy = config.hierarchy
90
+ }
84
91
  // callId
85
92
  args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
86
93
  if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
@@ -154,6 +161,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
154
161
  config.getAddedArgs(args)
155
162
 
156
163
  Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
164
+ args.apis = args.apis || ((name) => config.getConfig(name).api)
157
165
  /*
158
166
  if (uuidForScoping) {
159
167
  Object.assign(args, args.getUUIDScoped(uuidForScoping))
@@ -241,15 +249,17 @@ const setupContexts = (rawContexts) => {
241
249
  let first = true
242
250
  const contexts = []
243
251
  contexts.push({ marker: 'controlStart', controlRemove: true })
252
+ let previous;
244
253
  for (const context of rawContexts) {
245
254
  if (first) {
246
255
  first = false
247
256
  } else {
248
- contexts.push({ marker: 'controlBetween', controlRemove: true })
257
+ contexts.push({ marker: 'controlBetween', controlRemove: true, previous })
249
258
  }
250
259
  contexts.push(context)
260
+ previous = context
251
261
  }
252
- contexts.push({ marker: 'controlEnd', controlRemove: true })
262
+ contexts.push({ marker: 'controlEnd', controlRemove: true, previous })
253
263
 
254
264
  let _index = 0
255
265
  const id = (context) => {
@@ -280,11 +290,14 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
280
290
  args.insert = (context) => toDo.unshift(context)
281
291
  let overlap, lastRange
282
292
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
293
+ let context_id_counter = 0
283
294
  while (toDo.length > 0) {
284
295
  const context = toDo.shift()
285
296
  args.calls.next()
286
297
  let contextPrime = context
287
298
  context.topLevel = true
299
+ context_id_counter += 1
300
+ context.context_id = context_id_counter
288
301
  try {
289
302
  if (json.has_errors) {
290
303
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
package/src/debug.js ADDED
@@ -0,0 +1,78 @@
1
+ const counters = {}
2
+ const hits = {}
3
+
4
+ let db = () => {
5
+ debugger // eslint-disable-line no-debugger
6
+ }
7
+
8
+ const reset = () => {
9
+ Object.keys(counters).forEach(key => delete counters[key])
10
+ Object.keys(hits).forEach(key => delete hits[key])
11
+ db = () => { debugger } // eslint-disable-line no-debugger
12
+ }
13
+
14
+ const getDb = () => {
15
+ return db
16
+ }
17
+
18
+ const setDb = (value) => {
19
+ db = value
20
+ }
21
+
22
+ const hit = (name) => {
23
+ hits[name] = true
24
+ }
25
+
26
+ const unhit = (name) => {
27
+ hits[name] = false
28
+ }
29
+
30
+ const wasHit = (name) => {
31
+ return hits[name]
32
+ }
33
+
34
+ const counter = (name, breakAt = [], debugBreak = true) => {
35
+ if (!counters[name]) {
36
+ counters[name] = 0
37
+ }
38
+ counters[name] += 1
39
+ console.log(`counters[${name}] = ${counters[name]}`)
40
+ unhit(name)
41
+ if (Array.isArray(breakAt) && breakAt.includes(counters[name])) {
42
+ if (debugBreak) {
43
+ db()
44
+ }
45
+ hit(name)
46
+ return true
47
+ } else if (breakAt == counters[name]) {
48
+ if (debugBreak) {
49
+ db()
50
+ }
51
+ hit(name)
52
+ return true
53
+ }
54
+ }
55
+
56
+ const get = (name) => {
57
+ return counters[name]
58
+ }
59
+
60
+ const _break = (name) => {
61
+ if (wasHit(name)) {
62
+ db()
63
+ }
64
+ }
65
+
66
+ module.exports = {
67
+ counter,
68
+ get,
69
+ _break, // break is a keyword
70
+
71
+ // used for tests
72
+ reset,
73
+ hit,
74
+ unhit,
75
+ wasHit,
76
+ getDb,
77
+ setDb
78
+ }
package/src/generators.js CHANGED
@@ -211,7 +211,7 @@ class Generators {
211
211
  lines.setElement(0, 2, generator.toString())
212
212
  lines.newRow()
213
213
  lines.setElement(0, 1, 'TO')
214
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
214
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
215
215
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
216
216
  lines.newRow()
217
217
  lines.setElement(0, 1, 'STACK')
@@ -253,7 +253,7 @@ class Generators {
253
253
  lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
254
254
  lines.newRow()
255
255
  lines.setElement(0, 1, 'TO')
256
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
256
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
257
257
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
258
  this.logs.push(lines.toString())
259
259
  }
package/src/helpers.js CHANGED
@@ -310,7 +310,7 @@ const validProps = (valids, object, type) => {
310
310
  }
311
311
  }
312
312
  if (!okay) {
313
- throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`)
313
+ throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids.join(', ')}. The ${type} is ${JSON.stringify(object)}`)
314
314
  }
315
315
  }
316
316
  }
package/src/semantics.js CHANGED
@@ -183,7 +183,16 @@ class Semantics {
183
183
  deferWasCalled = true
184
184
  }
185
185
  args.defer = defer
186
+
187
+ let continueWasCalled = false
188
+ const _continue = () => {
189
+ continueWasCalled = true
190
+ }
191
+ args._continue = _continue
186
192
  contextPrime = await semantic.apply(args, context, s, options)
193
+ if (continueWasCalled) {
194
+ continue
195
+ }
187
196
  if (deferWasCalled) {
188
197
  continue
189
198
  }
@@ -218,7 +227,7 @@ class Semantics {
218
227
  lines.setElement(0, 2, semantic.toString())
219
228
  lines.newRow()
220
229
  lines.setElement(0, 1, 'TO')
221
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
230
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
222
231
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
223
232
  lines.newRow()
224
233
  lines.setElement(0, 1, 'STACK')
@@ -253,7 +262,7 @@ class Semantics {
253
262
  lines.setElement(0, 2, semantic.toString())
254
263
  lines.newRow()
255
264
  lines.setElement(0, 1, 'TO')
256
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
265
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
257
266
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
267
  lines.newRow()
259
268
  lines.setElement(0, 1, 'STACK')
@@ -263,7 +272,7 @@ class Semantics {
263
272
  lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
264
273
  lines.newRow()
265
274
  lines.setElement(0, 1, 'RESULT')
266
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(contextPrime, { depth: 25 })))})`)
275
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
267
276
  lines.setElement(1, 2, JSON.stringify(contextPrime, null, 2))
268
277
  for (const { semantic } of deferred) {
269
278
  lines.setElement(0, 1, 'DEFERRED')
@@ -295,7 +304,7 @@ class Semantics {
295
304
  lines.setElement(0, 2, stack)
296
305
  lines.newRow()
297
306
  lines.setElement(0, 1, 'TO')
298
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
307
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
299
308
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
300
309
  this.logs.push(lines.toString())
301
310
  }