theprogrammablemind_4wp 9.1.1 → 9.2.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,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,10 +1182,11 @@ 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,
1189
+ sendObjectsToServer,
1163
1190
 
1164
1191
  module: moduleFromJSFile,
1165
1192
  description,
@@ -1188,8 +1215,34 @@ const knowledgeModuleImpl = async ({
1188
1215
  throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
1189
1216
  }
1190
1217
 
1218
+ const setupConfig = (config) => {
1219
+ if (!config.name) {
1220
+ throw new Error("config must have 'name' set to the knowledge module name.")
1221
+ }
1222
+
1223
+ config.description = description
1224
+ if (typeof testConfig === 'object') {
1225
+ if (testConfig.contents) {
1226
+ config.tests = testConfig.contents
1227
+ test = testConfig.name
1228
+ }
1229
+ } else {
1230
+ if (runtime.fs && runtime.fs.existsSync(test)) {
1231
+ config.tests = JSON.parse(runtime.fs.readFileSync(test))
1232
+ } else {
1233
+ config.tests = []
1234
+ }
1235
+ }
1236
+ config.setTestConfig(testConfig)
1237
+ }
1238
+
1191
1239
  const createConfig = async () => {
1192
- const config = new Config(configStruct, moduleFromJSFile, _process)
1240
+ const config = new Config(configStruct, moduleFromJSFile, _process, apiKMs)
1241
+ if (sendObjectsToServer) {
1242
+ config.setSendObjectsToServer()
1243
+ }
1244
+ setupConfig(config)
1245
+ config.expect_template = !!template
1193
1246
  config.setTerminator(terminator)
1194
1247
  config.stop_auto_rebuild()
1195
1248
  await config.add(...(includes || []))
@@ -1216,27 +1269,6 @@ const knowledgeModuleImpl = async ({
1216
1269
 
1217
1270
  const isProcess = require.main === moduleFromJSFile
1218
1271
 
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
1272
  if (isProcess) {
1241
1273
  let config
1242
1274
  try {
@@ -1298,7 +1330,6 @@ const knowledgeModuleImpl = async ({
1298
1330
  if (args.rebuildTemplateFull) {
1299
1331
  args.rebuildTemplate = true
1300
1332
  }
1301
-
1302
1333
  config = await createConfig()
1303
1334
 
1304
1335
  // 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 +1337,7 @@ const knowledgeModuleImpl = async ({
1306
1337
  global.pauseDebugging = true
1307
1338
  }
1308
1339
 
1309
- setupConfig(config)
1340
+ // setupConfig(config)
1310
1341
  processResults = processResults({ config, errorHandler })
1311
1342
 
1312
1343
  if (args.rebuildTemplate) {
@@ -1542,6 +1573,7 @@ const knowledgeModuleImpl = async ({
1542
1573
  }
1543
1574
  try {
1544
1575
  await config.load(rebuildTemplate, template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1576
+ config.fixtures()
1545
1577
  } catch (e) {
1546
1578
  console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
1547
1579
  runtime.process.exit(-1)
@@ -1841,6 +1873,7 @@ const knowledgeModuleImpl = async ({
1841
1873
  config.terminate()
1842
1874
  }
1843
1875
  }
1876
+ moduleFromJSFile.exports = createConfig
1844
1877
  } else {
1845
1878
  const initConfig = async (config) => {
1846
1879
  if (template) {
@@ -1910,6 +1943,11 @@ const test = (name) => {
1910
1943
  }
1911
1944
  */
1912
1945
 
1946
+ // for testing
1947
+ const getRequireMain = () => {
1948
+ return require.main
1949
+ }
1950
+
1913
1951
  const ensureTestFile = (module, name, type) => {
1914
1952
  const isProcess = require.main === module
1915
1953
  if (isProcess) {
@@ -1931,6 +1969,7 @@ const knowledgeModule = async (...args) => {
1931
1969
  module.exports = {
1932
1970
  process: _process,
1933
1971
  stableId,
1972
+ getRequireMain, // for testing
1934
1973
  ensureTestFile,
1935
1974
  rebuildTemplate,
1936
1975
  processContext,
package/index.js CHANGED
@@ -6,6 +6,7 @@ const Digraph = require('./src/digraph')
6
6
  const client = require('./client')
7
7
  const flattens = require('./src/flatten')
8
8
  const unflatten = require('./src/unflatten')
9
+ const debug = require('./src/debug')
9
10
 
10
11
  module.exports = {
11
12
  process: client.process,
@@ -26,5 +27,6 @@ module.exports = {
26
27
  Digraph,
27
28
  flattens: flattens.flattens,
28
29
  flatten: flattens.flatten,
29
- unflatten: unflatten.unflatten
30
+ unflatten: unflatten.unflatten,
31
+ debug
30
32
  }
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",
72
+ "version": "9.2.0",
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 })
@@ -575,6 +576,10 @@ const addWord = (config, uuid) => ({ word, id, initial }) => {
575
576
 
576
577
  const normalizeConfig = (config) => {
577
578
  if (config) {
579
+ if (!config.objects) {
580
+ config.objects = { namespaced: {}, }
581
+ }
582
+
578
583
  for (const bag of bags) {
579
584
  if (config[bag]) {
580
585
  config[bag] = config[bag].map(normalizeGenerator)
@@ -844,14 +849,6 @@ const multiApiImpl = (initializer) => {
844
849
  }
845
850
  },
846
851
 
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
852
  // "product1": apiInstance(testData1),
856
853
  apis: {
857
854
  },
@@ -869,6 +866,15 @@ class Config {
869
866
  return config_toServer(config)
870
867
  }
871
868
 
869
+ async fixtures () {
870
+ if (this.testConfig?.fixtures) {
871
+ const args = {}
872
+ args.uuid = this._uuid
873
+ configHelpers.setupArgs(args, this)
874
+ return this.testConfig.fixtures(args)
875
+ }
876
+ }
877
+
872
878
  getInfo () {
873
879
  const name = this.name
874
880
  const includes = this.configs.slice(1).map((km) => km.config.name)
@@ -892,7 +898,7 @@ class Config {
892
898
 
893
899
  getPseudoConfig (uuid, config) {
894
900
  return {
895
- description: 'this is a pseudo config that has limited functionality due to being available in the initializer function context',
901
+ description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
896
902
  addAssociation: (...args) => this.addAssociation(...args),
897
903
  addAssociations: (...args) => this.addAssociations(...args),
898
904
  addBridge: (...args) => this.addBridge(...args, uuid),
@@ -960,7 +966,7 @@ class Config {
960
966
  },
961
967
  objects: {
962
968
  // this is where the namespaced configs have their objects
963
- namespaced: {}
969
+ namespaced: {},
964
970
  },
965
971
  description: '',
966
972
  words: {
@@ -1324,6 +1330,11 @@ class Config {
1324
1330
 
1325
1331
  toData (data) {
1326
1332
  Object.assign(data, this.config)
1333
+ // greg99 delete data.objects
1334
+ data.objects = {...this.config.objects}
1335
+ if (!this.sendObjectsToServer) {
1336
+ delete data.objects.namespaced
1337
+ }
1327
1338
  config_toServer(data)
1328
1339
  }
1329
1340
 
@@ -1363,12 +1374,22 @@ class Config {
1363
1374
  this.instances.push(instance)
1364
1375
  await configHelpers.loadInstance(this, instance)
1365
1376
  }
1377
+ this.expect_template = false
1366
1378
  }
1367
1379
  }
1368
1380
 
1381
+ watchNewFragments (list) {
1382
+ this.addFragmentWatcher = list
1383
+ }
1384
+
1369
1385
  addFragments (fragments) {
1370
1386
  // only run this if not loading as module write error if loading as module and different
1371
1387
  this.dynamicFragments = this.dynamicFragments.concat(fragments)
1388
+ if (this.addFragmentWatcher) {
1389
+ for (const fragment of fragments) {
1390
+ this.addFragmentWatcher.push(fragment)
1391
+ }
1392
+ }
1372
1393
  }
1373
1394
 
1374
1395
  objects () {
@@ -1755,7 +1776,7 @@ class Config {
1755
1776
  if (!config.objects) {
1756
1777
  config.objects = {
1757
1778
  namespaced: {
1758
- }
1779
+ },
1759
1780
  }
1760
1781
  }
1761
1782
 
@@ -1839,6 +1860,17 @@ class Config {
1839
1860
  }
1840
1861
  }
1841
1862
 
1863
+ get kms () {
1864
+ const kms = {}
1865
+ kms[this.name] = this
1866
+ for (const config of this.configs) {
1867
+ if (config.config instanceof Config) {
1868
+ kms[config.config.name] = config.config
1869
+ }
1870
+ }
1871
+ return kms
1872
+ }
1873
+
1842
1874
  removeDevelopmentElements (config) {
1843
1875
  if (!config) {
1844
1876
  return
@@ -1897,11 +1929,15 @@ class Config {
1897
1929
  }
1898
1930
 
1899
1931
  // configs = [ { config, namespace } ... ]
1900
- constructor (config, module, clientProcess) {
1932
+ constructor (config, module, clientProcess, apiKMs) {
1901
1933
  if (config instanceof Config) {
1902
1934
  throw new Error('Excepted the config argument to be a hash not a Config object')
1903
1935
  }
1904
1936
 
1937
+ if (!apiKMs) {
1938
+ apiKMs = []
1939
+ }
1940
+
1905
1941
  if (config) {
1906
1942
  validConfigProps(config)
1907
1943
 
@@ -1915,6 +1951,8 @@ class Config {
1915
1951
  config.priorities = config.priorities || []
1916
1952
  }
1917
1953
 
1954
+ this._apiKMs = apiKMs
1955
+
1918
1956
  this.clientProcess = clientProcess
1919
1957
  this.maxDepth = 20 // for generators and semantics
1920
1958
  this.debugLoops = false // for generators and semantics
@@ -1970,6 +2008,7 @@ class Config {
1970
2008
  this.wasInitialized = false
1971
2009
  this.configs = []
1972
2010
  this._api = undefined
2011
+ this.sendObjectsToServer = false
1973
2012
  this._namespace = []
1974
2013
  this._eqClasses = []
1975
2014
  // this._uuid = uuidv4()
@@ -1994,6 +2033,10 @@ class Config {
1994
2033
  debugConfigProps(this.config)
1995
2034
  }
1996
2035
 
2036
+ setSendObjectsToServer() {
2037
+ this.sendObjectsToServer = true
2038
+ }
2039
+
1997
2040
  addArgs (moreArgs) {
1998
2041
  this.addedArgss.push(moreArgs)
1999
2042
  }
@@ -2061,7 +2104,28 @@ class Config {
2061
2104
  this.resetDelta(cacheKey)
2062
2105
  }
2063
2106
 
2107
+ // use this to set the api if you only want to partially override the KM api
2108
+ apiBase (name) {
2109
+ if (this._api && this._api.multiApi) {
2110
+ throw new Error('This is intended to be used to instantiate a new class based on the existing API.')
2111
+ } else {
2112
+ if (name) {
2113
+ if (this.name == name) {
2114
+ return this._api.constructor
2115
+ } else {
2116
+ return this.getConfig(name)._api.constructor
2117
+ }
2118
+ } else {
2119
+ return this._api.constructor
2120
+ }
2121
+ }
2122
+ }
2123
+
2064
2124
  get api () {
2125
+ if (this._stop_auto_rebuild) {
2126
+ throw new Error('The API cannot be accessed until the auto rebuild is restarted')
2127
+ }
2128
+
2065
2129
  if (this._api && this._api.multiApi) {
2066
2130
  return this._api.api(this._api)
2067
2131
  } else {
@@ -2069,6 +2133,10 @@ class Config {
2069
2133
  }
2070
2134
  }
2071
2135
 
2136
+ set api (api) {
2137
+ this._api = api
2138
+ }
2139
+
2072
2140
  async addAPI (api) {
2073
2141
  // console.trace()
2074
2142
  // throw "addAPI"
@@ -2079,13 +2147,26 @@ class Config {
2079
2147
  }
2080
2148
  }
2081
2149
 
2150
+ // constructors is a constructor
2082
2151
  async setApi (constructor) {
2083
2152
  if (typeof constructor !== 'function') {
2084
2153
  throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
2085
2154
  }
2086
2155
  const value = constructor()
2087
- if (!value.initialize) {
2088
- throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2156
+ if (this._apiKMs.length > 0) {
2157
+ for (const name of this._apiKMs) {
2158
+ const api = value[name]
2159
+ if (!api) {
2160
+ throw new Error(`The API for ${this.name} is not being provided by the API constructor.`)
2161
+ }
2162
+ if (!api.initialize) {
2163
+ throw new Error(`Expected the API for ${this.name} to have an initialize function.`)
2164
+ }
2165
+ }
2166
+ } else {
2167
+ if (!value.initialize) {
2168
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2169
+ }
2089
2170
  }
2090
2171
 
2091
2172
  if (this._api && this._api.multiApi) {
@@ -2098,8 +2179,14 @@ class Config {
2098
2179
  return api
2099
2180
  }
2100
2181
  } else {
2101
- this._api = value
2102
2182
  this._apiConstructor = constructor
2183
+ if (this._apiKMs.length > 0) {
2184
+ for (const name of this._apiKMs) {
2185
+ this.km(name)._api = value[name]
2186
+ }
2187
+ } else {
2188
+ this._api = value
2189
+ }
2103
2190
  await this.rebuild()
2104
2191
  }
2105
2192
  }
@@ -2167,10 +2254,21 @@ class Config {
2167
2254
  // update uuid here set the uuid in the objects and add error checking
2168
2255
  cp.initializerFn = this.initializerFn
2169
2256
  cp.terminatorFn = this.terminatorFn
2170
- // cp._api = _.cloneDeep(this._api)
2171
- if (this._apiConstructor) {
2172
- cp._api = this._apiConstructor(cp)
2173
- cp._apiConstructor = this._apiConstructor
2257
+ cp._apiKMs = this._apiKMs
2258
+ cp._apiConstructor = this._apiConstructor
2259
+ if (cp._apiConstructor) {
2260
+ if (this._apiKMs.length > 0) {
2261
+ const apis = cp._apiConstructor(cp)
2262
+ for (const name of this._apiKMs) {
2263
+ if (name == this.name) {
2264
+ cp._api = apis[name]
2265
+ } else {
2266
+ cp.km(name)._api = apis[name]
2267
+ }
2268
+ }
2269
+ } else {
2270
+ cp._api = cp._apiConstructor(cp)
2271
+ }
2174
2272
  }
2175
2273
  cp._namespace = this._namespace
2176
2274
  cp._eqClasses = this._eqClasses
@@ -2185,6 +2283,7 @@ class Config {
2185
2283
  cp.testConfig = this.testConfig
2186
2284
  cp._server = this._server
2187
2285
  cp.hierarchy = new DigraphInternal(this.config.hierarchy)
2286
+ cp.sendObjectsToServer = this.sendObjectsToServer
2188
2287
 
2189
2288
  cp.initConfig = _.cloneDeep(this.initConfig)
2190
2289
  cp.defaultConfig()
@@ -2202,7 +2301,9 @@ class Config {
2202
2301
  await cp.rebuild(options) // in copy
2203
2302
  } else {
2204
2303
  if (!cp.config.objects) {
2205
- cp.config.objects = { namespaced: {} }
2304
+ cp.config.objects = {
2305
+ namespaced: {},
2306
+ }
2206
2307
  } else if (!cp.config.objects.namespaced) {
2207
2308
  cp.config.objects.namespaced = {}
2208
2309
  }
@@ -2550,7 +2651,9 @@ class Config {
2550
2651
  const initAfterApis = []
2551
2652
  this.configs.forEach((km) => {
2552
2653
  const namespace = km.namespace
2553
- this.config.objects.namespaced[km._uuid] = {}
2654
+ this.config.objects.namespaced[km._uuid] = {
2655
+ km: km._uuid
2656
+ }
2554
2657
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
2555
2658
  this.setupNamespace(km)
2556
2659
  // const aw = (word, def) => this.addWord(word, def)
@@ -2588,6 +2691,7 @@ class Config {
2588
2691
  currentConfig: config,
2589
2692
  uuid: config._uuid,
2590
2693
  objects: namespacedObjects,
2694
+ globals: this.config.objects,
2591
2695
  namespace,
2592
2696
  api: config.api
2593
2697
  }))
@@ -2682,6 +2786,13 @@ class Config {
2682
2786
  }
2683
2787
 
2684
2788
  this.hierarchy.edges = this.config.hierarchy
2789
+
2790
+ if (!this.isModule) {
2791
+ if (this.template || !this.expect_template) {
2792
+ await this.fixtures()
2793
+ }
2794
+ }
2795
+
2685
2796
  this.valid()
2686
2797
  this.checks()
2687
2798
  }
@@ -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) {
@@ -126,6 +136,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
126
136
  return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
127
137
  }
128
138
  args.e = (c) => {
139
+ if (!c) {
140
+ return
141
+ }
129
142
  return config.getEvaluator(args.s, args.calls, logs, c)
130
143
  }
131
144
  args.gs = gs(args.g)
@@ -154,6 +167,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
154
167
  config.getAddedArgs(args)
155
168
 
156
169
  Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
170
+ args.apis = args.apis || ((name) => config.getConfig(name).api)
157
171
  /*
158
172
  if (uuidForScoping) {
159
173
  Object.assign(args, args.getUUIDScoped(uuidForScoping))
@@ -241,15 +255,17 @@ const setupContexts = (rawContexts) => {
241
255
  let first = true
242
256
  const contexts = []
243
257
  contexts.push({ marker: 'controlStart', controlRemove: true })
258
+ let previous
244
259
  for (const context of rawContexts) {
245
260
  if (first) {
246
261
  first = false
247
262
  } else {
248
- contexts.push({ marker: 'controlBetween', controlRemove: true })
263
+ contexts.push({ marker: 'controlBetween', controlRemove: true, previous })
249
264
  }
250
265
  contexts.push(context)
266
+ previous = context
251
267
  }
252
- contexts.push({ marker: 'controlEnd', controlRemove: true })
268
+ contexts.push({ marker: 'controlEnd', controlRemove: true, previous })
253
269
 
254
270
  let _index = 0
255
271
  const id = (context) => {
@@ -280,11 +296,14 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
280
296
  args.insert = (context) => toDo.unshift(context)
281
297
  let overlap, lastRange
282
298
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
299
+ let context_id_counter = 0
283
300
  while (toDo.length > 0) {
284
301
  const context = toDo.shift()
285
302
  args.calls.next()
286
303
  let contextPrime = context
287
304
  context.topLevel = true
305
+ context_id_counter += 1
306
+ context.context_id = context_id_counter
288
307
  try {
289
308
  if (json.has_errors) {
290
309
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
@@ -324,9 +343,9 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
324
343
  if (contextPrime.controlRemove) {
325
344
  continue
326
345
  }
327
- let paraphrases = []
328
- let paraphrasesParenthesized = []
329
- let generatedParenthesized = []
346
+ const paraphrases = []
347
+ const paraphrasesParenthesized = []
348
+ const generatedParenthesized = []
330
349
  if (forTemplate) {
331
350
  // noop
332
351
  } 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
  }