@harperfast/harper-pro 5.0.6 → 5.0.7

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.
Files changed (104) hide show
  1. package/core/bin/status.js +2 -2
  2. package/core/bin/stop.js +6 -5
  3. package/core/components/EntryHandler.ts +2 -4
  4. package/core/components/Scope.ts +1 -1
  5. package/core/components/componentLoader.ts +4 -11
  6. package/core/components/requestRestart.ts +2 -17
  7. package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
  8. package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
  9. package/core/package-lock.json +63 -971
  10. package/core/resources/DatabaseTransaction.ts +3 -8
  11. package/core/resources/Table.ts +17 -12
  12. package/core/resources/databases.ts +2 -2
  13. package/core/resources/graphql.ts +165 -163
  14. package/core/resources/indexes/HierarchicalNavigableSmallWorld.ts +3 -14
  15. package/core/resources/indexes/vector.ts +0 -17
  16. package/core/resources/loadEnv.ts +16 -20
  17. package/core/resources/login.ts +3 -4
  18. package/core/resources/roles.ts +65 -60
  19. package/core/security/auth.ts +14 -15
  20. package/core/security/jsLoader.ts +2 -14
  21. package/core/server/REST.ts +11 -10
  22. package/core/server/fastifyRoutes.ts +29 -30
  23. package/core/server/graphqlQuerying.ts +3 -4
  24. package/core/server/http.ts +1 -175
  25. package/core/server/mqtt.ts +2 -8
  26. package/core/server/serverHelpers/serverUtilities.ts +5 -2
  27. package/core/server/threads/threadServer.js +2 -30
  28. package/core/server/throttle.ts +0 -18
  29. package/core/utility/environment/environmentManager.js +4 -10
  30. package/core/utility/environment/systemInformation.js +355 -0
  31. package/core/utility/hdbTerms.ts +0 -1
  32. package/core/utility/operation_authorization.js +5 -2
  33. package/dist/core/bin/status.js +2 -2
  34. package/dist/core/bin/status.js.map +1 -1
  35. package/dist/core/bin/stop.js +5 -5
  36. package/dist/core/bin/stop.js.map +1 -1
  37. package/dist/core/components/EntryHandler.js +2 -4
  38. package/dist/core/components/EntryHandler.js.map +1 -1
  39. package/dist/core/components/Scope.js +1 -1
  40. package/dist/core/components/Scope.js.map +1 -1
  41. package/dist/core/components/componentLoader.js +3 -11
  42. package/dist/core/components/componentLoader.js.map +1 -1
  43. package/dist/core/components/requestRestart.js +1 -12
  44. package/dist/core/components/requestRestart.js.map +1 -1
  45. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +24 -0
  46. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js.map +1 -0
  47. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +19 -18
  48. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js.map +1 -1
  49. package/dist/core/resources/DatabaseTransaction.js +1 -6
  50. package/dist/core/resources/DatabaseTransaction.js.map +1 -1
  51. package/dist/core/resources/Table.js +18 -14
  52. package/dist/core/resources/Table.js.map +1 -1
  53. package/dist/core/resources/databases.js +1 -2
  54. package/dist/core/resources/databases.js.map +1 -1
  55. package/dist/core/resources/graphql.js +176 -176
  56. package/dist/core/resources/graphql.js.map +1 -1
  57. package/dist/core/resources/indexes/HierarchicalNavigableSmallWorld.js +2 -14
  58. package/dist/core/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  59. package/dist/core/resources/indexes/vector.js +0 -14
  60. package/dist/core/resources/indexes/vector.js.map +1 -1
  61. package/dist/core/resources/loadEnv.js +17 -20
  62. package/dist/core/resources/loadEnv.js.map +1 -1
  63. package/dist/core/resources/login.js +4 -4
  64. package/dist/core/resources/login.js.map +1 -1
  65. package/dist/core/resources/roles.js +68 -64
  66. package/dist/core/resources/roles.js.map +1 -1
  67. package/dist/core/security/auth.js +15 -17
  68. package/dist/core/security/auth.js.map +1 -1
  69. package/dist/core/security/jsLoader.js +2 -16
  70. package/dist/core/security/jsLoader.js.map +1 -1
  71. package/dist/core/server/REST.js +11 -11
  72. package/dist/core/server/REST.js.map +1 -1
  73. package/dist/core/server/fastifyRoutes.js +29 -30
  74. package/dist/core/server/fastifyRoutes.js.map +1 -1
  75. package/dist/core/server/graphqlQuerying.js +4 -5
  76. package/dist/core/server/graphqlQuerying.js.map +1 -1
  77. package/dist/core/server/http.js +0 -179
  78. package/dist/core/server/http.js.map +1 -1
  79. package/dist/core/server/mqtt.js +3 -5
  80. package/dist/core/server/mqtt.js.map +1 -1
  81. package/dist/core/server/serverHelpers/serverUtilities.js +2 -2
  82. package/dist/core/server/serverHelpers/serverUtilities.js.map +1 -1
  83. package/dist/core/server/threads/threadServer.js +2 -26
  84. package/dist/core/server/threads/threadServer.js.map +1 -1
  85. package/dist/core/server/throttle.js +0 -17
  86. package/dist/core/server/throttle.js.map +1 -1
  87. package/dist/core/utility/environment/environmentManager.js +4 -9
  88. package/dist/core/utility/environment/environmentManager.js.map +1 -1
  89. package/dist/core/utility/environment/systemInformation.js +219 -359
  90. package/dist/core/utility/environment/systemInformation.js.map +1 -1
  91. package/dist/core/utility/hdbTerms.js +0 -1
  92. package/dist/core/utility/hdbTerms.js.map +1 -1
  93. package/dist/core/utility/operation_authorization.js +2 -2
  94. package/dist/core/utility/operation_authorization.js.map +1 -1
  95. package/npm-shrinkwrap.json +54 -974
  96. package/package.json +1 -2
  97. package/studio/web/assets/{index-qbLPhOzw.js → index-C0And10y.js} +2 -2
  98. package/studio/web/assets/{index-qbLPhOzw.js.map → index-C0And10y.js.map} +1 -1
  99. package/studio/web/index.html +1 -1
  100. package/core/dataLayer/harperBridge/TableSizeObject.ts +0 -35
  101. package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.ts +0 -24
  102. package/core/utility/environment/systemInformation.ts +0 -698
  103. package/dist/core/dataLayer/harperBridge/TableSizeObject.js +0 -32
  104. package/dist/core/dataLayer/harperBridge/TableSizeObject.js.map +0 -1
@@ -256,14 +256,9 @@ export class DatabaseTransaction implements Transaction {
256
256
  if (!outstandingCommit) {
257
257
  outstandingCommit = commitResolution;
258
258
  outstandingCommitStart = performance.now();
259
- outstandingCommit
260
- // if `commitResolution` rejects with and `ERR_BUSY` error, the retry logic
261
- // will correct course, but the reject will still be propagated on the
262
- // `outstandingCommit` promise and needs to be caught and silenced
263
- .catch(() => {})
264
- .finally(() => {
265
- outstandingCommit = null;
266
- });
259
+ outstandingCommit.finally(() => {
260
+ outstandingCommit = null;
261
+ });
267
262
  }
268
263
  const completions = [];
269
264
  return commitResolution.then(
@@ -91,7 +91,6 @@ const NULL_WITH_TIMESTAMP = new Uint8Array(9);
91
91
  NULL_WITH_TIMESTAMP[8] = 0xc0; // null
92
92
  const UNCACHEABLE_TIMESTAMP = Infinity; // we use this when dynamic content is accessed that we can't safely cache, and this prevents earlier timestamps from change the "last" modification
93
93
  const RECORD_PRUNING_INTERVAL = 60000; // one minute
94
- const CACHEABLE_STATUS_CODES = new Set([200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501]);
95
94
  envMngr.initSync();
96
95
  const LMDB_PREFETCH_WRITES = envMngr.get(CONFIG_PARAMS.STORAGE_PREFETCHWRITES);
97
96
  const LOCK_TIMEOUT = 10000;
@@ -4039,14 +4038,15 @@ export function makeTable(options) {
4039
4038
  if (typeof updatedRecord !== 'object') throw new Error('Only objects can be cached and stored in tables');
4040
4039
  if (updatedRecord.status > 0 && updatedRecord.headers) {
4041
4040
  // if the source has a status code and headers, treat it as a response
4042
- const status = updatedRecord.status;
4043
- if (status === 304) {
4044
- // revalidation of our current cached record
4045
- updatedRecord = existingRecord;
4046
- version = existingVersion;
4047
- } else if (!CACHEABLE_STATUS_CODES.has(status)) {
4048
- // non-cacheable status - propagate to client without caching
4049
- throw new ServerError(updatedRecord.body || 'Error from source', status);
4041
+ if (updatedRecord.status >= 300) {
4042
+ if (updatedRecord.status === 304) {
4043
+ // revalidation of our current cached record
4044
+ updatedRecord = existingRecord;
4045
+ version = existingVersion;
4046
+ } else {
4047
+ // if the source has an error status, we need to throw an error
4048
+ throw new ServerError(updatedRecord.body || 'Error from source', updatedRecord.status);
4049
+ } // there are definitely more status codes to handle
4050
4050
  } else {
4051
4051
  let headers: any;
4052
4052
  const sourceHeaders = updatedRecord.headers;
@@ -4074,11 +4074,16 @@ export function makeTable(options) {
4074
4074
  if (data !== undefined) {
4075
4075
  // we have structured data that we have parsed
4076
4076
  delete headers['content-type']; // don't store the content type if we have already parsed it
4077
- updatedRecord = { headers, data };
4077
+ updatedRecord = {
4078
+ headers,
4079
+ data,
4080
+ };
4078
4081
  } else {
4079
- updatedRecord = { headers, body: createBlob(updatedRecord.body) };
4082
+ updatedRecord = {
4083
+ headers,
4084
+ body: createBlob(updatedRecord.body),
4085
+ };
4080
4086
  }
4081
- if (status !== 200) updatedRecord.status = status;
4082
4087
  }
4083
4088
  }
4084
4089
  if (typeof updatedRecord.toJSON === 'function') updatedRecord = updatedRecord.toJSON();
@@ -184,6 +184,7 @@ export function getDatabases(): Databases {
184
184
  getConfigPath(CONFIG_PARAMS.STORAGE_PATH) ||
185
185
  (databasePath && (existsSync(databasePath) ? databasePath : join(getHdbBasePath(), LEGACY_DATABASES_DIR_NAME)));
186
186
  if (!databasePath) return;
187
+
187
188
  if (existsSync(databasePath)) {
188
189
  // First load all the databases from our main database folder
189
190
  // TODO: Load any databases defined with explicit storage paths from the config
@@ -367,7 +368,7 @@ function readRocksMetaDb(path: string, defaultTable?: string, databaseName: stri
367
368
  if (rootStore) {
368
369
  initStores(path, rootStore, databaseName, defaultTable);
369
370
  } else {
370
- rootStore = openRocksDatabase(path, { disableWAL: false, enableStats: true }) as RocksDatabaseEx;
371
+ rootStore = openRocksDatabase(path, { disableWAL: false }) as RocksDatabaseEx;
371
372
  rocksdbDatabaseEnvs.set(path, rootStore);
372
373
  initStores(path, rootStore, databaseName, defaultTable);
373
374
  replayLogs(rootStore, databases[databaseName]);
@@ -722,7 +723,6 @@ export function database({ database: databaseName, table: tableName }) {
722
723
  if (!rootStore || rootStore.status === 'closed') {
723
724
  rootStore = openRocksDatabase(path, {
724
725
  disableWAL: false,
725
- enableStats: true,
726
726
  });
727
727
  rocksdbDatabaseEnvs.set(path, rootStore);
728
728
  }
@@ -35,185 +35,187 @@ server.knownGraphQLDirectives.push(
35
35
  * @param filePath
36
36
  * @param resources
37
37
  */
38
- export function handleApplication(scope: import('../components/Scope.ts').Scope) {
39
- scope.handleEntry(async (entry) => {
40
- if (entry.eventType === 'unlink') return;
41
- await processGraphQLSchema(entry.contents, entry.urlPath, entry.absolutePath, scope.resources);
42
- });
43
- }
38
+ export function start({ ensureTable }) {
39
+ return {
40
+ handleFile,
41
+ setupFile: handleFile,
42
+ };
44
43
 
45
- async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
46
- // lazy load the graphql package so we don't load it for users that don't use graphql
47
- const { parse, Source, Kind } = await import('graphql');
48
- const ast = parse(new Source(gqlContent.toString(), filePath));
49
- const types = new Map();
50
- const tables = [];
51
- // we begin by iterating through the definitions in the AST to get the types and convert them
52
- // to a friendly format for table attributes
53
- for (const definition of ast.definitions) {
54
- switch (definition.kind) {
55
- case Kind.OBJECT_TYPE_DEFINITION:
56
- const typeName = definition.name.value;
57
- // use type name as the default table
58
- const properties = [];
59
- const typeDef = { table: null, database: null, properties };
60
- types.set(typeName, typeDef);
61
- resources.allTypes.set(typeName, typeDef);
62
- for (const directive of definition.directives) {
63
- const directiveName = directive.name.value;
64
- if (directiveName === 'table') {
65
- for (const arg of directive.arguments) {
66
- typeDef[arg.name.value] = (arg.value as StringValueNode).value;
44
+ async function handleFile(gqlContent, urlPath, filePath, resources) {
45
+ // lazy load the graphql package so we don't load it for users that don't use graphql
46
+ const { parse, Source, Kind } = await import('graphql');
47
+ const ast = parse(new Source(gqlContent.toString(), filePath));
48
+ const types = new Map();
49
+ const tables = [];
50
+ // we begin by iterating through the definitions in the AST to get the types and convert them
51
+ // to a friendly format for table attributes
52
+ for (const definition of ast.definitions) {
53
+ switch (definition.kind) {
54
+ case Kind.OBJECT_TYPE_DEFINITION:
55
+ const typeName = definition.name.value;
56
+ // use type name as the default table
57
+ const properties = [];
58
+ const typeDef = { table: null, database: null, properties };
59
+ types.set(typeName, typeDef);
60
+ resources.allTypes.set(typeName, typeDef);
61
+ for (const directive of definition.directives) {
62
+ const directiveName = directive.name.value;
63
+ if (directiveName === 'table') {
64
+ for (const arg of directive.arguments) {
65
+ typeDef[arg.name.value] = (arg.value as StringValueNode).value;
66
+ }
67
+ if (typeDef.schema) typeDef.database = typeDef.schema;
68
+ if (!typeDef.table) typeDef.table = typeName;
69
+ if (typeDef.audit) typeDef.audit = typeDef.audit !== 'false';
70
+ typeDef.attributes = typeDef.properties;
71
+ tables.push(typeDef);
67
72
  }
68
- if (typeDef.schema) typeDef.database = typeDef.schema;
69
- if (!typeDef.table) typeDef.table = typeName;
70
- if (typeDef.audit) typeDef.audit = typeDef.audit !== 'false';
71
- typeDef.attributes = typeDef.properties;
72
- tables.push(typeDef);
73
- }
74
- if (directive.name.value === 'sealed') typeDef.sealed = true;
75
- if (directive.name.value === 'splitSegments') typeDef.splitSegments = true;
76
- if (directive.name.value === 'replicate') typeDef.replicate = true;
77
- if (directive.name.value === 'export') {
78
- typeDef.export = true;
79
- for (const arg of directive.arguments) {
80
- if (typeof typeDef.export !== 'object') typeDef.export = {};
81
- typeDef.export[arg.name.value] = (arg.value as StringValueNode).value;
73
+ if (directive.name.value === 'sealed') typeDef.sealed = true;
74
+ if (directive.name.value === 'splitSegments') typeDef.splitSegments = true;
75
+ if (directive.name.value === 'replicate') typeDef.replicate = true;
76
+ if (directive.name.value === 'export') {
77
+ typeDef.export = true;
78
+ for (const arg of directive.arguments) {
79
+ if (typeof typeDef.export !== 'object') typeDef.export = {};
80
+ typeDef.export[arg.name.value] = (arg.value as StringValueNode).value;
81
+ }
82
82
  }
83
83
  }
84
- }
85
- let hasPrimaryKey = false;
86
- function getProperty(type) {
87
- if (type.kind === 'NonNullType') {
88
- const property = getProperty(type.type);
89
- property.nullable = false;
84
+ let hasPrimaryKey = false;
85
+ function getProperty(type) {
86
+ if (type.kind === 'NonNullType') {
87
+ const property = getProperty(type.type);
88
+ property.nullable = false;
89
+ return property;
90
+ }
91
+ if (type.kind === 'ListType') {
92
+ return {
93
+ type: 'array',
94
+ elements: getProperty(type.type),
95
+ };
96
+ }
97
+ const typeName = (type as NamedTypeNode).name?.value;
98
+ const property = { type: typeName };
99
+ Object.defineProperty(property, 'location', { value: type.loc.startToken });
90
100
  return property;
91
101
  }
92
- if (type.kind === 'ListType') {
93
- return {
94
- type: 'array',
95
- elements: getProperty(type.type),
96
- };
97
- }
98
- const typeName = (type as NamedTypeNode).name?.value;
99
- const property = { type: typeName };
100
- Object.defineProperty(property, 'location', { value: type.loc.startToken });
101
- return property;
102
- }
103
- const attributesObject = {};
104
- for (const field of definition.fields) {
105
- const property = getProperty(field.type);
106
- property.name = field.name.value;
107
- properties.push(property);
108
- attributesObject[property.name] = undefined; // this is used as a backup scope for computed properties
109
- for (const directive of field.directives) {
110
- const directiveName = directive.name.value;
111
- if (directiveName === 'primaryKey') {
112
- if (hasPrimaryKey) console.warn('Can not define two attributes as a primary key at', directive.loc);
113
- else {
114
- property.isPrimaryKey = true;
115
- hasPrimaryKey = true;
116
- }
117
- } else if (directiveName === 'indexed') {
118
- const indexedDefinition = {};
119
- // store indexed arguments for configurable indexes.
120
- for (const arg of directive.arguments || []) {
121
- indexedDefinition[arg.name.value] = (arg.value as StringValueNode).value;
122
- }
123
- property.indexed = indexedDefinition;
124
- } else if (directiveName === 'computed') {
125
- for (const arg of directive.arguments || []) {
126
- if (arg.name.value === 'from') {
127
- const computedFromExpression = (arg.value as StringValueNode).value;
128
- property.computed = {
129
- from: createComputedFrom(computedFromExpression, arg, attributesObject),
130
- };
131
- // if the version is not defined, we use the computed from expression as the version, any changes to the computed from expression will trigger a version change and reindex
132
- if (property.version == undefined) property.version = computedFromExpression;
133
- } else if (arg.name.value === 'version') {
134
- property.version = (arg.value as StringValueNode).value;
102
+ const attributesObject = {};
103
+ for (const field of definition.fields) {
104
+ const property = getProperty(field.type);
105
+ property.name = field.name.value;
106
+ properties.push(property);
107
+ attributesObject[property.name] = undefined; // this is used as a backup scope for computed properties
108
+ for (const directive of field.directives) {
109
+ const directiveName = directive.name.value;
110
+ if (directiveName === 'primaryKey') {
111
+ if (hasPrimaryKey) console.warn('Can not define two attributes as a primary key at', directive.loc);
112
+ else {
113
+ property.isPrimaryKey = true;
114
+ hasPrimaryKey = true;
135
115
  }
136
- }
137
- property.computed = property.computed || true;
138
- } else if (directiveName === 'relationship') {
139
- const relationshipDefinition = {};
140
- for (const arg of directive.arguments) {
141
- relationshipDefinition[arg.name.value] = (arg.value as StringValueNode).value;
142
- }
143
- property.relationship = relationshipDefinition;
144
- } else if (directiveName === 'createdTime') {
145
- property.assignCreatedTime = true;
146
- } else if (directiveName === 'updatedTime') {
147
- property.assignUpdatedTime = true;
148
- } else if (directiveName === 'expiresAt') {
149
- property.expiresAt = true;
150
- } else if (directiveName === 'enumerable') {
151
- property.enumerable = true;
152
- } else if (directiveName === 'allow') {
153
- const authorizedRoles = (property.authorizedRoles = []);
154
- for (const arg of directive.arguments) {
155
- if (arg.name.value === 'role') {
156
- authorizedRoles.push((arg.value as StringValueNode).value);
116
+ } else if (directiveName === 'indexed') {
117
+ const indexedDefinition = {};
118
+ // store indexed arguments for configurable indexes.
119
+ for (const arg of directive.arguments || []) {
120
+ indexedDefinition[arg.name.value] = (arg.value as StringValueNode).value;
121
+ }
122
+ property.indexed = indexedDefinition;
123
+ } else if (directiveName === 'computed') {
124
+ for (const arg of directive.arguments || []) {
125
+ if (arg.name.value === 'from') {
126
+ const computedFromExpression = (arg.value as StringValueNode).value;
127
+ property.computed = {
128
+ from: createComputedFrom(computedFromExpression, arg, attributesObject),
129
+ };
130
+ // if the version is not defined, we use the computed from expression as the version, any changes to the computed from expression will trigger a version change and reindex
131
+ if (property.version == undefined) property.version = computedFromExpression;
132
+ } else if (arg.name.value === 'version') {
133
+ property.version = (arg.value as StringValueNode).value;
134
+ }
157
135
  }
136
+ property.computed = property.computed || true;
137
+ } else if (directiveName === 'relationship') {
138
+ const relationshipDefinition = {};
139
+ for (const arg of directive.arguments) {
140
+ relationshipDefinition[arg.name.value] = (arg.value as StringValueNode).value;
141
+ }
142
+ property.relationship = relationshipDefinition;
143
+ } else if (directiveName === 'createdTime') {
144
+ property.assignCreatedTime = true;
145
+ } else if (directiveName === 'updatedTime') {
146
+ property.assignUpdatedTime = true;
147
+ } else if (directiveName === 'expiresAt') {
148
+ property.expiresAt = true;
149
+ } else if (directiveName === 'enumerable') {
150
+ property.enumerable = true;
151
+ } else if (directiveName === 'allow') {
152
+ const authorizedRoles = (property.authorizedRoles = []);
153
+ for (const arg of directive.arguments) {
154
+ if (arg.name.value === 'role') {
155
+ authorizedRoles.push((arg.value as StringValueNode).value);
156
+ }
157
+ }
158
+ } else if (server.knownGraphQLDirectives.includes(directiveName)) {
159
+ console.warn(`@${directiveName} is an unknown directive, at`, directive.loc);
158
160
  }
159
- } else if (server.knownGraphQLDirectives.includes(directiveName)) {
160
- console.warn(`@${directiveName} is an unknown directive, at`, directive.loc);
161
161
  }
162
162
  }
163
- }
164
- typeDef.type = typeName;
163
+ typeDef.type = typeName;
164
+ }
165
165
  }
166
- }
167
- // check the types and if any types reference other types, fill those in.
168
- function connectPropertyType(property) {
169
- const targetTypeDef = types.get(property.type);
170
- if (targetTypeDef) {
171
- Object.defineProperty(property, 'properties', { value: targetTypeDef.properties });
172
- Object.defineProperty(property, 'definition', { value: targetTypeDef });
173
- } else if (property.type === 'array') connectPropertyType(property.elements);
174
- else if (!PRIMITIVE_TYPES.includes(property.type)) {
175
- if (getWorkerIndex() === 0)
176
- console.error(
177
- `The type ${property.type} is unknown at line ${property.location.line}, column ${property.location.column}, in ${filePath}`
178
- );
166
+ // check the types and if any types reference other types, fill those in.
167
+ function connectPropertyType(property) {
168
+ const targetTypeDef = types.get(property.type);
169
+ if (targetTypeDef) {
170
+ Object.defineProperty(property, 'properties', { value: targetTypeDef.properties });
171
+ Object.defineProperty(property, 'definition', { value: targetTypeDef });
172
+ } else if (property.type === 'array') connectPropertyType(property.elements);
173
+ else if (!PRIMITIVE_TYPES.includes(property.type)) {
174
+ if (getWorkerIndex() === 0)
175
+ console.error(
176
+ `The type ${property.type} is unknown at line ${property.location.line}, column ${property.location.column}, in ${filePath}`
177
+ );
178
+ }
179
179
  }
180
- }
181
- for (const typeDef of types.values()) {
182
- for (const property of typeDef.properties) connectPropertyType(property);
183
- }
184
- // any tables that are defined in the schema can now be registered
185
- for (const typeDef of tables) {
186
- // with graphql database definitions, this is a declaration that the table should exist and that it
187
- // should be created if it does not exist
188
- typeDef.tableClass = table(typeDef);
189
- if (typeDef.export) {
190
- // allow empty string to be used to declare a table on the root path
191
- if (typeDef.export.name === '') resources.set(dirname(urlPath), typeDef.tableClass);
192
- else
193
- resources.set(
194
- dirname(urlPath) + '/' + (typeDef.export.name || typeDef.type),
195
- typeDef.tableClass,
196
- typeDef.export
197
- );
180
+ for (const typeDef of types.values()) {
181
+ for (const property of typeDef.properties) connectPropertyType(property);
198
182
  }
199
- }
200
- function createComputedFrom(computedFrom: string, arg: any, attributes: any) {
201
- // Create a function from a computed "from" directive. This can look like:
202
- // @computed(from: "fieldOne + fieldTwo")
203
- // We use Node's built-in Script class to compile the function and run it in the context of the record object, which allows us to specify the source
204
- const script = new Script(
205
- // we use the inner with statement to allow the computed function to access the record object's properties directly as top level names
206
- // we use the outer with statement with attributes as a fallback so any access to an attribute that isn't defined on the record still returns undefined (instead of a ReferenceError)
207
- `function computed(attributes) { return function(record) { with(attributes) { with (record) { return ${computedFrom}; } } } } computed;`,
208
- {
209
- filename: filePath, // specify the file path and line position for better error messages/debugging
210
- lineOffset: arg.loc.startToken.line - 1,
211
- columnOffset: arg.loc.startToken.column,
183
+ // any tables that are defined in the schema can now be registered
184
+ for (const typeDef of tables) {
185
+ // with graphql database definitions, this is a declaration that the table should exist and that it
186
+ // should be created if it does not exist
187
+ typeDef.tableClass = ensureTable(typeDef);
188
+ if (typeDef.export) {
189
+ // allow empty string to be used to declare a table on the root path
190
+ if (typeDef.export.name === '') resources.set(dirname(urlPath), typeDef.tableClass);
191
+ else
192
+ resources.set(
193
+ dirname(urlPath) + '/' + (typeDef.export.name || typeDef.type),
194
+ typeDef.tableClass,
195
+ typeDef.export
196
+ );
212
197
  }
213
- );
214
- return script.runInThisContext()(attributes); // run the script in the context of the current context/global and return the function we defined
198
+ }
199
+ function createComputedFrom(computedFrom: string, arg: any, attributes: any) {
200
+ // Create a function from a computed "from" directive. This can look like:
201
+ // @computed(from: "fieldOne + fieldTwo")
202
+ // We use Node's built-in Script class to compile the function and run it in the context of the record object, which allows us to specify the source
203
+ const script = new Script(
204
+ // we use the inner with statement to allow the computed function to access the record object's properties directly as top level names
205
+ // we use the outer with statement with attributes as a fallback so any access to an attribute that isn't defined on the record still returns undefined (instead of a ReferenceError)
206
+ `function computed(attributes) { return function(record) { with(attributes) { with (record) { return ${computedFrom}; } } } } computed;`,
207
+ {
208
+ filename: filePath, // specify the file path and line position for better error messages/debugging
209
+ lineOffset: arg.loc.startToken.line - 1,
210
+ columnOffset: arg.loc.startToken.column,
211
+ }
212
+ );
213
+ return script.runInThisContext()(attributes); // run the script in the context of the current context/global and return the function we defined
214
+ }
215
215
  }
216
216
  }
217
217
 
218
+ export const startOnMainThread = start;
218
219
  // useful for testing
219
- export const loadGQLSchema = (content) => processGraphQLSchema(content, null, null, new Resources());
220
+ export const loadGQLSchema = (content) =>
221
+ start({ ensureTable: table }).handleFile(content, null, null, new Resources());
@@ -1,4 +1,4 @@
1
- import { cosineDistance, euclideanDistance, dotProductDistance } from './vector.ts';
1
+ import { cosineDistance, euclideanDistance } from './vector.ts';
2
2
  import { FLOAT32_OPTIONS } from 'msgpackr';
3
3
  import { loggerWithTag } from '../../utility/logging/logger.ts';
4
4
  import { ClientError } from '../../utility/errors/hdbError.js';
@@ -52,12 +52,7 @@ export class HierarchicalNavigableSmallWorld {
52
52
  // (we would actually like to use float16 if it were available)
53
53
  this.indexStore.encoder.useFloat32 = FLOAT32_OPTIONS.ALWAYS;
54
54
  }
55
- this.distance =
56
- options?.distance === 'euclidean'
57
- ? euclideanDistance
58
- : options?.distance === 'dotProduct'
59
- ? dotProductDistance
60
- : cosineDistance;
55
+ this.distance = options?.distance === 'euclidean' ? euclideanDistance : cosineDistance;
61
56
  if (options) {
62
57
  // allow all the HNSW parameters to be configured/tuned
63
58
  if (options.M !== undefined) {
@@ -474,7 +469,6 @@ export class HierarchicalNavigableSmallWorld {
474
469
  let distanceFunction: (a: number[], b: number[]) => number;
475
470
  if (distance === 'cosine') distanceFunction = cosineDistance;
476
471
  else if (distance === 'euclidean') distanceFunction = euclideanDistance;
477
- else if (distance === 'dotProduct') distanceFunction = dotProductDistance;
478
472
  else if (distance) throw new ClientError('Unknown distance function');
479
473
  else distanceFunction = this.distance;
480
474
  if (!target) throw new ClientError('A target vector must be provided for an HNSW query');
@@ -664,12 +658,7 @@ export class HierarchicalNavigableSmallWorld {
664
658
 
665
659
  let distanceFunction = this.distance;
666
660
  if (sortDefinition.type)
667
- distanceFunction =
668
- sortDefinition.distance === 'euclidean'
669
- ? euclideanDistance
670
- : sortDefinition.distance === 'dotProduct'
671
- ? dotProductDistance
672
- : cosineDistance;
661
+ distanceFunction = sortDefinition.distance === 'euclidean' ? euclideanDistance : cosineDistance;
673
662
  const distance = distanceFunction(sortDefinition.target, vector);
674
663
  vectorDistances.set(entry, distance);
675
664
  return distance;
@@ -36,20 +36,3 @@ export function cosineDistance(a: number[], b: number[]): number {
36
36
 
37
37
  return 1 - dotProduct / (magnitudeA * magnitudeB || 1);
38
38
  }
39
-
40
- export function dotProductDistance(a: number[], b: number[]): number {
41
- if (!Array.isArray(a) || !Array.isArray(b)) {
42
- throw new Error('Inner product comparison requires an array');
43
- }
44
-
45
- let dotProduct = 0;
46
- const length = Math.max(a.length, b.length);
47
-
48
- for (let i = 0; i < length; i++) {
49
- const va = a[i] || 0;
50
- const vb = b[i] || 0;
51
- dotProduct += va * vb;
52
- }
53
-
54
- return -dotProduct;
55
- }
@@ -1,26 +1,22 @@
1
1
  import { parse } from 'dotenv';
2
2
  import logger from '../utility/logging/harper_logger.js';
3
- import { Scope } from '../components/Scope.ts';
4
3
 
5
- export function handleApplication(scope: Scope) {
6
- const override = (scope.options.getAll() as { override?: boolean }).override ?? false;
7
- scope.handleEntry((entry) => {
8
- if (entry.eventType !== 'add') {
9
- scope.requestRestart();
10
- return;
11
- }
12
- logger.debug(`Loading env file: ${entry.absolutePath}`);
13
- for (const [key, value] of Object.entries(parse(entry.contents))) {
14
- if (process.env[key] !== undefined) {
15
- logger.warn(`Environment variable conflict: ${key} from ${entry.absolutePath} is already set on process.env`);
16
- if (override) {
17
- logger.debug(`override option enabled. overriding environment variable: ${key}`);
18
- } else {
19
- continue;
4
+ export function start({ override }: { override: boolean }) {
5
+ return {
6
+ handleFile: (contents, _, filePath) => {
7
+ logger.debug(`Loading env file: ${filePath}`);
8
+ for (const [key, value] of Object.entries(parse(contents))) {
9
+ if (process.env[key] !== undefined) {
10
+ logger.warn(`Environment variable conflict: ${key} from ${filePath} is already set on process.env`);
11
+ if (override) {
12
+ logger.debug(`override option enabled. overriding environment variable: ${key}`);
13
+ } else {
14
+ continue;
15
+ }
20
16
  }
21
- }
22
17
 
23
- process.env[key] = value;
24
- }
25
- });
18
+ process.env[key] = value;
19
+ }
20
+ },
21
+ };
26
22
  }
@@ -1,8 +1,7 @@
1
1
  import { Resource } from './Resource.ts';
2
- import { Scope } from '../components/Scope.ts';
3
- export function handleApplication(scope: Scope) {
4
- scope.resources.set('login', Login);
5
- scope.resources.loginPath = (request) => {
2
+ export function start({ resources }) {
3
+ resources.set('login', Login);
4
+ resources.loginPath = (request) => {
6
5
  return '/login?redirect=' + encodeURIComponent(request.url);
7
6
  };
8
7
  }