theprogrammablemind 9.1.1-beta.2 → 9.1.1-beta.20

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.2",
72
+ "version": "9.1.1-beta.20",
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
@@ -472,7 +473,7 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
472
473
  if (moreConfig.bridges) {
473
474
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
474
475
  bridge = { ...bridge }
475
- const valid = ['after', 'before', 'bridge', 'development', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
476
+ const valid = ['after', 'associations', 'before', 'bridge', 'development', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
476
477
  'level', 'optional', 'selector', 'semantic', 'semantics', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
477
478
  helpers.validProps(valid, bridge, 'bridge')
478
479
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
@@ -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,15 @@ class Config {
869
862
  return config_toServer(config)
870
863
  }
871
864
 
865
+ async fixtures () {
866
+ if (this.testConfig?.fixtures) {
867
+ const args = {}
868
+ args.uuid = this._uuid
869
+ configHelpers.setupArgs(args, this)
870
+ return this.testConfig.fixtures(args)
871
+ }
872
+ }
873
+
872
874
  getInfo () {
873
875
  const name = this.name
874
876
  const includes = this.configs.slice(1).map((km) => km.config.name)
@@ -892,7 +894,7 @@ class Config {
892
894
 
893
895
  getPseudoConfig (uuid, config) {
894
896
  return {
895
- description: 'this is a pseudo config that has limited functionality due to being available in the initializer function context',
897
+ description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
896
898
  addAssociation: (...args) => this.addAssociation(...args),
897
899
  addAssociations: (...args) => this.addAssociations(...args),
898
900
  addBridge: (...args) => this.addBridge(...args, uuid),
@@ -1363,12 +1365,22 @@ class Config {
1363
1365
  this.instances.push(instance)
1364
1366
  await configHelpers.loadInstance(this, instance)
1365
1367
  }
1368
+ this.expect_template = false
1366
1369
  }
1367
1370
  }
1368
1371
 
1372
+ watchNewFragments (list) {
1373
+ this.addFragmentWatcher = list
1374
+ }
1375
+
1369
1376
  addFragments (fragments) {
1370
1377
  // only run this if not loading as module write error if loading as module and different
1371
1378
  this.dynamicFragments = this.dynamicFragments.concat(fragments)
1379
+ if (this.addFragmentWatcher) {
1380
+ for (const fragment of fragments) {
1381
+ this.addFragmentWatcher.push(fragment)
1382
+ }
1383
+ }
1372
1384
  }
1373
1385
 
1374
1386
  objects () {
@@ -1908,11 +1920,15 @@ class Config {
1908
1920
  }
1909
1921
 
1910
1922
  // configs = [ { config, namespace } ... ]
1911
- constructor (config, module, clientProcess) {
1923
+ constructor (config, module, clientProcess, apiKMs) {
1912
1924
  if (config instanceof Config) {
1913
1925
  throw new Error('Excepted the config argument to be a hash not a Config object')
1914
1926
  }
1915
1927
 
1928
+ if (!apiKMs) {
1929
+ apiKMs = []
1930
+ }
1931
+
1916
1932
  if (config) {
1917
1933
  validConfigProps(config)
1918
1934
 
@@ -1926,6 +1942,8 @@ class Config {
1926
1942
  config.priorities = config.priorities || []
1927
1943
  }
1928
1944
 
1945
+ this._apiKMs = apiKMs
1946
+
1929
1947
  this.clientProcess = clientProcess
1930
1948
  this.maxDepth = 20 // for generators and semantics
1931
1949
  this.debugLoops = false // for generators and semantics
@@ -2072,7 +2090,24 @@ class Config {
2072
2090
  this.resetDelta(cacheKey)
2073
2091
  }
2074
2092
 
2093
+ // use this to set the api if you only want to partially override the KM api
2094
+ apiBase (name) {
2095
+ if (this._api && this._api.multiApi) {
2096
+ throw new Error('This is intended to be used to instantiate a new class based on the existing API.')
2097
+ } else {
2098
+ if (name) {
2099
+ return this.getConfig(name)._api
2100
+ } else {
2101
+ return this._api.constructor
2102
+ }
2103
+ }
2104
+ }
2105
+
2075
2106
  get api () {
2107
+ if (this._stop_auto_rebuild) {
2108
+ throw new Error('The API cannot be accessed until the auto rebuild is restarted')
2109
+ }
2110
+
2076
2111
  if (this._api && this._api.multiApi) {
2077
2112
  return this._api.api(this._api)
2078
2113
  } else {
@@ -2094,13 +2129,26 @@ class Config {
2094
2129
  }
2095
2130
  }
2096
2131
 
2132
+ // constructors is a constructor
2097
2133
  async setApi (constructor) {
2098
2134
  if (typeof constructor !== 'function') {
2099
2135
  throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
2100
2136
  }
2101
2137
  const value = constructor()
2102
- if (!value.initialize) {
2103
- throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2138
+ if (this._apiKMs.length > 0) {
2139
+ for (const name of this._apiKMs) {
2140
+ const api = value[name]
2141
+ if (!api) {
2142
+ throw new Error(`The API for ${this.name} is not being provided by the API constructor.`)
2143
+ }
2144
+ if (!api.initialize) {
2145
+ throw new Error(`Expected the API for ${this.name} to have an initialize function.`)
2146
+ }
2147
+ }
2148
+ } else {
2149
+ if (!value.initialize) {
2150
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2151
+ }
2104
2152
  }
2105
2153
 
2106
2154
  if (this._api && this._api.multiApi) {
@@ -2113,8 +2161,14 @@ class Config {
2113
2161
  return api
2114
2162
  }
2115
2163
  } else {
2116
- this._api = value
2117
2164
  this._apiConstructor = constructor
2165
+ if (this._apiKMs.length > 0) {
2166
+ for (const name of this._apiKMs) {
2167
+ this.km(name)._api = value[name]
2168
+ }
2169
+ } else {
2170
+ this._api = value
2171
+ }
2118
2172
  await this.rebuild()
2119
2173
  }
2120
2174
  }
@@ -2182,10 +2236,21 @@ class Config {
2182
2236
  // update uuid here set the uuid in the objects and add error checking
2183
2237
  cp.initializerFn = this.initializerFn
2184
2238
  cp.terminatorFn = this.terminatorFn
2185
- // cp._api = _.cloneDeep(this._api)
2186
- if (this._apiConstructor) {
2187
- cp._api = this._apiConstructor(cp)
2188
- cp._apiConstructor = this._apiConstructor
2239
+ cp._apiKMs = this._apiKMs
2240
+ cp._apiConstructor = this._apiConstructor
2241
+ if (cp._apiConstructor) {
2242
+ if (this._apiKMs.length > 0) {
2243
+ const apis = cp._apiConstructor(cp)
2244
+ for (const name of this._apiKMs) {
2245
+ if (name == this.name) {
2246
+ cp._api = apis[name]
2247
+ } else {
2248
+ cp.km(name)._api = apis[name]
2249
+ }
2250
+ }
2251
+ } else {
2252
+ cp._api = cp._apiConstructor(cp)
2253
+ }
2189
2254
  }
2190
2255
  cp._namespace = this._namespace
2191
2256
  cp._eqClasses = this._eqClasses
@@ -2565,7 +2630,9 @@ class Config {
2565
2630
  const initAfterApis = []
2566
2631
  this.configs.forEach((km) => {
2567
2632
  const namespace = km.namespace
2568
- this.config.objects.namespaced[km._uuid] = {}
2633
+ this.config.objects.namespaced[km._uuid] = {
2634
+ km: km._uuid
2635
+ }
2569
2636
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
2570
2637
  this.setupNamespace(km)
2571
2638
  // const aw = (word, def) => this.addWord(word, def)
@@ -2603,6 +2670,7 @@ class Config {
2603
2670
  currentConfig: config,
2604
2671
  uuid: config._uuid,
2605
2672
  objects: namespacedObjects,
2673
+ globals: this.config.objects,
2606
2674
  namespace,
2607
2675
  api: config.api
2608
2676
  }))
@@ -2697,6 +2765,13 @@ class Config {
2697
2765
  }
2698
2766
 
2699
2767
  this.hierarchy.edges = this.config.hierarchy
2768
+
2769
+ if (!this.isModule) {
2770
+ if (this.template || !this.expect_template) {
2771
+ await this.fixtures()
2772
+ }
2773
+ }
2774
+
2700
2775
  this.valid()
2701
2776
  this.checks()
2702
2777
  }
@@ -81,6 +81,16 @@ 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 (args.uuid) {
89
+ args.objects = args.getObjects(args.uuid)
90
+ }
91
+ if (!hierarchy) {
92
+ hierarchy = config.hierarchy
93
+ }
84
94
  // callId
85
95
  args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
86
96
  if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
@@ -154,6 +164,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
154
164
  config.getAddedArgs(args)
155
165
 
156
166
  Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
167
+ args.apis = args.apis || ((name) => config.getConfig(name).api)
157
168
  /*
158
169
  if (uuidForScoping) {
159
170
  Object.assign(args, args.getUUIDScoped(uuidForScoping))
@@ -241,15 +252,17 @@ const setupContexts = (rawContexts) => {
241
252
  let first = true
242
253
  const contexts = []
243
254
  contexts.push({ marker: 'controlStart', controlRemove: true })
255
+ let previous
244
256
  for (const context of rawContexts) {
245
257
  if (first) {
246
258
  first = false
247
259
  } else {
248
- contexts.push({ marker: 'controlBetween', controlRemove: true })
260
+ contexts.push({ marker: 'controlBetween', controlRemove: true, previous })
249
261
  }
250
262
  contexts.push(context)
263
+ previous = context
251
264
  }
252
- contexts.push({ marker: 'controlEnd', controlRemove: true })
265
+ contexts.push({ marker: 'controlEnd', controlRemove: true, previous })
253
266
 
254
267
  let _index = 0
255
268
  const id = (context) => {
@@ -280,11 +293,14 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
280
293
  args.insert = (context) => toDo.unshift(context)
281
294
  let overlap, lastRange
282
295
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
296
+ let context_id_counter = 0
283
297
  while (toDo.length > 0) {
284
298
  const context = toDo.shift()
285
299
  args.calls.next()
286
300
  let contextPrime = context
287
301
  context.topLevel = true
302
+ context_id_counter += 1
303
+ context.context_id = context_id_counter
288
304
  try {
289
305
  if (json.has_errors) {
290
306
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
@@ -324,9 +340,9 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
324
340
  if (contextPrime.controlRemove) {
325
341
  continue
326
342
  }
327
- let paraphrases = []
328
- let paraphrasesParenthesized = []
329
- let generatedParenthesized = []
343
+ const paraphrases = []
344
+ const paraphrasesParenthesized = []
345
+ const generatedParenthesized = []
330
346
  if (forTemplate) {
331
347
  // noop
332
348
  } else {
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
  }