velocious 1.0.474 → 1.0.476

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 (141) hide show
  1. package/README.md +10 -2
  2. package/build/configuration-types.js +39 -1
  3. package/build/configuration.js +46 -1
  4. package/build/database/drivers/base.js +67 -3
  5. package/build/database/drivers/mssql/index.js +13 -0
  6. package/build/database/drivers/mssql/sql/remove-index.js +6 -0
  7. package/build/database/drivers/mysql/index.js +87 -7
  8. package/build/database/drivers/mysql/sql/remove-index.js +6 -0
  9. package/build/database/drivers/pgsql/index.js +13 -0
  10. package/build/database/drivers/pgsql/sql/remove-index.js +6 -0
  11. package/build/database/drivers/sqlite/base.js +13 -0
  12. package/build/database/drivers/sqlite/connection-sql-js.js +16 -5
  13. package/build/database/drivers/sqlite/index.web.js +29 -15
  14. package/build/database/drivers/sqlite/sql/remove-index.js +6 -0
  15. package/build/database/drivers/sqlite/web-persistence.js +521 -0
  16. package/build/database/migration/index.js +44 -0
  17. package/build/database/pool/base-methods-forward.js +1 -0
  18. package/build/database/query/remove-index-base.js +39 -0
  19. package/build/database/record/index.js +25 -9
  20. package/build/environment-handlers/node/cli/commands/generate/base-models.js +36 -0
  21. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +63 -0
  22. package/build/frontend-model-controller.js +401 -4
  23. package/build/frontend-model-resource/base-resource.js +5 -1
  24. package/build/frontend-models/base.js +146 -2
  25. package/build/frontend-models/query.js +3 -3
  26. package/build/frontend-models/resource-definition.js +304 -2
  27. package/build/routes/hooks/frontend-model-command-route-hook.js +16 -0
  28. package/build/src/configuration-types.d.ts +118 -2
  29. package/build/src/configuration-types.d.ts.map +1 -1
  30. package/build/src/configuration-types.js +36 -2
  31. package/build/src/configuration.d.ts +18 -1
  32. package/build/src/configuration.d.ts.map +1 -1
  33. package/build/src/configuration.js +42 -2
  34. package/build/src/database/drivers/base.d.ts +50 -0
  35. package/build/src/database/drivers/base.d.ts.map +1 -1
  36. package/build/src/database/drivers/base.js +62 -4
  37. package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
  38. package/build/src/database/drivers/mssql/index.js +12 -1
  39. package/build/src/database/drivers/mssql/sql/remove-index.d.ts +4 -0
  40. package/build/src/database/drivers/mssql/sql/remove-index.d.ts.map +1 -0
  41. package/build/src/database/drivers/mssql/sql/remove-index.js +5 -0
  42. package/build/src/database/drivers/mysql/index.d.ts +32 -3
  43. package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
  44. package/build/src/database/drivers/mysql/index.js +76 -7
  45. package/build/src/database/drivers/mysql/sql/remove-index.d.ts +4 -0
  46. package/build/src/database/drivers/mysql/sql/remove-index.d.ts.map +1 -0
  47. package/build/src/database/drivers/mysql/sql/remove-index.js +5 -0
  48. package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
  49. package/build/src/database/drivers/pgsql/index.js +12 -1
  50. package/build/src/database/drivers/pgsql/sql/remove-index.d.ts +4 -0
  51. package/build/src/database/drivers/pgsql/sql/remove-index.d.ts.map +1 -0
  52. package/build/src/database/drivers/pgsql/sql/remove-index.js +5 -0
  53. package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
  54. package/build/src/database/drivers/sqlite/base.js +12 -1
  55. package/build/src/database/drivers/sqlite/connection-sql-js.d.ts +8 -1
  56. package/build/src/database/drivers/sqlite/connection-sql-js.d.ts.map +1 -1
  57. package/build/src/database/drivers/sqlite/connection-sql-js.js +15 -6
  58. package/build/src/database/drivers/sqlite/index.web.d.ts +5 -5
  59. package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
  60. package/build/src/database/drivers/sqlite/index.web.js +27 -13
  61. package/build/src/database/drivers/sqlite/sql/remove-index.d.ts +4 -0
  62. package/build/src/database/drivers/sqlite/sql/remove-index.d.ts.map +1 -0
  63. package/build/src/database/drivers/sqlite/sql/remove-index.js +5 -0
  64. package/build/src/database/drivers/sqlite/web-persistence.d.ts +77 -0
  65. package/build/src/database/drivers/sqlite/web-persistence.d.ts.map +1 -0
  66. package/build/src/database/drivers/sqlite/web-persistence.js +464 -0
  67. package/build/src/database/migration/index.d.ts +25 -0
  68. package/build/src/database/migration/index.d.ts.map +1 -1
  69. package/build/src/database/migration/index.js +39 -1
  70. package/build/src/database/pool/base-methods-forward.d.ts.map +1 -1
  71. package/build/src/database/pool/base-methods-forward.js +2 -1
  72. package/build/src/database/query/remove-index-base.d.ts +35 -0
  73. package/build/src/database/query/remove-index-base.d.ts.map +1 -0
  74. package/build/src/database/query/remove-index-base.js +34 -0
  75. package/build/src/database/record/index.d.ts +11 -0
  76. package/build/src/database/record/index.d.ts.map +1 -1
  77. package/build/src/database/record/index.js +26 -11
  78. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +15 -0
  79. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  80. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +33 -1
  81. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +30 -0
  82. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  83. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +53 -1
  84. package/build/src/frontend-model-controller.d.ts +96 -0
  85. package/build/src/frontend-model-controller.d.ts.map +1 -1
  86. package/build/src/frontend-model-controller.js +359 -5
  87. package/build/src/frontend-model-resource/base-resource.d.ts +4 -2
  88. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  89. package/build/src/frontend-model-resource/base-resource.js +7 -2
  90. package/build/src/frontend-models/base.d.ts +29 -0
  91. package/build/src/frontend-models/base.d.ts.map +1 -1
  92. package/build/src/frontend-models/base.js +131 -3
  93. package/build/src/frontend-models/query.js +4 -4
  94. package/build/src/frontend-models/resource-definition.d.ts +6 -0
  95. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  96. package/build/src/frontend-models/resource-definition.js +272 -3
  97. package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts.map +1 -1
  98. package/build/src/routes/hooks/frontend-model-command-route-hook.js +15 -1
  99. package/build/src/sync/device-identity.d.ts +240 -0
  100. package/build/src/sync/device-identity.d.ts.map +1 -0
  101. package/build/src/sync/device-identity.js +454 -0
  102. package/build/src/sync/local-mutation-log.d.ts +212 -0
  103. package/build/src/sync/local-mutation-log.d.ts.map +1 -0
  104. package/build/src/sync/local-mutation-log.js +404 -0
  105. package/build/src/sync/offline-grant.d.ts +157 -0
  106. package/build/src/sync/offline-grant.d.ts.map +1 -0
  107. package/build/src/sync/offline-grant.js +292 -0
  108. package/build/sync/device-identity.js +503 -0
  109. package/build/sync/local-mutation-log.js +448 -0
  110. package/build/sync/offline-grant.js +327 -0
  111. package/build/tsconfig.tsbuildinfo +1 -1
  112. package/package.json +3 -3
  113. package/src/configuration-types.js +39 -1
  114. package/src/configuration.js +46 -1
  115. package/src/database/drivers/base.js +67 -3
  116. package/src/database/drivers/mssql/index.js +13 -0
  117. package/src/database/drivers/mssql/sql/remove-index.js +6 -0
  118. package/src/database/drivers/mysql/index.js +87 -7
  119. package/src/database/drivers/mysql/sql/remove-index.js +6 -0
  120. package/src/database/drivers/pgsql/index.js +13 -0
  121. package/src/database/drivers/pgsql/sql/remove-index.js +6 -0
  122. package/src/database/drivers/sqlite/base.js +13 -0
  123. package/src/database/drivers/sqlite/connection-sql-js.js +16 -5
  124. package/src/database/drivers/sqlite/index.web.js +29 -15
  125. package/src/database/drivers/sqlite/sql/remove-index.js +6 -0
  126. package/src/database/drivers/sqlite/web-persistence.js +521 -0
  127. package/src/database/migration/index.js +44 -0
  128. package/src/database/pool/base-methods-forward.js +1 -0
  129. package/src/database/query/remove-index-base.js +39 -0
  130. package/src/database/record/index.js +25 -9
  131. package/src/environment-handlers/node/cli/commands/generate/base-models.js +36 -0
  132. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +63 -0
  133. package/src/frontend-model-controller.js +401 -4
  134. package/src/frontend-model-resource/base-resource.js +5 -1
  135. package/src/frontend-models/base.js +146 -2
  136. package/src/frontend-models/query.js +3 -3
  137. package/src/frontend-models/resource-definition.js +304 -2
  138. package/src/routes/hooks/frontend-model-command-route-hook.js +16 -0
  139. package/src/sync/device-identity.js +503 -0
  140. package/src/sync/local-mutation-log.js +448 -0
  141. package/src/sync/offline-grant.js +327 -0
@@ -9,6 +9,12 @@
9
9
  * @property {boolean} [unique] - Whether the index should enforce uniqueness.
10
10
  * @property {string} tableName - Name of the table to add the index to.
11
11
  */
12
+ /**
13
+ * RemoveIndexSqlArgs type.
14
+ * @typedef {object} RemoveIndexSqlArgs
15
+ * @property {string} name - Index name to drop.
16
+ * @property {string} tableName - Name of the table the index belongs to.
17
+ */
12
18
  /**
13
19
  * DropTableSqlArgsType type.
14
20
  * @typedef {object} DropTableSqlArgsType
@@ -50,6 +56,7 @@
50
56
  * @property {string} [logName] - Query log subject.
51
57
  * @property {boolean} [logQuery] - Whether to log the query.
52
58
  * @property {boolean} [processListComment] - Whether to add process-list comments to the query.
59
+ * @property {boolean} [sessionTimeZone] - Whether to ensure the configured database session time zone before the query.
53
60
  * @property {string} [sourceStack] - Stack captured at the caller boundary.
54
61
  */
55
62
 
@@ -237,6 +244,14 @@ export default class VelociousDatabaseDriversBase {
237
244
  // No-op by default
238
245
  }
239
246
 
247
+ /**
248
+ * Flushes pending writes that the driver delayed for persistence.
249
+ * @returns {Promise<void>} - Resolves when pending writes are durable.
250
+ */
251
+ async flushPendingWrites() {
252
+ // No-op by default
253
+ }
254
+
240
255
  /**
241
256
  * Runs set connection checkout name.
242
257
  * @param {string | undefined} name - Human-readable name for this active checkout.
@@ -298,6 +313,16 @@ export default class VelociousDatabaseDriversBase {
298
313
  throw new Error("'createIndexSQLs' not implemented")
299
314
  }
300
315
 
316
+ /**
317
+ * Runs remove index sqls.
318
+ * @abstract
319
+ * @param {RemoveIndexSqlArgs} indexData - Index data.
320
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
321
+ */
322
+ async removeIndexSQLs(indexData) { // eslint-disable-line no-unused-vars
323
+ throw new Error("'removeIndexSQLs' not implemented")
324
+ }
325
+
301
326
  /**
302
327
  * Runs create table.
303
328
  * @param {import("../table-data/index.js").default} tableData - Table data.
@@ -1041,12 +1066,14 @@ export default class VelociousDatabaseDriversBase {
1041
1066
  let result
1042
1067
 
1043
1068
  try {
1069
+ const runQueryActualWithHooks = async () => await this._queryActualWithHooks(querySql, options)
1070
+
1044
1071
  if (requestTiming && tries === 1) {
1045
- result = await requestTiming.measureDbQuery(async () => await this._queryActual(querySql))
1072
+ result = await requestTiming.measureDbQuery(runQueryActualWithHooks)
1046
1073
  } else if (requestTiming) {
1047
- result = await requestTiming.measure("db", async () => await this._queryActual(querySql))
1074
+ result = await requestTiming.measure("db", runQueryActualWithHooks)
1048
1075
  } else {
1049
- result = await this._queryActual(querySql)
1076
+ result = await runQueryActualWithHooks()
1050
1077
  }
1051
1078
  } finally {
1052
1079
  this._activeQuery = previousActiveQuery
@@ -1070,6 +1097,42 @@ export default class VelociousDatabaseDriversBase {
1070
1097
  return result
1071
1098
  }
1072
1099
 
1100
+ /**
1101
+ * Runs query actual with before/after hooks.
1102
+ * @param {string} sql - SQL string.
1103
+ * @param {QueryOptions} options - Query options.
1104
+ * @returns {Promise<QueryResultType>} - Resolves with the query.
1105
+ */
1106
+ async _queryActualWithHooks(sql, options) {
1107
+ await this.beforeQuery(sql, options)
1108
+
1109
+ try {
1110
+ return await this._queryActual(sql)
1111
+ } finally {
1112
+ await this.afterQuery(sql, options)
1113
+ }
1114
+ }
1115
+
1116
+ /**
1117
+ * Hook that runs immediately before a SQL query is sent to the driver.
1118
+ * @param {string} _sql - SQL string.
1119
+ * @param {QueryOptions} _options - Query options.
1120
+ * @returns {Promise<void>} - Resolves when complete.
1121
+ */
1122
+ async beforeQuery(_sql, _options) {
1123
+ // No-op by default
1124
+ }
1125
+
1126
+ /**
1127
+ * Hook that runs immediately after a SQL query has completed or failed.
1128
+ * @param {string} _sql - SQL string.
1129
+ * @param {QueryOptions} _options - Query options.
1130
+ * @returns {Promise<void>} - Resolves when complete.
1131
+ */
1132
+ async afterQuery(_sql, _options) {
1133
+ // No-op by default
1134
+ }
1135
+
1073
1136
  /**
1074
1137
  * Runs get debug snapshot.
1075
1138
  * @returns {DatabaseConnectionDebugSnapshot} - Diagnostic snapshot for this connection.
@@ -1504,6 +1567,7 @@ export default class VelociousDatabaseDriversBase {
1504
1567
  }
1505
1568
  }
1506
1569
  })
1570
+ await this.flushPendingWrites()
1507
1571
  }
1508
1572
 
1509
1573
  /**
@@ -15,6 +15,7 @@ import Options from "./options.js"
15
15
  import mssql from "mssql"
16
16
  import net from "node:net"
17
17
  import QueryParser from "./query-parser.js"
18
+ import RemoveIndex from "./sql/remove-index.js"
18
19
  import Table from "./table.js"
19
20
  import StructureSql from "./structure-sql.js"
20
21
  import timeout from "awaitery/build/timeout.js"
@@ -113,6 +114,18 @@ export default class VelociousDatabaseDriversMssql extends Base{
113
114
  return await createIndex.toSQLs()
114
115
  }
115
116
 
117
+ /**
118
+ * Runs remove index sqls.
119
+ * @param {import("../base.js").RemoveIndexSqlArgs} indexData - Index data.
120
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
121
+ */
122
+ async removeIndexSQLs(indexData) {
123
+ const removeArgs = Object.assign({driver: this}, indexData)
124
+ const removeIndex = new RemoveIndex(removeArgs)
125
+
126
+ return await removeIndex.toSQLs()
127
+ }
128
+
116
129
  /**
117
130
  * Runs create table sql.
118
131
  * @param {import("../../table-data/index.js").default} tableData - Table data.
@@ -0,0 +1,6 @@
1
+ // @ts-check
2
+
3
+ import RemoveIndexBase from "../../../query/remove-index-base.js"
4
+
5
+ export default class VelociousDatabaseConnectionDriversMssqlSqlRemoveIndex extends RemoveIndexBase {
6
+ }
@@ -14,6 +14,7 @@ import Options from "./options.js"
14
14
  import mysql from "mysql"
15
15
  import query from "./query.js"
16
16
  import QueryParser from "./query-parser.js"
17
+ import RemoveIndex from "./sql/remove-index.js"
17
18
  import Table from "./table.js"
18
19
  import StructureSql from "./structure-sql.js"
19
20
  import Upsert from "./sql/upsert.js"
@@ -30,15 +31,20 @@ import Update from "./sql/update.js"
30
31
  const MYSQL_INDEFINITE_LOCK_TIMEOUT_SECONDS = 60 * 60 * 24 * 365
31
32
 
32
33
  export default class VelociousDatabaseDriversMysql extends Base{
34
+ /** @type {string | null} */
35
+ _desiredSessionTimeZone = "+00:00"
36
+
37
+ /** @type {string | null} */
38
+ _currentSessionTimeZone = null
39
+
33
40
  /**
34
41
  * Runs connect.
35
42
  * @returns {Promise<void>} - Resolves when complete.
36
43
  */
37
44
  async connect() {
45
+ this.resetCurrentSessionTimeZone()
38
46
  this.pool = mysql.createPool(Object.assign({connectionLimit: 1}, this.connectArgs()))
39
47
  this.pool.on("error", this.onPoolError)
40
-
41
- await this.setSessionTimezoneToUtc()
42
48
  }
43
49
 
44
50
  /**
@@ -56,6 +62,7 @@ export default class VelociousDatabaseDriversMysql extends Base{
56
62
  async close() {
57
63
  await this.pool?.end()
58
64
  this.pool = undefined
65
+ this.resetCurrentSessionTimeZone()
59
66
  }
60
67
 
61
68
  /**
@@ -64,7 +71,7 @@ export default class VelociousDatabaseDriversMysql extends Base{
64
71
  * @returns {Promise<void>} - Resolves when complete.
65
72
  */
66
73
  async setConnectionCheckoutName(name) {
67
- await this.query(`SET @velocious_connection_checkout_name = ${name === undefined ? "NULL" : this.quote(name)}`, {logName: "Set Connection Checkout Name", processListComment: false})
74
+ await this.query(`SET @velocious_connection_checkout_name = ${name === undefined ? "NULL" : this.quote(name)}`, {logName: "Set Connection Checkout Name", processListComment: false, sessionTimeZone: false})
68
75
  await super.setConnectionCheckoutName(name)
69
76
  }
70
77
 
@@ -73,16 +80,77 @@ export default class VelociousDatabaseDriversMysql extends Base{
73
80
  * @returns {Promise<void>} - Resolves when complete.
74
81
  */
75
82
  async clearConnectionCheckoutName() {
76
- await this.query("SET @velocious_connection_checkout_name = NULL", {logName: "Clear Connection Checkout Name", processListComment: false})
83
+ await this.query("SET @velocious_connection_checkout_name = NULL", {logName: "Clear Connection Checkout Name", processListComment: false, sessionTimeZone: false})
77
84
  await super.clearConnectionCheckoutName()
78
85
  }
79
86
 
80
87
  /**
81
- * Sets the database session timezone to UTC so bare timestamp literals store UTC instants.
88
+ * Hook before every query.
89
+ * @param {string} _sql - SQL string.
90
+ * @param {import("../base.js").QueryOptions} options - Query options.
82
91
  * @returns {Promise<void>} - Resolves when complete.
83
92
  */
84
- async setSessionTimezoneToUtc() {
85
- await this.query("SET time_zone = '+00:00'", {logName: "Set Session Time Zone", processListComment: false})
93
+ async beforeQuery(_sql, options) {
94
+ if (options.sessionTimeZone !== false) await this.ensureSessionTimeZone()
95
+ }
96
+
97
+ /**
98
+ * Gets the desired database session time zone for this connection context.
99
+ * @returns {string | null} - Desired session time zone.
100
+ */
101
+ getDesiredSessionTimeZone() {
102
+ return this._desiredSessionTimeZone
103
+ }
104
+
105
+ /**
106
+ * Sets the desired database session time zone without querying MySQL immediately.
107
+ * @param {string | null} timeZone - Desired session time zone.
108
+ */
109
+ setDesiredSessionTimeZone(timeZone) {
110
+ this._desiredSessionTimeZone = timeZone
111
+ }
112
+
113
+ /**
114
+ * Gets the database session time zone last confirmed through SET time_zone.
115
+ * @returns {string | null} - Current known session time zone.
116
+ */
117
+ getCurrentSessionTimeZone() {
118
+ return this._currentSessionTimeZone
119
+ }
120
+
121
+ /**
122
+ * Clears the current known database session time zone when the physical connection changes.
123
+ */
124
+ resetCurrentSessionTimeZone() {
125
+ this._currentSessionTimeZone = null
126
+ }
127
+
128
+ /**
129
+ * Ensures MySQL has the desired session time zone before user SQL runs.
130
+ * @returns {Promise<boolean>} - True when SET time_zone was executed.
131
+ */
132
+ async ensureSessionTimeZone() {
133
+ const desiredSessionTimeZone = this.getDesiredSessionTimeZone()
134
+
135
+ if (desiredSessionTimeZone === null || this.getCurrentSessionTimeZone() === desiredSessionTimeZone) return false
136
+
137
+ await this.setSessionTimeZone(desiredSessionTimeZone)
138
+
139
+ return true
140
+ }
141
+
142
+ /**
143
+ * Sets the database session time zone if it changed from the last confirmed value.
144
+ * @param {string} timeZone - Session time zone value accepted by MySQL.
145
+ * @returns {Promise<boolean>} - True when SET time_zone was executed.
146
+ */
147
+ async setSessionTimeZone(timeZone) {
148
+ if (this.getCurrentSessionTimeZone() === timeZone) return false
149
+
150
+ await this._queryActual(`SET time_zone = ${this.quote(timeZone)}`)
151
+ this._currentSessionTimeZone = timeZone
152
+
153
+ return true
86
154
  }
87
155
 
88
156
  /**
@@ -160,6 +228,18 @@ export default class VelociousDatabaseDriversMysql extends Base{
160
228
  return await createIndex.toSQLs()
161
229
  }
162
230
 
231
+ /**
232
+ * Runs remove index sqls.
233
+ * @param {import("../base.js").RemoveIndexSqlArgs} indexData - Index data.
234
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
235
+ */
236
+ async removeIndexSQLs(indexData) {
237
+ const removeArgs = Object.assign({driver: this}, indexData)
238
+ const removeIndex = new RemoveIndex(removeArgs)
239
+
240
+ return await removeIndex.toSQLs()
241
+ }
242
+
163
243
  /**
164
244
  * Runs create table sql.
165
245
  * @param {import("../../table-data/index.js").default} tableData - Table data.
@@ -0,0 +1,6 @@
1
+ // @ts-check
2
+
3
+ import RemoveIndexBase from "../../../query/remove-index-base.js"
4
+
5
+ export default class VelociousDatabaseConnectionDriversMysqlSqlRemoveIndex extends RemoveIndexBase {
6
+ }
@@ -14,6 +14,7 @@ import DropTable from "./sql/drop-table.js"
14
14
  import Insert from "./sql/insert.js"
15
15
  import Options from "./options.js"
16
16
  import QueryParser from "./query-parser.js"
17
+ import RemoveIndex from "./sql/remove-index.js"
17
18
  import Table from "./table.js"
18
19
  import StructureSql from "./structure-sql.js"
19
20
  import Upsert from "./sql/upsert.js"
@@ -149,6 +150,18 @@ export default class VelociousDatabaseDriversPgsql extends Base{
149
150
  return await createIndex.toSQLs()
150
151
  }
151
152
 
153
+ /**
154
+ * Runs remove index sqls.
155
+ * @param {import("../base.js").RemoveIndexSqlArgs} indexData - Index data.
156
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
157
+ */
158
+ async removeIndexSQLs(indexData) {
159
+ const removeArgs = Object.assign({driver: this}, indexData)
160
+ const removeIndex = new RemoveIndex(removeArgs)
161
+
162
+ return await removeIndex.toSQLs()
163
+ }
164
+
152
165
  /**
153
166
  * Runs create table sql.
154
167
  * @param {import("../../table-data/index.js").default} tableData - Table data.
@@ -0,0 +1,6 @@
1
+ // @ts-check
2
+
3
+ import RemoveIndexBase from "../../../query/remove-index-base.js"
4
+
5
+ export default class VelociousDatabaseConnectionDriversPgsqlSqlRemoveIndex extends RemoveIndexBase {
6
+ }
@@ -12,6 +12,7 @@ import escapeString from "sql-escape-string"
12
12
  import Insert from "./sql/insert.js"
13
13
  import Options from "./options.js"
14
14
  import QueryParser from "./query-parser.js"
15
+ import RemoveIndex from "./sql/remove-index.js"
15
16
  import Table from "./table.js"
16
17
  import StructureSql from "./structure-sql.js"
17
18
  import Upsert from "./sql/upsert.js"
@@ -55,6 +56,18 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
55
56
  return await createIndex.toSQLs()
56
57
  }
57
58
 
59
+ /**
60
+ * Runs remove index sqls.
61
+ * @param {import("../base.js").RemoveIndexSqlArgs} indexData - Index data.
62
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
63
+ */
64
+ async removeIndexSQLs(indexData) {
65
+ const removeArgs = Object.assign({driver: this}, indexData)
66
+ const removeIndex = new RemoveIndex(removeArgs)
67
+
68
+ return await removeIndex.toSQLs()
69
+ }
70
+
58
71
  /**
59
72
  * Runs create table sql.
60
73
  * @abstract
@@ -8,16 +8,28 @@ export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
8
8
  * Runs constructor.
9
9
  * @param {import("../base.js").default} driver - Database driver instance.
10
10
  * @param {import("sql.js").Database} connection - Connection.
11
+ * @param {import("./web-persistence.js").SqliteWebPersistence} persistence - Database persistence adapter.
11
12
  */
12
- constructor(driver, connection) {
13
+ constructor(driver, connection, persistence) {
13
14
  this.connection = connection
14
15
  this.driver = driver
16
+ this.persistence = persistence
15
17
  }
16
18
 
17
19
  async close() {
18
- await this.saveDatabase()
20
+ await this.flushDatabaseSave()
19
21
  await this.connection.close()
20
22
  }
23
+
24
+ /**
25
+ * Flushes any debounced database save and waits until persistence is complete.
26
+ * @returns {Promise<void>} - Resolves when the current database bytes are stored.
27
+ */
28
+ async flushDatabaseSave() {
29
+ this.saveDatabaseDebounce.clear()
30
+ await this.saveDatabase()
31
+ }
32
+
21
33
  /**
22
34
  * Runs query.
23
35
  * @param {string} sql - SQL string.
@@ -36,10 +48,9 @@ export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
36
48
  }
37
49
 
38
50
  saveDatabase = async () => {
39
- const localStorageContent = this.connection.export()
51
+ const databaseContent = this.connection.export()
40
52
 
41
- // @ts-expect-error
42
- await this.driver.betterLocalStorage.set(this.driver.localStorageName(), localStorageContent)
53
+ await this.persistence.save(databaseContent)
43
54
  }
44
55
 
45
56
  saveDatabaseDebounce = debounce(this.saveDatabase, 500)
@@ -1,8 +1,8 @@
1
1
  // @ts-check
2
2
 
3
- import BetterLocalStorage from "better-localstorage"
4
3
  import ConnectionSqlJs from "./connection-sql-js.js"
5
4
  import initSqlJs from "sql.js"
5
+ import {createSqliteWebPersistence, deleteSqliteWebPersistences, sqliteWebPersistenceKey} from "./web-persistence.js"
6
6
 
7
7
  import Base from "./base.js"
8
8
 
@@ -12,10 +12,6 @@ import Base from "./base.js"
12
12
  */
13
13
 
14
14
  export default class VelociousDatabaseDriversSqliteWeb extends Base {
15
- /**
16
- * Better local storage.
17
- * @type {BetterLocalStorage | undefined} */
18
- betterLocalStorage = undefined
19
15
  /**
20
16
  * Connection.
21
17
  * @type {ConnectionSqlJs | undefined} */
@@ -39,16 +35,14 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
39
35
  this.args = this.getArgs()
40
36
 
41
37
  if (!this.args.getConnection) {
42
- this.betterLocalStorage ||= new BetterLocalStorage()
43
-
44
38
  if (this.args.reset) {
45
- await this.betterLocalStorage.delete(this.localStorageName())
39
+ await deleteSqliteWebPersistences({databaseName: this.databaseName()})
46
40
  }
47
41
 
42
+ const persistence = await createSqliteWebPersistence({databaseName: this.databaseName()})
48
43
  const SQL = await initSqlJs({locateFile: this.sqlJsLocateFile()})
49
-
50
- const databaseContent = await this.betterLocalStorage.get(this.localStorageName())
51
- const connectionSqlJs = new ConnectionSqlJs(this, new SQL.Database(databaseContent))
44
+ const databaseContent = await persistence.load()
45
+ const connectionSqlJs = new ConnectionSqlJs(this, new SQL.Database(databaseContent), persistence)
52
46
 
53
47
  this._connection = connectionSqlJs
54
48
  }
@@ -58,6 +52,18 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
58
52
  await this.getConnection().close()
59
53
  }
60
54
 
55
+ /**
56
+ * Flushes pending SQL.js local persistence writes.
57
+ * @returns {Promise<void>} - Resolves when pending writes are durable.
58
+ */
59
+ async flushPendingWrites() {
60
+ if (!this.args?.getConnection) {
61
+ if (!this._connection) throw new Error("SQLite web connection has not been initialized")
62
+
63
+ await this._connection.flushDatabaseSave()
64
+ }
65
+ }
66
+
61
67
  /**
62
68
  * Runs get connection.
63
69
  * @returns {ConnectionSqlJs | SqliteWebConnection} - The connection.
@@ -72,11 +78,19 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
72
78
  }
73
79
 
74
80
  localStorageName() {
75
- if (!this.args?.name) {
76
- throw new Error("No name given in arguments for SQLite Web database")
77
- }
81
+ return sqliteWebPersistenceKey(this.databaseName())
82
+ }
83
+
84
+ /**
85
+ * Returns the configured database name.
86
+ * @returns {string} - Database name.
87
+ */
88
+ databaseName() {
89
+ const name = this.args?.name
90
+
91
+ if (typeof name !== "string" || name.length < 1) throw new Error("No name given in arguments for SQLite Web database")
78
92
 
79
- return `VelociousDatabaseDriversSqliteWeb---${this.args?.name}`
93
+ return name
80
94
  }
81
95
 
82
96
  /**
@@ -0,0 +1,6 @@
1
+ // @ts-check
2
+
3
+ import RemoveIndexBase from "../../../query/remove-index-base.js"
4
+
5
+ export default class VelociousDatabaseConnectionDriversSqliteSqlRemoveIndex extends RemoveIndexBase {
6
+ }