@rvoh/dream 0.29.4 → 0.29.5

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 (161) hide show
  1. package/dist/cjs/src/db/DreamDbConnection.js +7 -1
  2. package/dist/cjs/src/db/errors.js +10 -3
  3. package/dist/cjs/src/dream/Query.js +32 -12
  4. package/dist/cjs/src/dream-application/index.js +6 -0
  5. package/dist/cjs/src/helpers/db/loadPgClient.js +6 -0
  6. package/dist/esm/src/db/DreamDbConnection.js +7 -1
  7. package/dist/esm/src/db/errors.js +10 -3
  8. package/dist/esm/src/dream/Query.js +32 -12
  9. package/dist/esm/src/dream-application/index.js +6 -0
  10. package/dist/esm/src/helpers/db/loadPgClient.js +6 -0
  11. package/dist/types/src/dream/Query.d.ts +11 -0
  12. package/docs/classes/Benchmark.html +2 -2
  13. package/docs/classes/CalendarDate.html +2 -2
  14. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
  15. package/docs/classes/Decorators.html +14 -14
  16. package/docs/classes/Dream.html +126 -126
  17. package/docs/classes/DreamApplication.html +4 -4
  18. package/docs/classes/DreamBin.html +2 -2
  19. package/docs/classes/DreamCLI.html +3 -3
  20. package/docs/classes/DreamImporter.html +2 -2
  21. package/docs/classes/DreamMigrationHelpers.html +7 -7
  22. package/docs/classes/DreamSerializer.html +2 -2
  23. package/docs/classes/DreamTransaction.html +2 -2
  24. package/docs/classes/Encrypt.html +2 -2
  25. package/docs/classes/Env.html +2 -2
  26. package/docs/classes/GlobalNameNotSet.html +3 -3
  27. package/docs/classes/NonLoadedAssociation.html +3 -3
  28. package/docs/classes/Query.html +50 -50
  29. package/docs/classes/Range.html +2 -2
  30. package/docs/classes/RecordNotFound.html +3 -3
  31. package/docs/classes/ValidationError.html +3 -3
  32. package/docs/functions/Attribute.html +1 -1
  33. package/docs/functions/RendersMany.html +1 -1
  34. package/docs/functions/RendersOne.html +1 -1
  35. package/docs/functions/ReplicaSafe.html +1 -1
  36. package/docs/functions/STI.html +1 -1
  37. package/docs/functions/Scope.html +1 -1
  38. package/docs/functions/SoftDelete.html +1 -1
  39. package/docs/functions/Validate.html +1 -1
  40. package/docs/functions/Validates.html +1 -1
  41. package/docs/functions/Virtual.html +1 -1
  42. package/docs/functions/camelize.html +1 -1
  43. package/docs/functions/capitalize.html +1 -1
  44. package/docs/functions/closeAllDbConnections.html +1 -1
  45. package/docs/functions/compact.html +1 -1
  46. package/docs/functions/db.html +1 -1
  47. package/docs/functions/debug.html +1 -1
  48. package/docs/functions/dreamDbConnections.html +1 -1
  49. package/docs/functions/dreamPath.html +1 -1
  50. package/docs/functions/generateDream.html +1 -1
  51. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  52. package/docs/functions/hyphenize.html +1 -1
  53. package/docs/functions/inferSerializerFromDreamClassOrViewModelClass.html +1 -1
  54. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  55. package/docs/functions/isEmpty.html +1 -1
  56. package/docs/functions/loadRepl.html +1 -1
  57. package/docs/functions/lookupClassByGlobalName.html +1 -1
  58. package/docs/functions/pascalize.html +1 -1
  59. package/docs/functions/pgErrorType.html +1 -1
  60. package/docs/functions/range-1.html +1 -1
  61. package/docs/functions/relativeDreamPath.html +1 -1
  62. package/docs/functions/round.html +1 -1
  63. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  64. package/docs/functions/sharedPathPrefix.html +1 -1
  65. package/docs/functions/snakeify.html +1 -1
  66. package/docs/functions/sortBy.html +1 -1
  67. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  68. package/docs/functions/uncapitalize.html +1 -1
  69. package/docs/functions/uniq.html +1 -1
  70. package/docs/functions/validateColumn.html +1 -1
  71. package/docs/functions/validateTable.html +1 -1
  72. package/docs/interfaces/AttributeStatement.html +2 -2
  73. package/docs/interfaces/DecoratorContext.html +2 -2
  74. package/docs/interfaces/DreamApplicationInitOptions.html +2 -2
  75. package/docs/interfaces/DreamApplicationOpts.html +2 -2
  76. package/docs/interfaces/DreamSerializerAssociationStatement.html +2 -2
  77. package/docs/interfaces/EncryptOptions.html +2 -2
  78. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  79. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  80. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  81. package/docs/types/Camelized.html +1 -1
  82. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  83. package/docs/types/DreamAssociationMetadata.html +1 -1
  84. package/docs/types/DreamAttributes.html +1 -1
  85. package/docs/types/DreamClassColumn.html +1 -1
  86. package/docs/types/DreamColumn.html +1 -1
  87. package/docs/types/DreamColumnNames.html +1 -1
  88. package/docs/types/DreamLogLevel.html +1 -1
  89. package/docs/types/DreamLogger.html +1 -1
  90. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  91. package/docs/types/DreamParamSafeAttributes.html +1 -1
  92. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  93. package/docs/types/DreamSerializerKey.html +1 -1
  94. package/docs/types/DreamSerializers.html +1 -1
  95. package/docs/types/DreamTableSchema.html +1 -1
  96. package/docs/types/DreamVirtualColumns.html +1 -1
  97. package/docs/types/EncryptAlgorithm.html +1 -1
  98. package/docs/types/Hyphenized.html +1 -1
  99. package/docs/types/IdType.html +1 -1
  100. package/docs/types/OpenapiAllTypes.html +1 -1
  101. package/docs/types/OpenapiFormats.html +1 -1
  102. package/docs/types/OpenapiNumberFormats.html +1 -1
  103. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  104. package/docs/types/OpenapiSchemaArray.html +1 -1
  105. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  106. package/docs/types/OpenapiSchemaBase.html +1 -1
  107. package/docs/types/OpenapiSchemaBody.html +1 -1
  108. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  109. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  110. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  111. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  112. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  113. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  114. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  115. package/docs/types/OpenapiSchemaInteger.html +1 -1
  116. package/docs/types/OpenapiSchemaNull.html +1 -1
  117. package/docs/types/OpenapiSchemaNumber.html +1 -1
  118. package/docs/types/OpenapiSchemaObject.html +1 -1
  119. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  120. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  121. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  122. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  123. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  124. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  125. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  126. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  127. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  128. package/docs/types/OpenapiSchemaPartialSegment.html +1 -1
  129. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  130. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  131. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  132. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  133. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  134. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  135. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  136. package/docs/types/OpenapiSchemaString.html +1 -1
  137. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  138. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  139. package/docs/types/OpenapiTypeField.html +1 -1
  140. package/docs/types/Pascalized.html +1 -1
  141. package/docs/types/PrimaryKeyType.html +1 -1
  142. package/docs/types/RoundingPrecision.html +1 -1
  143. package/docs/types/SerializableClassOrSerializerCallback.html +1 -1
  144. package/docs/types/SerializableDreamClassOrViewModelClass.html +1 -1
  145. package/docs/types/SerializableDreamOrViewModel.html +1 -1
  146. package/docs/types/SerializableTypes.html +1 -1
  147. package/docs/types/Snakeified.html +1 -1
  148. package/docs/types/Timestamp.html +1 -1
  149. package/docs/types/UpdateableAssociationProperties.html +1 -1
  150. package/docs/types/UpdateableProperties.html +1 -1
  151. package/docs/types/ValidationType.html +1 -1
  152. package/docs/types/ViewModelSerializerKey.html +1 -1
  153. package/docs/types/WhereStatementForDream.html +1 -1
  154. package/docs/types/WhereStatementForDreamClass.html +1 -1
  155. package/docs/variables/DreamConst.html +1 -1
  156. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  157. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  158. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  159. package/docs/variables/ops.html +1 -1
  160. package/docs/variables/primaryKeyTypes.html +1 -1
  161. package/package.json +2 -2
@@ -2,10 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.dreamDbConnections = dreamDbConnections;
4
4
  exports.closeAllDbConnections = closeAllDbConnections;
5
- const kysely_1 = require("kysely");
5
+ // after building for esm, importing pg using the following:
6
+ //
7
+ // import * as pg from 'pg'
8
+ //
9
+ // will crash. This is difficult to discover, since it only happens
10
+ // when being imported from our esm build.
6
11
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
7
12
  // @ts-ignore
8
13
  const pg_1 = require("pg");
14
+ const kysely_1 = require("kysely");
9
15
  const index_js_1 = require("../dream-application/index.js");
10
16
  const ConnectionConfRetriever_js_1 = require("./ConnectionConfRetriever.js");
11
17
  let connections = {};
@@ -2,8 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PG_ERRORS = void 0;
4
4
  exports.pgErrorType = pgErrorType;
5
- const pg = require("pg");
6
- const { DatabaseError } = pg;
5
+ // after building for esm, importing pg using the following:
6
+ //
7
+ // import * as pg from 'pg'
8
+ //
9
+ // will crash. This is difficult to discover, since it only happens
10
+ // when being imported from our esm build.
11
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
+ // @ts-ignore
13
+ const pg_1 = require("pg");
7
14
  exports.PG_ERRORS = {
8
15
  23505: 'UNIQUE_CONSTRAINT_VIOLATION',
9
16
  };
@@ -11,7 +18,7 @@ function pgErrorFromCode(code) {
11
18
  return exports.PG_ERRORS[code] || null;
12
19
  }
13
20
  function pgErrorType(error) {
14
- if (error instanceof DatabaseError)
21
+ if (error instanceof pg_1.default.DatabaseError)
15
22
  return pgErrorFromCode(error.code);
16
23
  return null;
17
24
  }
@@ -1101,6 +1101,9 @@ class Query extends ConnectedToDB_js_1.default {
1101
1101
  // base model, it will be underscored (to match the table name), but when the selected column
1102
1102
  // comes back from Kysely camelCased
1103
1103
  aliases.push(field.includes('_') ? (0, camelize_js_1.default)(field) : field);
1104
+ // namespace the selection so that when plucking the same column name from
1105
+ // multpile tables, they don't get saved as the same name (e.g. select results with two `id` columns,
1106
+ // which the pg package then returns in an object with a single `id` key)
1104
1107
  kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(field)} as ${field}`);
1105
1108
  });
1106
1109
  return (await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'execute')).map(singleResult => aliases.map(alias => singleResult[alias]));
@@ -1802,14 +1805,15 @@ class Query extends ConnectedToDB_js_1.default {
1802
1805
  const dream = dreams.find(dream => dream['getAssociationMetadata'](associationName));
1803
1806
  if (!dream)
1804
1807
  return;
1805
- const association = dream['getAssociationMetadata'](associationName);
1808
+ const { name, alias } = (0, extractAssociationMetadataFromAssociationName_js_1.default)(associationName);
1809
+ const association = dream['getAssociationMetadata'](name);
1806
1810
  const dreamClass = dream.constructor;
1807
1811
  const dreamClassToHydrate = association.modelCB();
1808
1812
  if ((association.polymorphic && association.type === 'BelongsTo') || Array.isArray(dreamClassToHydrate))
1809
1813
  return this.preloadPolymorphicBelongsTo(association, dreams);
1810
1814
  const dreamClassToHydrateColumns = [...dreamClassToHydrate.columns()];
1811
1815
  const throughColumnsToHydrate = [];
1812
- const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), associationName));
1816
+ const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), alias));
1813
1817
  const asHasAssociation = association;
1814
1818
  if (asHasAssociation.through && asHasAssociation.preloadThroughColumns) {
1815
1819
  if ((0, typechecks_js_1.isObject)(asHasAssociation.preloadThroughColumns)) {
@@ -1921,9 +1925,17 @@ class Query extends ConnectedToDB_js_1.default {
1921
1925
  }
1922
1926
  return query;
1923
1927
  }
1924
- // Through associations don't get written into the SQL; they
1925
- // locate the next association we need to build into the SQL
1926
- // AND the source to reference on the other side
1928
+ /**
1929
+ * Each association in the chain is pushed onto `throughAssociations`
1930
+ * and `applyOneJoin` is recursively called. The trick is that the
1931
+ * through associations don't get written into the SQL; they
1932
+ * locate the next association we need to build into the SQL,
1933
+ * which is only run by the association that started the `through`
1934
+ * chain. The final association at the end of the `through` chain _is_
1935
+ * written into the SQL as a full association, but the modifications from
1936
+ * the `through` association are only added when the recursion returns
1937
+ * back to the association that kicked off the through associations.
1938
+ */
1927
1939
  joinsBridgeThroughAssociations({ query, dreamClass, association, previousAssociationTableOrAlias, throughAssociations, joinType, }) {
1928
1940
  if (association.type === 'BelongsTo' || !association.through) {
1929
1941
  return {
@@ -2004,25 +2016,33 @@ class Query extends ConnectedToDB_js_1.default {
2004
2016
  previousAssociationTableOrAlias = results.previousAssociationTableOrAlias;
2005
2017
  const throughClass = results.throughClass;
2006
2018
  if (timeToApplyThroughAssociations) {
2007
- ///////////////////////////////////////////////////////////////////////////////////////
2008
- // when an association is through another association, `joinsBridgeThroughAssociations`
2009
- // is called, which eventually calls back to this method, passing in the original
2010
- // through association as `originalAssociation`
2011
- ///////////////////////////////////////////////////////////////////////////////////////
2019
+ /**
2020
+ * Each association in the chain is pushed onto `throughAssociations`
2021
+ * and `applyOneJoin` is recursively called. The trick is that the
2022
+ * through associations don't get written into the SQL; they
2023
+ * locate the next association we need to build into the SQL,
2024
+ * which is only run by the association that started the `through`
2025
+ * chain (thus the
2026
+ * `throughAssociations.length && throughAssociations[0].source === association.as`
2027
+ * above). The final association at the end of the `through` chain _is_
2028
+ * written into the SQL as a full association, but the modifications from
2029
+ * the `through` association are only added when the recursion returns
2030
+ * back to the association that kicked off the through associations.
2031
+ */
2012
2032
  throughAssociations.forEach((throughAssociation) => {
2013
2033
  if (throughAssociation.type === 'HasMany') {
2014
2034
  if (query?.distinctOn && throughAssociation.distinct) {
2015
2035
  query = query.distinctOn(this.distinctColumnNameForAssociation({
2016
2036
  association: throughAssociation,
2017
- tableNameOrAlias: throughAssociation.as,
2037
+ tableNameOrAlias: currentAssociationTableOrAlias,
2018
2038
  foreignKey: throughAssociation.primaryKey(),
2019
2039
  }));
2020
2040
  }
2021
2041
  if (throughAssociation.order) {
2022
2042
  query = this.applyOrderStatementForAssociation({
2023
2043
  query,
2024
- tableNameOrAlias: throughAssociation.as,
2025
2044
  association: throughAssociation,
2045
+ tableNameOrAlias: currentAssociationTableOrAlias,
2026
2046
  });
2027
2047
  }
2028
2048
  }
@@ -1,5 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ // after building for esm, importing pg using the following:
4
+ //
5
+ // import * as pg from 'pg'
6
+ //
7
+ // will crash. This is difficult to discover, since it only happens
8
+ // when being imported from our esm build.
3
9
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
10
  // @ts-ignore
5
11
  const pg_1 = require("pg");
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = loadPgClient;
4
+ // after building for esm, importing pg using the following:
5
+ //
6
+ // import * as pg from 'pg'
7
+ //
8
+ // will crash. This is difficult to discover, since it only happens
9
+ // when being imported from our esm build.
4
10
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
11
  // @ts-ignore
6
12
  const pg_1 = require("pg");
@@ -1,7 +1,13 @@
1
- import { CamelCasePlugin, Kysely, PostgresDialect } from 'kysely';
1
+ // after building for esm, importing pg using the following:
2
+ //
3
+ // import * as pg from 'pg'
4
+ //
5
+ // will crash. This is difficult to discover, since it only happens
6
+ // when being imported from our esm build.
2
7
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
8
  // @ts-ignore
4
9
  import pg from 'pg';
10
+ import { CamelCasePlugin, Kysely, PostgresDialect } from 'kysely';
5
11
  import DreamApplication from '../dream-application/index.js';
6
12
  import ConnectionConfRetriever from './ConnectionConfRetriever.js';
7
13
  let connections = {};
@@ -1,5 +1,12 @@
1
- import * as pg from 'pg';
2
- const { DatabaseError } = pg;
1
+ // after building for esm, importing pg using the following:
2
+ //
3
+ // import * as pg from 'pg'
4
+ //
5
+ // will crash. This is difficult to discover, since it only happens
6
+ // when being imported from our esm build.
7
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
8
+ // @ts-ignore
9
+ import pg from 'pg';
3
10
  export const PG_ERRORS = {
4
11
  23505: 'UNIQUE_CONSTRAINT_VIOLATION',
5
12
  };
@@ -7,7 +14,7 @@ function pgErrorFromCode(code) {
7
14
  return PG_ERRORS[code] || null;
8
15
  }
9
16
  export function pgErrorType(error) {
10
- if (error instanceof DatabaseError)
17
+ if (error instanceof pg.DatabaseError)
11
18
  return pgErrorFromCode(error.code);
12
19
  return null;
13
20
  }
@@ -1099,6 +1099,9 @@ export default class Query extends ConnectedToDB {
1099
1099
  // base model, it will be underscored (to match the table name), but when the selected column
1100
1100
  // comes back from Kysely camelCased
1101
1101
  aliases.push(field.includes('_') ? camelize(field) : field);
1102
+ // namespace the selection so that when plucking the same column name from
1103
+ // multpile tables, they don't get saved as the same name (e.g. select results with two `id` columns,
1104
+ // which the pg package then returns in an object with a single `id` key)
1102
1105
  kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(field)} as ${field}`);
1103
1106
  });
1104
1107
  return (await executeDatabaseQuery(kyselyQuery, 'execute')).map(singleResult => aliases.map(alias => singleResult[alias]));
@@ -1800,14 +1803,15 @@ export default class Query extends ConnectedToDB {
1800
1803
  const dream = dreams.find(dream => dream['getAssociationMetadata'](associationName));
1801
1804
  if (!dream)
1802
1805
  return;
1803
- const association = dream['getAssociationMetadata'](associationName);
1806
+ const { name, alias } = extractAssociationMetadataFromAssociationName(associationName);
1807
+ const association = dream['getAssociationMetadata'](name);
1804
1808
  const dreamClass = dream.constructor;
1805
1809
  const dreamClassToHydrate = association.modelCB();
1806
1810
  if ((association.polymorphic && association.type === 'BelongsTo') || Array.isArray(dreamClassToHydrate))
1807
1811
  return this.preloadPolymorphicBelongsTo(association, dreams);
1808
1812
  const dreamClassToHydrateColumns = [...dreamClassToHydrate.columns()];
1809
1813
  const throughColumnsToHydrate = [];
1810
- const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), associationName));
1814
+ const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), alias));
1811
1815
  const asHasAssociation = association;
1812
1816
  if (asHasAssociation.through && asHasAssociation.preloadThroughColumns) {
1813
1817
  if (isObject(asHasAssociation.preloadThroughColumns)) {
@@ -1919,9 +1923,17 @@ export default class Query extends ConnectedToDB {
1919
1923
  }
1920
1924
  return query;
1921
1925
  }
1922
- // Through associations don't get written into the SQL; they
1923
- // locate the next association we need to build into the SQL
1924
- // AND the source to reference on the other side
1926
+ /**
1927
+ * Each association in the chain is pushed onto `throughAssociations`
1928
+ * and `applyOneJoin` is recursively called. The trick is that the
1929
+ * through associations don't get written into the SQL; they
1930
+ * locate the next association we need to build into the SQL,
1931
+ * which is only run by the association that started the `through`
1932
+ * chain. The final association at the end of the `through` chain _is_
1933
+ * written into the SQL as a full association, but the modifications from
1934
+ * the `through` association are only added when the recursion returns
1935
+ * back to the association that kicked off the through associations.
1936
+ */
1925
1937
  joinsBridgeThroughAssociations({ query, dreamClass, association, previousAssociationTableOrAlias, throughAssociations, joinType, }) {
1926
1938
  if (association.type === 'BelongsTo' || !association.through) {
1927
1939
  return {
@@ -2002,25 +2014,33 @@ export default class Query extends ConnectedToDB {
2002
2014
  previousAssociationTableOrAlias = results.previousAssociationTableOrAlias;
2003
2015
  const throughClass = results.throughClass;
2004
2016
  if (timeToApplyThroughAssociations) {
2005
- ///////////////////////////////////////////////////////////////////////////////////////
2006
- // when an association is through another association, `joinsBridgeThroughAssociations`
2007
- // is called, which eventually calls back to this method, passing in the original
2008
- // through association as `originalAssociation`
2009
- ///////////////////////////////////////////////////////////////////////////////////////
2017
+ /**
2018
+ * Each association in the chain is pushed onto `throughAssociations`
2019
+ * and `applyOneJoin` is recursively called. The trick is that the
2020
+ * through associations don't get written into the SQL; they
2021
+ * locate the next association we need to build into the SQL,
2022
+ * which is only run by the association that started the `through`
2023
+ * chain (thus the
2024
+ * `throughAssociations.length && throughAssociations[0].source === association.as`
2025
+ * above). The final association at the end of the `through` chain _is_
2026
+ * written into the SQL as a full association, but the modifications from
2027
+ * the `through` association are only added when the recursion returns
2028
+ * back to the association that kicked off the through associations.
2029
+ */
2010
2030
  throughAssociations.forEach((throughAssociation) => {
2011
2031
  if (throughAssociation.type === 'HasMany') {
2012
2032
  if (query?.distinctOn && throughAssociation.distinct) {
2013
2033
  query = query.distinctOn(this.distinctColumnNameForAssociation({
2014
2034
  association: throughAssociation,
2015
- tableNameOrAlias: throughAssociation.as,
2035
+ tableNameOrAlias: currentAssociationTableOrAlias,
2016
2036
  foreignKey: throughAssociation.primaryKey(),
2017
2037
  }));
2018
2038
  }
2019
2039
  if (throughAssociation.order) {
2020
2040
  query = this.applyOrderStatementForAssociation({
2021
2041
  query,
2022
- tableNameOrAlias: throughAssociation.as,
2023
2042
  association: throughAssociation,
2043
+ tableNameOrAlias: currentAssociationTableOrAlias,
2024
2044
  });
2025
2045
  }
2026
2046
  }
@@ -1,3 +1,9 @@
1
+ // after building for esm, importing pg using the following:
2
+ //
3
+ // import * as pg from 'pg'
4
+ //
5
+ // will crash. This is difficult to discover, since it only happens
6
+ // when being imported from our esm build.
1
7
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
8
  // @ts-ignore
3
9
  import pg from 'pg';
@@ -1,3 +1,9 @@
1
+ // after building for esm, importing pg using the following:
2
+ //
3
+ // import * as pg from 'pg'
4
+ //
5
+ // will crash. This is difficult to discover, since it only happens
6
+ // when being imported from our esm build.
1
7
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
8
  // @ts-ignore
3
9
  import pg from 'pg';
@@ -1045,6 +1045,17 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1045
1045
  */
1046
1046
  private applyablePreloadOnStatements;
1047
1047
  private conditionallyApplyDefaultScopes;
1048
+ /**
1049
+ * Each association in the chain is pushed onto `throughAssociations`
1050
+ * and `applyOneJoin` is recursively called. The trick is that the
1051
+ * through associations don't get written into the SQL; they
1052
+ * locate the next association we need to build into the SQL,
1053
+ * which is only run by the association that started the `through`
1054
+ * chain. The final association at the end of the `through` chain _is_
1055
+ * written into the SQL as a full association, but the modifications from
1056
+ * the `through` association are only added when the recursion returns
1057
+ * back to the association that kicked off the through associations.
1058
+ */
1048
1059
  private joinsBridgeThroughAssociations;
1049
1060
  private applyOneJoin;
1050
1061
  private applyAssociationOnStatementsToJoinStatement;
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html class="default" lang="en"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Benchmark | @rvoh/dream</title><meta name="description" content="Documentation for @rvoh/dream"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">@rvoh/dream</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">@rvoh/dream</a></li><li><a href="Benchmark.html">Benchmark</a></li></ul><h1>Class Benchmark</h1></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/8f1ff94e72666919099afe9aa29c570ae553422d/src/helpers/benchmark.ts#L6">src/helpers/benchmark.ts:6</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Constructors</h3><div class="tsd-index-list"><a href="Benchmark.html#constructor" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a>
1
+ <!DOCTYPE html><html class="default" lang="en"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Benchmark | @rvoh/dream</title><meta name="description" content="Documentation for @rvoh/dream"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">@rvoh/dream</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">@rvoh/dream</a></li><li><a href="Benchmark.html">Benchmark</a></li></ul><h1>Class Benchmark</h1></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/0489589271d20046be13267aaff5a27cc2cfc18c/src/helpers/benchmark.ts#L6">src/helpers/benchmark.ts:6</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Constructors</h3><div class="tsd-index-list"><a href="Benchmark.html#constructor" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a>
2
2
  </div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Methods</h3><div class="tsd-index-list"><a href="Benchmark.html#mark" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>mark</span></a>
3
3
  <a href="Benchmark.html#start" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>start</span></a>
4
- </div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Constructors"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Constructors</h2></summary><section><section class="tsd-panel tsd-member"><a id="constructor" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>constructor</span><a href="#constructor" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="constructor.new_Benchmark" class="tsd-anchor"></a><span class="tsd-kind-constructor-signature">new <wbr/>Benchmark</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="Benchmark.html" class="tsd-signature-type tsd-kind-class">Benchmark</a><a href="#constructor.new_Benchmark" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><h4 class="tsd-returns-title">Returns <a href="Benchmark.html" class="tsd-signature-type tsd-kind-class">Benchmark</a></h4></li></ul></section></section></details><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Methods"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Methods</h2></summary><section><section class="tsd-panel tsd-member"><a id="mark" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>mark</span><a href="#mark" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="mark.mark-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">mark</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">message</span>, <span class="tsd-kind-parameter">level</span><span class="tsd-signature-symbol">?</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span><a href="#mark.mark-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">message</span>: <span class="tsd-signature-type">string</span></span></li><li><span><span class="tsd-kind-parameter">level</span>: <span class="tsd-signature-type">BenchmarkLogLevel</span><span class="tsd-signature-symbol"> = &#39;log&#39;</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/8f1ff94e72666919099afe9aa29c570ae553422d/src/helpers/benchmark.ts#L12">src/helpers/benchmark.ts:12</a></li></ul></aside></li></ul></section><section class="tsd-panel tsd-member"><a id="start" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>start</span><a href="#start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="start.start-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">start</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span><a href="#start.start-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/8f1ff94e72666919099afe9aa29c570ae553422d/src/helpers/benchmark.ts#L8">src/helpers/benchmark.ts:8</a></li></ul></aside></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="tsd-otp-Constructors"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Constructors</summary><div><a href="#constructor" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="tsd-otp-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#mark" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>mark</span></a><a href="#start" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>start</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1"></use></svg><span>@rvoh/dream</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base=".."><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
4
+ </div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Constructors"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Constructors</h2></summary><section><section class="tsd-panel tsd-member"><a id="constructor" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>constructor</span><a href="#constructor" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="constructor.new_Benchmark" class="tsd-anchor"></a><span class="tsd-kind-constructor-signature">new <wbr/>Benchmark</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="Benchmark.html" class="tsd-signature-type tsd-kind-class">Benchmark</a><a href="#constructor.new_Benchmark" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><h4 class="tsd-returns-title">Returns <a href="Benchmark.html" class="tsd-signature-type tsd-kind-class">Benchmark</a></h4></li></ul></section></section></details><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Methods"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Methods</h2></summary><section><section class="tsd-panel tsd-member"><a id="mark" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>mark</span><a href="#mark" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="mark.mark-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">mark</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">message</span>, <span class="tsd-kind-parameter">level</span><span class="tsd-signature-symbol">?</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span><a href="#mark.mark-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">message</span>: <span class="tsd-signature-type">string</span></span></li><li><span><span class="tsd-kind-parameter">level</span>: <span class="tsd-signature-type">BenchmarkLogLevel</span><span class="tsd-signature-symbol"> = &#39;log&#39;</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/0489589271d20046be13267aaff5a27cc2cfc18c/src/helpers/benchmark.ts#L12">src/helpers/benchmark.ts:12</a></li></ul></aside></li></ul></section><section class="tsd-panel tsd-member"><a id="start" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>start</span><a href="#start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="start.start-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">start</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span><a href="#start.start-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/rvohealth/dream/blob/0489589271d20046be13267aaff5a27cc2cfc18c/src/helpers/benchmark.ts#L8">src/helpers/benchmark.ts:8</a></li></ul></aside></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="tsd-otp-Constructors"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Constructors</summary><div><a href="#constructor" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="tsd-otp-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#mark" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>mark</span></a><a href="#start" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>start</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1"></use></svg><span>@rvoh/dream</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base=".."><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>