@hot-updater/server 1.0.0-rc.2 → 1.0.0-rc.21

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 (328) hide show
  1. package/LICENSE +12 -14
  2. package/dist/adapters/drizzle.cjs +32 -75
  3. package/dist/adapters/drizzle.d.cts +13 -5
  4. package/dist/adapters/drizzle.d.mts +13 -5
  5. package/dist/adapters/drizzle.mjs +32 -77
  6. package/dist/adapters/drizzleExecutor.cjs +114 -0
  7. package/dist/adapters/drizzleExecutor.d.cts +9 -0
  8. package/dist/adapters/drizzleExecutor.d.mts +9 -0
  9. package/dist/adapters/drizzleExecutor.mjs +112 -0
  10. package/dist/adapters/kysely.cjs +22 -31
  11. package/dist/adapters/kysely.d.cts +10 -6
  12. package/dist/adapters/kysely.d.mts +10 -6
  13. package/dist/adapters/kysely.mjs +23 -33
  14. package/dist/adapters/kyselyExecutor.cjs +32 -0
  15. package/dist/adapters/kyselyExecutor.d.cts +11 -0
  16. package/dist/adapters/kyselyExecutor.d.mts +11 -0
  17. package/dist/adapters/kyselyExecutor.mjs +32 -0
  18. package/dist/adapters/mongodb.cjs +18 -54
  19. package/dist/adapters/mongodb.d.cts +10 -5
  20. package/dist/adapters/mongodb.d.mts +10 -5
  21. package/dist/adapters/mongodb.mjs +19 -56
  22. package/dist/adapters/mongodbAdapter.cjs +192 -0
  23. package/dist/adapters/mongodbAdapter.d.cts +9 -0
  24. package/dist/adapters/mongodbAdapter.d.mts +9 -0
  25. package/dist/adapters/mongodbAdapter.mjs +191 -0
  26. package/dist/adapters/prisma.cjs +35 -267
  27. package/dist/adapters/prisma.d.cts +12 -7
  28. package/dist/adapters/prisma.d.mts +12 -7
  29. package/dist/adapters/prisma.mjs +36 -268
  30. package/dist/adapters/prismaExecutor.cjs +63 -0
  31. package/dist/adapters/prismaExecutor.mjs +63 -0
  32. package/dist/adapters/sqlProviders.cjs +14 -0
  33. package/dist/adapters/sqlProviders.mjs +14 -0
  34. package/dist/assembly/assemblePlugins.cjs +144 -0
  35. package/dist/assembly/assemblePlugins.d.cts +5 -0
  36. package/dist/assembly/assemblePlugins.d.mts +5 -0
  37. package/dist/assembly/assemblePlugins.mjs +139 -0
  38. package/dist/assembly/clientPlugins.cjs +88 -0
  39. package/dist/assembly/clientPlugins.mjs +88 -0
  40. package/dist/assembly/configError.d.cts +2 -0
  41. package/dist/assembly/configError.d.mts +2 -0
  42. package/dist/assembly/configError.mjs +2 -0
  43. package/dist/core/api.cjs +51 -0
  44. package/dist/core/api.d.cts +54 -0
  45. package/dist/core/api.d.mts +54 -0
  46. package/dist/core/api.mjs +51 -0
  47. package/dist/core/baseCandidates.cjs +28 -0
  48. package/dist/core/baseCandidates.mjs +28 -0
  49. package/dist/core/operations.cjs +351 -0
  50. package/dist/core/operations.mjs +351 -0
  51. package/dist/core/reads.cjs +273 -0
  52. package/dist/core/reads.d.cts +9 -0
  53. package/dist/core/reads.d.mts +9 -0
  54. package/dist/core/reads.mjs +267 -0
  55. package/dist/core/releases.cjs +193 -0
  56. package/dist/core/releases.mjs +190 -0
  57. package/dist/core/writes.cjs +96 -0
  58. package/dist/core/writes.mjs +91 -0
  59. package/dist/createHotUpdaterCore.cjs +72 -91
  60. package/dist/createHotUpdaterCore.d.cts +106 -38
  61. package/dist/createHotUpdaterCore.d.mts +106 -38
  62. package/dist/createHotUpdaterCore.mjs +74 -89
  63. package/dist/db/engineDrizzleSchema.cjs +53 -0
  64. package/dist/db/engineDrizzleSchema.mjs +53 -0
  65. package/dist/db/enginePrismaSchema.cjs +84 -0
  66. package/dist/db/enginePrismaSchema.d.cts +5 -0
  67. package/dist/db/enginePrismaSchema.d.mts +5 -0
  68. package/dist/db/enginePrismaSchema.mjs +83 -0
  69. package/dist/db/releaseCatalog.cjs +24 -47
  70. package/dist/db/releaseCatalog.mjs +20 -44
  71. package/dist/db/updateArtifacts.cjs +43 -72
  72. package/dist/db/updateArtifacts.mjs +40 -69
  73. package/dist/handler.cjs +59 -43
  74. package/dist/handler.d.cts +3 -5
  75. package/dist/handler.d.mts +3 -5
  76. package/dist/handler.mjs +61 -43
  77. package/dist/handlerAdminRoutes.cjs +374 -0
  78. package/dist/handlerAdminRoutes.mjs +372 -0
  79. package/dist/handlerParameters.cjs +6 -11
  80. package/dist/handlerParameters.mjs +6 -10
  81. package/dist/handlerReleaseCatalogRoutes.cjs +32 -15
  82. package/dist/handlerReleaseCatalogRoutes.mjs +32 -15
  83. package/dist/handlerTypes.d.cts +2 -55
  84. package/dist/handlerTypes.d.mts +2 -55
  85. package/dist/handlerVersionRoutes.cjs +20 -4
  86. package/dist/handlerVersionRoutes.mjs +20 -4
  87. package/dist/index.cjs +9 -9
  88. package/dist/index.d.cts +8 -9
  89. package/dist/index.d.mts +8 -9
  90. package/dist/index.mjs +3 -4
  91. package/dist/node.cjs +3 -6
  92. package/dist/node.d.cts +2 -2
  93. package/dist/node.d.mts +2 -2
  94. package/dist/node.mjs +4 -4
  95. package/dist/package.cjs +1 -1
  96. package/dist/package.mjs +1 -1
  97. package/dist/plugins/api-keys/index.cjs +9 -0
  98. package/dist/plugins/api-keys/index.d.cts +1 -0
  99. package/dist/plugins/api-keys/index.d.mts +1 -0
  100. package/dist/plugins/api-keys/index.mjs +2 -0
  101. package/dist/plugins/definePlugin.d.cts +2 -0
  102. package/dist/plugins/definePlugin.d.mts +2 -0
  103. package/dist/plugins/insights/index.cjs +9 -0
  104. package/dist/plugins/insights/index.d.cts +1 -0
  105. package/dist/plugins/insights/index.d.mts +1 -0
  106. package/dist/plugins/insights/index.mjs +2 -0
  107. package/dist/plugins/official.cjs +30 -0
  108. package/dist/plugins/official.mjs +29 -0
  109. package/dist/storageAccess.cjs +13 -10
  110. package/dist/storageAccess.mjs +13 -10
  111. package/dist/types/index.d.cts +2 -28
  112. package/dist/types/index.d.mts +2 -28
  113. package/package.json +26 -14
  114. package/dist/_virtual/_rolldown/runtime.cjs +0 -23
  115. package/dist/adapters/databaseConstraintErrors.cjs +0 -22
  116. package/dist/adapters/databaseConstraintErrors.mjs +0 -21
  117. package/dist/adapters/databasePluginUtils.cjs +0 -116
  118. package/dist/adapters/databasePluginUtils.mjs +0 -106
  119. package/dist/adapters/drizzleCrud.cjs +0 -311
  120. package/dist/adapters/drizzleCrud.mjs +0 -308
  121. package/dist/adapters/drizzleLazyDB.cjs +0 -106
  122. package/dist/adapters/drizzleLazyDB.mjs +0 -106
  123. package/dist/adapters/drizzleQuery.cjs +0 -69
  124. package/dist/adapters/drizzleQuery.mjs +0 -69
  125. package/dist/adapters/insightsTransaction.cjs +0 -22
  126. package/dist/adapters/insightsTransaction.mjs +0 -22
  127. package/dist/adapters/kyselyCrud.cjs +0 -305
  128. package/dist/adapters/kyselyCrud.mjs +0 -304
  129. package/dist/adapters/kyselyQuery.cjs +0 -56
  130. package/dist/adapters/kyselyQuery.mjs +0 -56
  131. package/dist/adapters/mongodbCollections.cjs +0 -38
  132. package/dist/adapters/mongodbCollections.mjs +0 -32
  133. package/dist/adapters/mongodbQuery.cjs +0 -94
  134. package/dist/adapters/mongodbQuery.mjs +0 -86
  135. package/dist/adapters/mongodbReads.cjs +0 -210
  136. package/dist/adapters/mongodbReads.mjs +0 -210
  137. package/dist/adapters/mongodbWrites.cjs +0 -148
  138. package/dist/adapters/mongodbWrites.mjs +0 -148
  139. package/dist/adapters/prismaQuery.cjs +0 -57
  140. package/dist/adapters/prismaQuery.mjs +0 -56
  141. package/dist/adapters/prismaRows.cjs +0 -219
  142. package/dist/adapters/prismaRows.mjs +0 -209
  143. package/dist/apiKeys.cjs +0 -143
  144. package/dist/apiKeys.d.cts +0 -49
  145. package/dist/apiKeys.d.mts +0 -49
  146. package/dist/apiKeys.mjs +0 -133
  147. package/dist/db/createBundleDiff.cjs +0 -144
  148. package/dist/db/createBundleDiff.d.cts +0 -16
  149. package/dist/db/createBundleDiff.d.mts +0 -16
  150. package/dist/db/createBundleDiff.mjs +0 -141
  151. package/dist/db/databasePluginCore.cjs +0 -137
  152. package/dist/db/databasePluginCore.mjs +0 -137
  153. package/dist/db/fixedMigrator.cjs +0 -79
  154. package/dist/db/fixedMigrator.mjs +0 -78
  155. package/dist/db/fixedMigratorMongo.cjs +0 -321
  156. package/dist/db/fixedMigratorMongo.mjs +0 -321
  157. package/dist/db/fixedMigratorShared.cjs +0 -23
  158. package/dist/db/fixedMigratorShared.mjs +0 -18
  159. package/dist/db/index.cjs +0 -27
  160. package/dist/db/index.d.cts +0 -12
  161. package/dist/db/index.d.mts +0 -12
  162. package/dist/db/index.mjs +0 -22
  163. package/dist/db/mongoMigrationExecution.cjs +0 -11
  164. package/dist/db/mongoMigrationExecution.mjs +0 -11
  165. package/dist/db/releaseCatalog.d.cts +0 -16
  166. package/dist/db/releaseCatalog.d.mts +0 -16
  167. package/dist/db/schema/insightsCollation.cjs +0 -14
  168. package/dist/db/schema/insightsCollation.mjs +0 -14
  169. package/dist/db/schema/mongodb.cjs +0 -25
  170. package/dist/db/schema/mongodb.mjs +0 -25
  171. package/dist/db/schema/registry.cjs +0 -21
  172. package/dist/db/schema/registry.mjs +0 -17
  173. package/dist/db/schema/sql.cjs +0 -105
  174. package/dist/db/schema/sql.mjs +0 -97
  175. package/dist/db/schema/sqlOperations.cjs +0 -27
  176. package/dist/db/schema/sqlOperations.mjs +0 -26
  177. package/dist/db/schemaGenerators.cjs +0 -275
  178. package/dist/db/schemaGenerators.mjs +0 -273
  179. package/dist/db/schemaReadiness.cjs +0 -26
  180. package/dist/db/schemaReadiness.d.cts +0 -9
  181. package/dist/db/schemaReadiness.d.mts +0 -9
  182. package/dist/db/schemaReadiness.mjs +0 -25
  183. package/dist/db/sqlMigrationExecution.cjs +0 -67
  184. package/dist/db/sqlMigrationExecution.mjs +0 -67
  185. package/dist/db/types.cjs +0 -22
  186. package/dist/db/types.d.cts +0 -118
  187. package/dist/db/types.d.mts +0 -118
  188. package/dist/db/types.mjs +0 -19
  189. package/dist/handlerBundleRoutes.cjs +0 -155
  190. package/dist/handlerBundleRoutes.mjs +0 -155
  191. package/dist/handlerReleaseManagementRoutes.cjs +0 -124
  192. package/dist/handlerReleaseManagementRoutes.mjs +0 -124
  193. package/dist/insights/domain.d.cts +0 -89
  194. package/dist/insights/domain.d.mts +0 -89
  195. package/dist/insights/errors.cjs +0 -15
  196. package/dist/insights/errors.mjs +0 -14
  197. package/dist/insights/eventInput.cjs +0 -155
  198. package/dist/insights/eventInput.mjs +0 -153
  199. package/dist/insights/provider.cjs +0 -314
  200. package/dist/insights/provider.d.cts +0 -6
  201. package/dist/insights/provider.d.mts +0 -6
  202. package/dist/insights/provider.mjs +0 -314
  203. package/dist/insights/queryInput.cjs +0 -93
  204. package/dist/insights/queryInput.mjs +0 -91
  205. package/dist/insights/routes.cjs +0 -58
  206. package/dist/insights/routes.mjs +0 -56
  207. package/dist/insights/types.d.cts +0 -32
  208. package/dist/insights/types.d.mts +0 -32
  209. package/dist/schema/dsl.cjs +0 -103
  210. package/dist/schema/dsl.mjs +0 -87
  211. package/dist/schema/index.cjs +0 -20
  212. package/dist/schema/index.mjs +0 -7
  213. package/dist/schema/settings.cjs +0 -9
  214. package/dist/schema/settings.mjs +0 -9
  215. package/dist/schema/types.cjs +0 -8
  216. package/dist/schema/types.mjs +0 -6
  217. package/dist/schema/v1_0_0.cjs +0 -406
  218. package/dist/schema/v1_0_0.mjs +0 -398
  219. package/src/adapters/databaseConstraintErrors.ts +0 -25
  220. package/src/adapters/databasePluginTestDatabase.ts +0 -120
  221. package/src/adapters/databasePluginUtils.spec.ts +0 -29
  222. package/src/adapters/databasePluginUtils.ts +0 -214
  223. package/src/adapters/drizzle.spec.ts +0 -336
  224. package/src/adapters/drizzle.ts +0 -162
  225. package/src/adapters/drizzleCrud.ts +0 -571
  226. package/src/adapters/drizzleLazyDB.ts +0 -271
  227. package/src/adapters/drizzleQuery.ts +0 -164
  228. package/src/adapters/insightsTransaction.ts +0 -32
  229. package/src/adapters/kysely.spec.ts +0 -174
  230. package/src/adapters/kysely.ts +0 -110
  231. package/src/adapters/kyselyCrud.ts +0 -709
  232. package/src/adapters/kyselyQuery.ts +0 -128
  233. package/src/adapters/mongodb.integration.spec.ts +0 -210
  234. package/src/adapters/mongodb.spec.ts +0 -209
  235. package/src/adapters/mongodb.ts +0 -138
  236. package/src/adapters/mongodbCollections.ts +0 -67
  237. package/src/adapters/mongodbQuery.ts +0 -255
  238. package/src/adapters/mongodbReads.ts +0 -380
  239. package/src/adapters/mongodbRows.spec.ts +0 -64
  240. package/src/adapters/mongodbRows.ts +0 -118
  241. package/src/adapters/mongodbTestClient.ts +0 -377
  242. package/src/adapters/mongodbTestFilter.ts +0 -169
  243. package/src/adapters/mongodbWrites.ts +0 -287
  244. package/src/adapters/prisma.spec.ts +0 -293
  245. package/src/adapters/prisma.ts +0 -565
  246. package/src/adapters/prismaQuery.ts +0 -129
  247. package/src/adapters/prismaRows.spec.ts +0 -98
  248. package/src/adapters/prismaRows.ts +0 -337
  249. package/src/adapters/prismaTestClient.ts +0 -413
  250. package/src/apiKeys.integration.spec.ts +0 -192
  251. package/src/apiKeys.spec.ts +0 -162
  252. package/src/apiKeys.ts +0 -220
  253. package/src/calculatePagination.ts +0 -34
  254. package/src/createHotUpdaterCore.ts +0 -246
  255. package/src/db/bundleRows.spec.ts +0 -164
  256. package/src/db/bundleRows.ts +0 -10
  257. package/src/db/createBundleDiff.spec.ts +0 -450
  258. package/src/db/createBundleDiff.ts +0 -364
  259. package/src/db/databasePluginCore.spec.ts +0 -62
  260. package/src/db/databasePluginCore.testFixtures.ts +0 -76
  261. package/src/db/databasePluginCore.ts +0 -185
  262. package/src/db/databasePluginUpdateCheck.bench.ts +0 -110
  263. package/src/db/fixedMigrator.spec.ts +0 -296
  264. package/src/db/fixedMigrator.ts +0 -147
  265. package/src/db/fixedMigratorMongo.spec.ts +0 -239
  266. package/src/db/fixedMigratorMongo.ts +0 -425
  267. package/src/db/fixedMigratorShared.ts +0 -36
  268. package/src/db/hotUpdaterSchema.ts +0 -5
  269. package/src/db/index.spec.ts +0 -1269
  270. package/src/db/index.ts +0 -47
  271. package/src/db/mongoMigrationExecution.ts +0 -23
  272. package/src/db/node-sqlite.d.ts +0 -25
  273. package/src/db/releaseCatalog.ts +0 -148
  274. package/src/db/schema/definitions.ts +0 -1
  275. package/src/db/schema/insightsCollation.ts +0 -21
  276. package/src/db/schema/mongodb.ts +0 -40
  277. package/src/db/schema/registry.ts +0 -55
  278. package/src/db/schema/sql.ts +0 -244
  279. package/src/db/schema/sqlOperations.ts +0 -63
  280. package/src/db/schema/types.ts +0 -1
  281. package/src/db/schemaGenerators.ts +0 -494
  282. package/src/db/schemaReadiness.ts +0 -34
  283. package/src/db/sqlMigrationExecution.spec.ts +0 -65
  284. package/src/db/sqlMigrationExecution.ts +0 -108
  285. package/src/db/types.spec.ts +0 -63
  286. package/src/db/types.ts +0 -228
  287. package/src/db/updateArtifacts.spec.ts +0 -359
  288. package/src/db/updateArtifacts.ts +0 -541
  289. package/src/handler-standalone.integration.spec.ts +0 -528
  290. package/src/handler.spec.ts +0 -190
  291. package/src/handler.testFixtures.ts +0 -30
  292. package/src/handler.ts +0 -245
  293. package/src/handlerAuth.integration.spec.ts +0 -33
  294. package/src/handlerBundleRoutes.ts +0 -259
  295. package/src/handlerErrors.ts +0 -7
  296. package/src/handlerManagement.spec.ts +0 -262
  297. package/src/handlerParameters.ts +0 -105
  298. package/src/handlerReleaseCatalogRoutes.ts +0 -154
  299. package/src/handlerReleaseManagementRoutes.ts +0 -213
  300. package/src/handlerTypes.ts +0 -96
  301. package/src/handlerVersionRoutes.ts +0 -12
  302. package/src/index.ts +0 -30
  303. package/src/insights/domain.ts +0 -103
  304. package/src/insights/errors.ts +0 -11
  305. package/src/insights/eventInput.ts +0 -225
  306. package/src/insights/insights.integration.spec.ts +0 -381
  307. package/src/insights/provider.spec.ts +0 -385
  308. package/src/insights/provider.ts +0 -591
  309. package/src/insights/queryInput.ts +0 -141
  310. package/src/insights/routes.ts +0 -104
  311. package/src/insights/types.ts +0 -55
  312. package/src/internalRouter.ts +0 -104
  313. package/src/node.spec.ts +0 -119
  314. package/src/node.ts +0 -111
  315. package/src/releaseCatalogRoutes.integration.spec.ts +0 -238
  316. package/src/runtime.spec.ts +0 -194
  317. package/src/runtime.testFixtures.ts +0 -71
  318. package/src/schema/dsl-all-versions.spec.ts +0 -37
  319. package/src/schema/dsl.ts +0 -187
  320. package/src/schema/index.ts +0 -10
  321. package/src/schema/settings.ts +0 -15
  322. package/src/schema/types.ts +0 -79
  323. package/src/schema/v1_0_0.spec.ts +0 -220
  324. package/src/schema/v1_0_0.ts +0 -529
  325. package/src/storageAccess.spec.ts +0 -152
  326. package/src/storageAccess.ts +0 -141
  327. package/src/types/index.ts +0 -34
  328. package/src/version.ts +0 -3
@@ -1,12 +1,16 @@
1
- import { DatabaseAdapterWithCapabilities, ORMSQLProvider, RelationMode } from "../db/types.cjs";
1
+ import { kyselyExecutor } from "./kyselyExecutor.cjs";
2
+ import { SqlDialect, ToolingDatabase } from "@hot-updater/plugin-core";
2
3
  import { Kysely } from "kysely";
3
4
  //#region src/adapters/kysely.d.ts
4
- type KyselySQLProvider = Exclude<ORMSQLProvider, "mssql">;
5
5
  interface KyselyAdapterConfig<TDatabase extends object = object> {
6
6
  readonly db: Kysely<TDatabase>;
7
- readonly provider: KyselySQLProvider;
8
- readonly relationMode?: RelationMode;
7
+ readonly provider: SqlDialect;
9
8
  }
10
- declare const kyselyAdapter: <TDatabase extends object>(config: KyselyAdapterConfig<TDatabase>) => DatabaseAdapterWithCapabilities;
9
+ /**
10
+ * Hot Updater's database on a Kysely instance: the storage engine through the
11
+ * shared SQL core, fenced by the schema settings. `db migrate` and
12
+ * `db generate --sql` apply the engine's SQL schema.
13
+ */
14
+ declare const kyselyAdapter: <TDatabase extends object>(config: KyselyAdapterConfig<TDatabase>) => ToolingDatabase;
11
15
  //#endregion
12
- export { KyselyAdapterConfig, type RelationMode, type KyselySQLProvider as SQLProvider, kyselyAdapter };
16
+ export { KyselyAdapterConfig, type SqlDialect as SQLProvider, kyselyAdapter, kyselyExecutor };
@@ -1,12 +1,16 @@
1
- import { DatabaseAdapterWithCapabilities, ORMSQLProvider, RelationMode } from "../db/types.mjs";
1
+ import { kyselyExecutor } from "./kyselyExecutor.mjs";
2
+ import { SqlDialect, ToolingDatabase } from "@hot-updater/plugin-core";
2
3
  import { Kysely } from "kysely";
3
4
  //#region src/adapters/kysely.d.ts
4
- type KyselySQLProvider = Exclude<ORMSQLProvider, "mssql">;
5
5
  interface KyselyAdapterConfig<TDatabase extends object = object> {
6
6
  readonly db: Kysely<TDatabase>;
7
- readonly provider: KyselySQLProvider;
8
- readonly relationMode?: RelationMode;
7
+ readonly provider: SqlDialect;
9
8
  }
10
- declare const kyselyAdapter: <TDatabase extends object>(config: KyselyAdapterConfig<TDatabase>) => DatabaseAdapterWithCapabilities;
9
+ /**
10
+ * Hot Updater's database on a Kysely instance: the storage engine through the
11
+ * shared SQL core, fenced by the schema settings. `db migrate` and
12
+ * `db generate --sql` apply the engine's SQL schema.
13
+ */
14
+ declare const kyselyAdapter: <TDatabase extends object>(config: KyselyAdapterConfig<TDatabase>) => ToolingDatabase;
11
15
  //#endregion
12
- export { KyselyAdapterConfig, type RelationMode, type KyselySQLProvider as SQLProvider, kyselyAdapter };
16
+ export { KyselyAdapterConfig, type SqlDialect as SQLProvider, kyselyAdapter, kyselyExecutor };
@@ -1,38 +1,28 @@
1
- import { createKyselyMigrator } from "../db/fixedMigrator.mjs";
2
- import { runInsightsTransaction } from "./insightsTransaction.mjs";
3
- import { createKyselyCrud, recordKyselyInsights } from "./kyselyCrud.mjs";
4
- import { createDatabasePlugin } from "@hot-updater/plugin-core";
5
- import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
1
+ import { kyselyExecutor } from "./kyselyExecutor.mjs";
2
+ import { checkSqlProvider } from "./sqlProviders.mjs";
3
+ import { coreTarget, createEngineDatabase, createEngineSqlMigrator, createSqlAdapter } from "@hot-updater/plugin-core";
6
4
  //#region src/adapters/kysely.ts
7
- const createImplementation = (config) => {
8
- const db = config.db;
9
- const relationMode = config.relationMode ?? "foreign-keys";
10
- return {
11
- ...createKyselyCrud(db, config.provider, relationMode),
12
- recordInsights: (input) => runInsightsTransaction(() => db.transaction().execute((transaction) => recordKyselyInsights(transaction, config.provider, input))),
13
- deleteChannel: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).deleteChannel(input)),
14
- create: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).create(input)),
15
- update: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).update(input)),
16
- delete: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).delete(input)),
17
- transaction: (callback) => db.transaction().execute((transaction) => callback(createKyselyCrud(transaction, config.provider, relationMode)))
18
- };
19
- };
5
+ /**
6
+ * Hot Updater's database on a Kysely instance: the storage engine through the
7
+ * shared SQL core, fenced by the schema settings. `db migrate` and
8
+ * `db generate --sql` apply the engine's SQL schema.
9
+ */
20
10
  const kyselyAdapter = (config) => {
21
- const adapter = createDatabasePluginAdapter("kysely", createImplementation(config));
22
- const plugin = createDatabasePlugin({
23
- name: "kysely",
24
- models: adapter.models,
25
- commit: adapter.commit
26
- });
27
- return Object.assign(plugin, {
28
- adapterName: "kysely",
29
- provider: config.provider,
30
- createMigrator: () => createKyselyMigrator({
31
- db: config.db,
32
- provider: config.provider,
33
- relationMode: config.relationMode
11
+ const provider = checkSqlProvider("kyselyAdapter", config.provider);
12
+ const executor = kyselyExecutor(config.db, provider);
13
+ return {
14
+ ...createEngineDatabase({
15
+ name: "kysely",
16
+ adapter: createSqlAdapter({ executor })
17
+ }),
18
+ provider,
19
+ createMigrator: ({ schema, settings } = coreTarget) => createEngineSqlMigrator({
20
+ adapterName: "kysely",
21
+ executor,
22
+ schema,
23
+ settings
34
24
  })
35
- });
25
+ };
36
26
  };
37
27
  //#endregion
38
- export { kyselyAdapter };
28
+ export { kyselyAdapter, kyselyExecutor };
@@ -0,0 +1,32 @@
1
+ let kysely = require("kysely");
2
+ //#region src/adapters/kyselyExecutor.ts
3
+ const over = (runner) => ({ async execute({ sql, params }) {
4
+ const result = await runner.executeQuery(kysely.CompiledQuery.raw(sql, [...params]));
5
+ return {
6
+ rows: result.rows,
7
+ changes: Number(result.numAffectedRows ?? 0n)
8
+ };
9
+ } });
10
+ const raw = (runner, sql) => runner.executeQuery(kysely.CompiledQuery.raw(sql));
11
+ /**
12
+ * The SQL core's executor over a Kysely instance: statements run as raw
13
+ * compiled queries. SQLite transactions begin with BEGIN IMMEDIATE on one
14
+ * connection; other dialects use Kysely's transactions.
15
+ */
16
+ const kyselyExecutor = (db, dialect) => ({
17
+ dialect,
18
+ ...over(db),
19
+ transaction: (fn) => dialect === "sqlite" ? db.connection().execute(async (connection) => {
20
+ await raw(connection, "BEGIN IMMEDIATE");
21
+ try {
22
+ const result = await fn(over(connection));
23
+ await raw(connection, "COMMIT");
24
+ return result;
25
+ } catch (error) {
26
+ await raw(connection, "ROLLBACK").catch(() => void 0);
27
+ throw error;
28
+ }
29
+ }) : db.transaction().execute((transaction) => fn(over(transaction)))
30
+ });
31
+ //#endregion
32
+ exports.kyselyExecutor = kyselyExecutor;
@@ -0,0 +1,11 @@
1
+ import { SqlDialect, SqlExecutor } from "@hot-updater/plugin-core";
2
+ import { Kysely } from "kysely";
3
+ //#region src/adapters/kyselyExecutor.d.ts
4
+ /**
5
+ * The SQL core's executor over a Kysely instance: statements run as raw
6
+ * compiled queries. SQLite transactions begin with BEGIN IMMEDIATE on one
7
+ * connection; other dialects use Kysely's transactions.
8
+ */
9
+ declare const kyselyExecutor: (db: Kysely<object>, dialect: SqlDialect) => SqlExecutor;
10
+ //#endregion
11
+ export { kyselyExecutor };
@@ -0,0 +1,11 @@
1
+ import { SqlDialect, SqlExecutor } from "@hot-updater/plugin-core";
2
+ import { Kysely } from "kysely";
3
+ //#region src/adapters/kyselyExecutor.d.ts
4
+ /**
5
+ * The SQL core's executor over a Kysely instance: statements run as raw
6
+ * compiled queries. SQLite transactions begin with BEGIN IMMEDIATE on one
7
+ * connection; other dialects use Kysely's transactions.
8
+ */
9
+ declare const kyselyExecutor: (db: Kysely<object>, dialect: SqlDialect) => SqlExecutor;
10
+ //#endregion
11
+ export { kyselyExecutor };
@@ -0,0 +1,32 @@
1
+ import { CompiledQuery } from "kysely";
2
+ //#region src/adapters/kyselyExecutor.ts
3
+ const over = (runner) => ({ async execute({ sql, params }) {
4
+ const result = await runner.executeQuery(CompiledQuery.raw(sql, [...params]));
5
+ return {
6
+ rows: result.rows,
7
+ changes: Number(result.numAffectedRows ?? 0n)
8
+ };
9
+ } });
10
+ const raw = (runner, sql) => runner.executeQuery(CompiledQuery.raw(sql));
11
+ /**
12
+ * The SQL core's executor over a Kysely instance: statements run as raw
13
+ * compiled queries. SQLite transactions begin with BEGIN IMMEDIATE on one
14
+ * connection; other dialects use Kysely's transactions.
15
+ */
16
+ const kyselyExecutor = (db, dialect) => ({
17
+ dialect,
18
+ ...over(db),
19
+ transaction: (fn) => dialect === "sqlite" ? db.connection().execute(async (connection) => {
20
+ await raw(connection, "BEGIN IMMEDIATE");
21
+ try {
22
+ const result = await fn(over(connection));
23
+ await raw(connection, "COMMIT");
24
+ return result;
25
+ } catch (error) {
26
+ await raw(connection, "ROLLBACK").catch(() => void 0);
27
+ throw error;
28
+ }
29
+ }) : db.transaction().execute((transaction) => fn(over(transaction)))
30
+ });
31
+ //#endregion
32
+ export { kyselyExecutor };
@@ -1,61 +1,25 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_fixedMigratorMongo = require("../db/fixedMigratorMongo.cjs");
3
- const require_mongodbCollections = require("./mongodbCollections.cjs");
4
- const require_mongodbReads = require("./mongodbReads.cjs");
5
- const require_mongodbWrites = require("./mongodbWrites.cjs");
2
+ const require_mongodbAdapter = require("./mongodbAdapter.cjs");
6
3
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
7
- let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
8
- let mongodb = require("mongodb");
9
4
  //#region src/adapters/mongodb.ts
10
- const createMongoImplementation = (client, session) => {
11
- const collections = require_mongodbCollections.createMongoCollections(client);
12
- return {
13
- recordInsights: async (input) => {
14
- const record = () => client.withSession((recordSession) => recordSession.withTransaction(async () => {
15
- const records = require_mongodbCollections.createMongoCollections(client);
16
- const options = {
17
- session: recordSession,
18
- collation: { locale: "simple" }
19
- };
20
- if ((await records.bundleEvents.updateOne({ id: input.event.id }, { $setOnInsert: input.event }, {
21
- ...options,
22
- upsert: true
23
- })).upsertedCount === 0) return;
24
- const current = await records.bundleInstallations.findOne({ install_id: input.installation.install_id }, options);
25
- if (current === null) await records.bundleInstallations.insertOne({ ...input.installation }, { session: recordSession });
26
- else if (input.installation.received_at_ms > current.received_at_ms || input.installation.received_at_ms === current.received_at_ms && (0, _hot_updater_plugin_core.compareInsightsText)(input.installation.id, current.id) > 0) await records.bundleInstallations.updateOne({ install_id: input.installation.install_id }, { $set: input.installation }, options);
27
- }, {
28
- readConcern: { level: "snapshot" },
29
- readPreference: "primary",
30
- writeConcern: { w: "majority" }
31
- }));
32
- try {
33
- await record();
34
- } catch (error) {
35
- if (!(error instanceof mongodb.MongoServerError) || error.code !== 11e3) throw error;
36
- await record();
37
- }
38
- },
39
- ...require_mongodbWrites.createMongoWrites(collections, session),
40
- ...require_mongodbReads.createMongoReads(collections, session)
41
- };
5
+ /** Settings rows by their `key` field: the engine's rows and a v0 database's alike. */
6
+ const readSettings = (client) => async () => {
7
+ const rows = await client.db().collection(_hot_updater_plugin_core.SETTINGS_TABLE.name).find({ key: { $type: "string" } }).toArray();
8
+ return new Map(rows.map((row) => [String(row.key), row.value]));
42
9
  };
43
- const createTransactionalMongoImplementation = (client) => ({
44
- ...createMongoImplementation(client),
45
- deleteChannel: (input) => client.withSession((session) => session.withTransaction(() => createMongoImplementation(client, session).deleteChannel(input))),
46
- transaction: (callback) => client.withSession((session) => session.withTransaction(() => callback(createMongoImplementation(client, session))))
47
- });
48
- const mongoAdapter = (config) => {
49
- const adapter = (0, _hot_updater_plugin_core_internal.createDatabasePluginAdapter)("mongodb", config.transactions === true ? createTransactionalMongoImplementation(config.client) : createMongoImplementation(config.client));
50
- return Object.assign((0, _hot_updater_plugin_core.createDatabasePlugin)({
10
+ /**
11
+ * Hot Updater's database on MongoDB: the storage engine's MongoDB adapter,
12
+ * fenced by the schema settings. `db migrate` creates the collections and
13
+ * indexes, then writes the settings.
14
+ */
15
+ const mongoAdapter = (config) => ({
16
+ ...(0, _hot_updater_plugin_core.createEngineDatabase)({
51
17
  name: "mongodb",
52
- models: adapter.models,
53
- commit: adapter.commit
54
- }), {
55
- adapterName: "mongodb",
56
- provider: "mongodb",
57
- createMigrator: () => require_fixedMigratorMongo.createMongoMigrator(config.client)
58
- });
59
- };
18
+ adapter: require_mongodbAdapter.createMongoAdapter({ client: config.client }),
19
+ readSettings: readSettings(config.client)
20
+ }),
21
+ provider: "mongodb"
22
+ });
60
23
  //#endregion
24
+ exports.MongoTransactionUnsupportedError = require_mongodbAdapter.MongoTransactionUnsupportedError;
61
25
  exports.mongoAdapter = mongoAdapter;
@@ -1,11 +1,16 @@
1
- import { DatabaseAdapterWithCapabilities } from "../db/types.cjs";
1
+ import { MongoTransactionUnsupportedError } from "./mongodbAdapter.cjs";
2
+ import { ToolingDatabase } from "@hot-updater/plugin-core";
2
3
  import { MongoClient } from "mongodb";
3
4
  //#region src/adapters/mongodb.d.ts
5
+ /** Every write runs in a transaction, which needs a replica set or a sharded cluster. */
4
6
  interface MongoDBConfig {
5
7
  readonly client: MongoClient;
6
- /** Enables atomic catalog commits. Insights always requires MongoDB 5+ on a replica set or sharded cluster. */
7
- readonly transactions?: boolean;
8
8
  }
9
- declare const mongoAdapter: (config: MongoDBConfig) => DatabaseAdapterWithCapabilities;
9
+ /**
10
+ * Hot Updater's database on MongoDB: the storage engine's MongoDB adapter,
11
+ * fenced by the schema settings. `db migrate` creates the collections and
12
+ * indexes, then writes the settings.
13
+ */
14
+ declare const mongoAdapter: (config: MongoDBConfig) => ToolingDatabase;
10
15
  //#endregion
11
- export { MongoDBConfig, mongoAdapter };
16
+ export { MongoDBConfig, MongoTransactionUnsupportedError, mongoAdapter };
@@ -1,11 +1,16 @@
1
- import { DatabaseAdapterWithCapabilities } from "../db/types.mjs";
1
+ import { MongoTransactionUnsupportedError } from "./mongodbAdapter.mjs";
2
+ import { ToolingDatabase } from "@hot-updater/plugin-core";
2
3
  import { MongoClient } from "mongodb";
3
4
  //#region src/adapters/mongodb.d.ts
5
+ /** Every write runs in a transaction, which needs a replica set or a sharded cluster. */
4
6
  interface MongoDBConfig {
5
7
  readonly client: MongoClient;
6
- /** Enables atomic catalog commits. Insights always requires MongoDB 5+ on a replica set or sharded cluster. */
7
- readonly transactions?: boolean;
8
8
  }
9
- declare const mongoAdapter: (config: MongoDBConfig) => DatabaseAdapterWithCapabilities;
9
+ /**
10
+ * Hot Updater's database on MongoDB: the storage engine's MongoDB adapter,
11
+ * fenced by the schema settings. `db migrate` creates the collections and
12
+ * indexes, then writes the settings.
13
+ */
14
+ declare const mongoAdapter: (config: MongoDBConfig) => ToolingDatabase;
10
15
  //#endregion
11
- export { MongoDBConfig, mongoAdapter };
16
+ export { MongoDBConfig, MongoTransactionUnsupportedError, mongoAdapter };
@@ -1,60 +1,23 @@
1
- import { createMongoMigrator } from "../db/fixedMigratorMongo.mjs";
2
- import { createMongoCollections } from "./mongodbCollections.mjs";
3
- import { createMongoReads } from "./mongodbReads.mjs";
4
- import { createMongoWrites } from "./mongodbWrites.mjs";
5
- import { compareInsightsText, createDatabasePlugin } from "@hot-updater/plugin-core";
6
- import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
7
- import { MongoServerError } from "mongodb";
1
+ import { MongoTransactionUnsupportedError, createMongoAdapter } from "./mongodbAdapter.mjs";
2
+ import { SETTINGS_TABLE, createEngineDatabase } from "@hot-updater/plugin-core";
8
3
  //#region src/adapters/mongodb.ts
9
- const createMongoImplementation = (client, session) => {
10
- const collections = createMongoCollections(client);
11
- return {
12
- recordInsights: async (input) => {
13
- const record = () => client.withSession((recordSession) => recordSession.withTransaction(async () => {
14
- const records = createMongoCollections(client);
15
- const options = {
16
- session: recordSession,
17
- collation: { locale: "simple" }
18
- };
19
- if ((await records.bundleEvents.updateOne({ id: input.event.id }, { $setOnInsert: input.event }, {
20
- ...options,
21
- upsert: true
22
- })).upsertedCount === 0) return;
23
- const current = await records.bundleInstallations.findOne({ install_id: input.installation.install_id }, options);
24
- if (current === null) await records.bundleInstallations.insertOne({ ...input.installation }, { session: recordSession });
25
- else if (input.installation.received_at_ms > current.received_at_ms || input.installation.received_at_ms === current.received_at_ms && compareInsightsText(input.installation.id, current.id) > 0) await records.bundleInstallations.updateOne({ install_id: input.installation.install_id }, { $set: input.installation }, options);
26
- }, {
27
- readConcern: { level: "snapshot" },
28
- readPreference: "primary",
29
- writeConcern: { w: "majority" }
30
- }));
31
- try {
32
- await record();
33
- } catch (error) {
34
- if (!(error instanceof MongoServerError) || error.code !== 11e3) throw error;
35
- await record();
36
- }
37
- },
38
- ...createMongoWrites(collections, session),
39
- ...createMongoReads(collections, session)
40
- };
4
+ /** Settings rows by their `key` field: the engine's rows and a v0 database's alike. */
5
+ const readSettings = (client) => async () => {
6
+ const rows = await client.db().collection(SETTINGS_TABLE.name).find({ key: { $type: "string" } }).toArray();
7
+ return new Map(rows.map((row) => [String(row.key), row.value]));
41
8
  };
42
- const createTransactionalMongoImplementation = (client) => ({
43
- ...createMongoImplementation(client),
44
- deleteChannel: (input) => client.withSession((session) => session.withTransaction(() => createMongoImplementation(client, session).deleteChannel(input))),
45
- transaction: (callback) => client.withSession((session) => session.withTransaction(() => callback(createMongoImplementation(client, session))))
46
- });
47
- const mongoAdapter = (config) => {
48
- const adapter = createDatabasePluginAdapter("mongodb", config.transactions === true ? createTransactionalMongoImplementation(config.client) : createMongoImplementation(config.client));
49
- return Object.assign(createDatabasePlugin({
9
+ /**
10
+ * Hot Updater's database on MongoDB: the storage engine's MongoDB adapter,
11
+ * fenced by the schema settings. `db migrate` creates the collections and
12
+ * indexes, then writes the settings.
13
+ */
14
+ const mongoAdapter = (config) => ({
15
+ ...createEngineDatabase({
50
16
  name: "mongodb",
51
- models: adapter.models,
52
- commit: adapter.commit
53
- }), {
54
- adapterName: "mongodb",
55
- provider: "mongodb",
56
- createMigrator: () => createMongoMigrator(config.client)
57
- });
58
- };
17
+ adapter: createMongoAdapter({ client: config.client }),
18
+ readSettings: readSettings(config.client)
19
+ }),
20
+ provider: "mongodb"
21
+ });
59
22
  //#endregion
60
- export { mongoAdapter };
23
+ export { MongoTransactionUnsupportedError, mongoAdapter };
@@ -0,0 +1,192 @@
1
+ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
2
+ let mongodb = require("mongodb");
3
+ //#region src/adapters/mongodbAdapter.ts
4
+ var MongoTransactionUnsupportedError = class extends Error {
5
+ name = "MongoTransactionUnsupportedError";
6
+ constructor(cause) {
7
+ super("Hot Updater writes in MongoDB transactions, which need a replica set or a sharded cluster.", { cause });
8
+ }
9
+ };
10
+ /** A single key column is the `_id`; a composite key is a document in key-column order. */
11
+ const idOf = (table, key) => table.key.length === 1 ? key[0] : Object.fromEntries(table.key.map((column, at) => [column, key[at]]));
12
+ /** A filter on `_id` (never an ObjectId), and on the version when given. */
13
+ const byId = (_id, v) => v === void 0 ? { _id } : {
14
+ _id,
15
+ [_hot_updater_plugin_core.DATABASE_VERSION_COLUMN]: v
16
+ };
17
+ /** MongoDB's TTL monitor deletes a document once its `_expireAt` passes. */
18
+ const TTL = {
19
+ name: "_expireAt",
20
+ key: { _expireAt: 1 },
21
+ expireAfterSeconds: 0
22
+ };
23
+ /** When a row with retention expires; a null retention column never does. */
24
+ const expireAt = ({ retention }, row) => {
25
+ const at = row[retention.column];
26
+ return typeof at === "number" ? new Date(at + retention.ms) : null;
27
+ };
28
+ /** Null columns are left out, so unique indexes skip them as SQL's do. */
29
+ const toDocument = (table, row) => ({
30
+ _id: idOf(table, (0, _hot_updater_plugin_core.rowKey)(table, row)),
31
+ ...Object.fromEntries(table.columns.flatMap(({ name }) => row[name] === null || row[name] === void 0 ? [] : [[name, row[name]]])),
32
+ ...table.retention && { [TTL.name]: expireAt(table, row) }
33
+ });
34
+ /** `columns op bound` over a tuple prefix, expanded into ORs. */
35
+ const compare = (columns, { values, inclusive }, op) => {
36
+ const terms = values.map((value, position) => ({
37
+ ...Object.fromEntries(columns.slice(0, position).map((column, at) => [column, values[at]])),
38
+ [columns[position]]: { [position === values.length - 1 && inclusive ? `${op}e` : op]: value }
39
+ }));
40
+ return terms.length === 1 ? terms[0] : { $or: terms };
41
+ };
42
+ const indexDescription = (table, index) => {
43
+ const columns = index.unique ? index.eq : [...index.eq, ...(0, _hot_updater_plugin_core.indexOrderColumns)(table, index)];
44
+ const exists = columns.filter((column) => (0, _hot_updater_plugin_core.findPhysicalColumn)(table, column).nullable).map((column) => [column, { $exists: true }]);
45
+ return {
46
+ name: index.name,
47
+ key: Object.fromEntries(columns.map((column) => [column, 1])),
48
+ ...index.unique && { unique: true },
49
+ ...index.unique && exists.length > 0 && { partialFilterExpression: Object.fromEntries(exists) }
50
+ };
51
+ };
52
+ const mongoError = (error) => error instanceof mongodb.MongoError ? error : void 0;
53
+ /**
54
+ * The storage engine's adapter over MongoDB: one collection per table, the
55
+ * key as `_id`, and indexes as declared, with multi-valued fields as multikey
56
+ * indexes. A write runs in one transaction. Guards are conditional updates,
57
+ * and `check` is a conditional `$inc`: a real write, so a concurrent
58
+ * transaction on the document conflicts.
59
+ */
60
+ const createMongoAdapter = (options) => {
61
+ const { client, tablePrefix = "", maxOps = 1e3 } = options;
62
+ const collection = (table) => client.db().collection(tablePrefix + table.name);
63
+ const normalize = (table, document) => (0, _hot_updater_plugin_core.normalizeStoredRow)(table, document, { jsonText: false });
64
+ /** Whether the op applied; a guard that no longer matches changes nothing. */
65
+ const apply = async (op, session) => {
66
+ const target = collection(op.table);
67
+ if (op.type === "insert") {
68
+ await target.insertOne(toDocument(op.table, op.row), { session });
69
+ return true;
70
+ }
71
+ const _id = idOf(op.table, op.key);
72
+ const update = async (filter, change) => (await target.updateOne(filter, change, { session })).matchedCount === 1;
73
+ switch (op.type) {
74
+ case "patch": {
75
+ const $set = { [_hot_updater_plugin_core.DATABASE_VERSION_COLUMN]: op.guard.v + 1 };
76
+ const $unset = {};
77
+ for (const [name, value] of Object.entries(op.set)) if (value === null) $unset[name] = "";
78
+ else $set[name] = value;
79
+ if (op.table.retention) $set[TTL.name] = expireAt(op.table, {
80
+ ...op.previous,
81
+ ...op.set
82
+ });
83
+ return update(byId(_id, op.guard.v), {
84
+ $set,
85
+ $unset
86
+ });
87
+ }
88
+ case "delete": return (await target.deleteOne(byId(_id, op.guard.v), { session })).deletedCount === 1;
89
+ case "check": return update(byId(_id, op.guard.v), { $inc: { _checked: 1 } });
90
+ case "increment": {
91
+ if (op.init === void 0 || op.guard !== void 0) return update(byId(_id, op.guard?.v), { $inc: {
92
+ ...op.by,
93
+ [_hot_updater_plugin_core.DATABASE_VERSION_COLUMN]: 1
94
+ } });
95
+ const set = {};
96
+ for (const { name } of op.table.columns) {
97
+ const start = op.init[name] ?? null;
98
+ const by = name === _hot_updater_plugin_core.DATABASE_VERSION_COLUMN ? 1 : op.by[name];
99
+ const stored = { $ifNull: [`$${name}`, { $literal: start ?? 0 }] };
100
+ if (by !== void 0) set[name] = { $add: [stored, by] };
101
+ else if (start !== null) set[name] = stored;
102
+ }
103
+ if (op.table.retention) set[TTL.name] = expireAt(op.table, op.init);
104
+ await target.updateOne(byId(_id), [{ $set: set }], {
105
+ upsert: true,
106
+ session
107
+ });
108
+ return true;
109
+ }
110
+ }
111
+ };
112
+ return {
113
+ id: "mongodb",
114
+ fits: (ops) => ops.length <= maxOps,
115
+ async get(table, keys) {
116
+ if (keys.length === 0) return [];
117
+ const ids = keys.map((key) => idOf(table, key));
118
+ const documents = await collection(table).find(byId({ $in: ids })).toArray();
119
+ const found = new Map(documents.map((document) => [JSON.stringify(document._id), document]));
120
+ return ids.map((id) => {
121
+ const document = found.get(JSON.stringify(id));
122
+ return document === void 0 ? null : normalize(table, document);
123
+ });
124
+ },
125
+ async query(table, request) {
126
+ const index = (0, _hot_updater_plugin_core.findPhysicalIndex)(table, request.index);
127
+ const columns = (0, _hot_updater_plugin_core.indexOrderColumns)(table, index);
128
+ const bounds = [...request.lower ? [compare(columns, request.lower, "$gt")] : [], ...request.upper ? [compare(columns, request.upper, "$lt")] : []];
129
+ const direction = request.order === "asc" ? 1 : -1;
130
+ return (await collection(table).find({
131
+ ...Object.fromEntries(index.eq.map((column, at) => [column, request.eq[at]])),
132
+ ...bounds.length > 0 && { $and: bounds }
133
+ }, {
134
+ sort: Object.fromEntries(columns.map((column) => [column, direction])),
135
+ limit: request.limit,
136
+ ...options.batchSize && { batchSize: options.batchSize }
137
+ }).toArray()).map((document) => normalize(table, document));
138
+ },
139
+ async write(ops) {
140
+ const session = client.startSession();
141
+ let position = 0;
142
+ try {
143
+ session.startTransaction({
144
+ readConcern: { level: "snapshot" },
145
+ writeConcern: { w: "majority" }
146
+ });
147
+ for (; position < ops.length; position += 1) if (!await apply(ops[position], session)) {
148
+ await session.abortTransaction();
149
+ return {
150
+ ok: false,
151
+ failedOp: position
152
+ };
153
+ }
154
+ await session.commitTransaction().catch(async (error) => {
155
+ if (!mongoError(error)?.hasErrorLabel("UnknownTransactionCommitResult")) throw error;
156
+ await session.commitTransaction();
157
+ });
158
+ return { ok: true };
159
+ } catch (error) {
160
+ if (session.inTransaction()) await session.abortTransaction().catch(() => void 0);
161
+ const failure = mongoError(error);
162
+ if (failure?.hasErrorLabel("TransientTransactionError") || failure?.code === 112) return {
163
+ ok: false,
164
+ retry: true
165
+ };
166
+ if (failure?.code === 11e3 && position < ops.length) return ops[position].type === "increment" ? {
167
+ ok: false,
168
+ retry: true
169
+ } : {
170
+ ok: false,
171
+ failedOp: position
172
+ };
173
+ throw failure?.code === 20 ? new MongoTransactionUnsupportedError(error) : error;
174
+ } finally {
175
+ await session.endSession();
176
+ }
177
+ },
178
+ migrations: { async apply(tables) {
179
+ for (const table of tables) {
180
+ await client.db().createCollection(tablePrefix + table.name).catch((error) => {
181
+ if (mongoError(error)?.code !== 48) throw error;
182
+ });
183
+ if (table.retention) await collection(table).createIndexes([TTL]);
184
+ if (table.indexes.length === 0) continue;
185
+ await collection(table).createIndexes(table.indexes.map((index) => indexDescription(table, index)));
186
+ }
187
+ } }
188
+ };
189
+ };
190
+ //#endregion
191
+ exports.MongoTransactionUnsupportedError = MongoTransactionUnsupportedError;
192
+ exports.createMongoAdapter = createMongoAdapter;
@@ -0,0 +1,9 @@
1
+ import "@hot-updater/plugin-core";
2
+ import { MongoClient } from "mongodb";
3
+ //#region src/adapters/mongodbAdapter.d.ts
4
+ declare class MongoTransactionUnsupportedError extends Error {
5
+ readonly name = "MongoTransactionUnsupportedError";
6
+ constructor(cause: unknown);
7
+ }
8
+ //#endregion
9
+ export { MongoTransactionUnsupportedError };
@@ -0,0 +1,9 @@
1
+ import "@hot-updater/plugin-core";
2
+ import { MongoClient } from "mongodb";
3
+ //#region src/adapters/mongodbAdapter.d.ts
4
+ declare class MongoTransactionUnsupportedError extends Error {
5
+ readonly name = "MongoTransactionUnsupportedError";
6
+ constructor(cause: unknown);
7
+ }
8
+ //#endregion
9
+ export { MongoTransactionUnsupportedError };