@restura/core 1.0.3 → 1.0.4

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/dist/index.d.ts CHANGED
@@ -1059,9 +1059,13 @@ declare class PsqlEngine extends SqlEngine {
1059
1059
  setupTriggerListeners: Promise<void> | undefined;
1060
1060
  private triggerClient;
1061
1061
  private scratchDbName;
1062
+ private reconnectAttempts;
1063
+ private readonly MAX_RECONNECT_ATTEMPTS;
1064
+ private readonly INITIAL_RECONNECT_DELAY;
1062
1065
  constructor(psqlConnectionPool: PsqlPool, shouldListenForDbTriggers?: boolean, scratchDatabaseSuffix?: string);
1063
1066
  close(): Promise<void>;
1064
1067
  private setupPgReturnTypes;
1068
+ private reconnectTriggerClient;
1065
1069
  private listenForDbTriggers;
1066
1070
  private handleTrigger;
1067
1071
  createDatabaseFromSchema(schema: ResturaSchema, connection: PsqlPool): Promise<string>;
@@ -1140,4 +1144,4 @@ declare function isValueNumber(value: unknown): value is number;
1140
1144
  */
1141
1145
  declare function SQL(strings: TemplateStringsArray, ...values: unknown[]): string;
1142
1146
 
1143
- export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticatedRequesterDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoggerConfigSchema, type MatchTypes, type MutationType, type OnValidAuthenticationCallback, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type QueryMetadata, type RequesterDetails, type ResturaConfigSchema, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, apiGenerator, escapeColumnName, eventManager, filterPsqlParser, insertObjectQuery, isSchemaValid, isValueNumber, logger, modelGenerator, questionMarksToOrderedParams, restura, resturaGlobalTypesGenerator, updateObjectQuery };
1147
+ export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticatedRequesterDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoggerConfigSchema, type MatchTypes, type MutationType, type OnValidAuthenticationCallback, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type QueryMetadata, type RequesterDetails, type ResturaConfigSchema, type ResturaSchema, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, apiGenerator, escapeColumnName, eventManager, filterPsqlParser, insertObjectQuery, isSchemaValid, isValueNumber, logger, modelGenerator, questionMarksToOrderedParams, restura, resturaGlobalTypesGenerator, resturaSchema, updateObjectQuery };
package/dist/index.js CHANGED
@@ -2045,6 +2045,7 @@ var systemUser = {
2045
2045
  isSystemUser: true
2046
2046
  };
2047
2047
  var PsqlEngine = class extends SqlEngine {
2048
+ // 5 seconds
2048
2049
  constructor(psqlConnectionPool, shouldListenForDbTriggers = false, scratchDatabaseSuffix = "") {
2049
2050
  super();
2050
2051
  this.psqlConnectionPool = psqlConnectionPool;
@@ -2057,6 +2058,9 @@ var PsqlEngine = class extends SqlEngine {
2057
2058
  setupTriggerListeners;
2058
2059
  triggerClient;
2059
2060
  scratchDbName = "";
2061
+ reconnectAttempts = 0;
2062
+ MAX_RECONNECT_ATTEMPTS = 5;
2063
+ INITIAL_RECONNECT_DELAY = 5e3;
2060
2064
  async close() {
2061
2065
  if (this.triggerClient) {
2062
2066
  await this.triggerClient.end();
@@ -2072,6 +2076,34 @@ var PsqlEngine = class extends SqlEngine {
2072
2076
  return val === null ? null : Number(val);
2073
2077
  });
2074
2078
  }
2079
+ async reconnectTriggerClient() {
2080
+ if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
2081
+ logger.error("Max reconnection attempts reached for trigger client. Stopping reconnection attempts.");
2082
+ return;
2083
+ }
2084
+ if (this.triggerClient) {
2085
+ try {
2086
+ await this.triggerClient.end();
2087
+ } catch (error) {
2088
+ logger.error(`Error closing trigger client: ${error}`);
2089
+ }
2090
+ }
2091
+ const delay = this.INITIAL_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts);
2092
+ logger.info(
2093
+ `Attempting to reconnect trigger client in ${delay / 1e3} seconds... (Attempt ${this.reconnectAttempts + 1}/${this.MAX_RECONNECT_ATTEMPTS})`
2094
+ );
2095
+ await new Promise((resolve2) => setTimeout(resolve2, delay));
2096
+ this.reconnectAttempts++;
2097
+ try {
2098
+ await this.listenForDbTriggers();
2099
+ this.reconnectAttempts = 0;
2100
+ } catch (error) {
2101
+ logger.error(`Reconnection attempt ${this.reconnectAttempts} failed: ${error}`);
2102
+ if (this.reconnectAttempts < this.MAX_RECONNECT_ATTEMPTS) {
2103
+ await this.reconnectTriggerClient();
2104
+ }
2105
+ }
2106
+ }
2075
2107
  async listenForDbTriggers() {
2076
2108
  this.triggerClient = new Client({
2077
2109
  user: this.psqlConnectionPool.poolConfig.user,
@@ -2081,18 +2113,28 @@ var PsqlEngine = class extends SqlEngine {
2081
2113
  port: this.psqlConnectionPool.poolConfig.port,
2082
2114
  connectionTimeoutMillis: this.psqlConnectionPool.poolConfig.connectionTimeoutMillis
2083
2115
  });
2084
- await this.triggerClient.connect();
2085
- const promises = [];
2086
- promises.push(this.triggerClient.query("LISTEN insert"));
2087
- promises.push(this.triggerClient.query("LISTEN update"));
2088
- promises.push(this.triggerClient.query("LISTEN delete"));
2089
- await Promise.all(promises);
2090
- this.triggerClient.on("notification", async (msg) => {
2091
- if (msg.channel === "insert" || msg.channel === "update" || msg.channel === "delete") {
2092
- const payload = ObjectUtils4.safeParse(msg.payload);
2093
- await this.handleTrigger(payload, msg.channel.toUpperCase());
2094
- }
2095
- });
2116
+ try {
2117
+ await this.triggerClient.connect();
2118
+ const promises = [];
2119
+ promises.push(this.triggerClient.query("LISTEN insert"));
2120
+ promises.push(this.triggerClient.query("LISTEN update"));
2121
+ promises.push(this.triggerClient.query("LISTEN delete"));
2122
+ await Promise.all(promises);
2123
+ this.triggerClient.on("error", async (error) => {
2124
+ logger.error(`Trigger client error: ${error}`);
2125
+ await this.reconnectTriggerClient();
2126
+ });
2127
+ this.triggerClient.on("notification", async (msg) => {
2128
+ if (msg.channel === "insert" || msg.channel === "update" || msg.channel === "delete") {
2129
+ const payload = ObjectUtils4.safeParse(msg.payload);
2130
+ await this.handleTrigger(payload, msg.channel.toUpperCase());
2131
+ }
2132
+ });
2133
+ logger.info("Successfully connected to database triggers");
2134
+ } catch (error) {
2135
+ logger.error(`Failed to setup trigger listeners: ${error}`);
2136
+ await this.reconnectTriggerClient();
2137
+ }
2096
2138
  }
2097
2139
  async handleTrigger(payload, mutationType) {
2098
2140
  if (payload.queryMetadata && payload.queryMetadata.connectionInstanceId === this.psqlConnectionPool.instanceId) {
@@ -3232,6 +3274,7 @@ export {
3232
3274
  questionMarksToOrderedParams,
3233
3275
  restura,
3234
3276
  resturaGlobalTypesGenerator,
3277
+ resturaSchema,
3235
3278
  updateObjectQuery
3236
3279
  };
3237
3280
  //# sourceMappingURL=index.js.map