@hot-updater/server 1.0.0-rc.16 → 1.0.0-rc.18

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 (309) hide show
  1. package/dist/adapters/drizzle.cjs +5 -5
  2. package/dist/adapters/drizzle.mjs +4 -4
  3. package/dist/adapters/kysely.cjs +3 -3
  4. package/dist/adapters/kysely.mjs +2 -2
  5. package/dist/adapters/mongodb.cjs +3 -3
  6. package/dist/adapters/mongodb.mjs +2 -2
  7. package/dist/adapters/mongodbAdapter.cjs +19 -1
  8. package/dist/adapters/mongodbAdapter.mjs +19 -1
  9. package/dist/adapters/prisma.cjs +5 -5
  10. package/dist/adapters/prisma.mjs +4 -4
  11. package/dist/assembly/assemblePlugins.cjs +47 -28
  12. package/dist/assembly/assemblePlugins.d.cts +3 -7
  13. package/dist/assembly/assemblePlugins.d.mts +3 -7
  14. package/dist/assembly/assemblePlugins.mjs +46 -27
  15. package/dist/assembly/clientPlugins.cjs +86 -0
  16. package/dist/assembly/clientPlugins.d.cts +16 -0
  17. package/dist/assembly/clientPlugins.d.mts +16 -0
  18. package/dist/assembly/clientPlugins.mjs +86 -0
  19. package/dist/assembly/configError.cjs +7 -0
  20. package/dist/assembly/configError.d.cts +7 -0
  21. package/dist/assembly/configError.d.mts +7 -0
  22. package/dist/assembly/configError.mjs +7 -0
  23. package/dist/assembly/databasePlugins.cjs +5 -1
  24. package/dist/assembly/databasePlugins.d.cts +5 -5
  25. package/dist/assembly/databasePlugins.d.mts +5 -5
  26. package/dist/assembly/databasePlugins.mjs +5 -1
  27. package/dist/assembly/pluginCli.cjs +125 -0
  28. package/dist/assembly/pluginCli.d.cts +59 -0
  29. package/dist/assembly/pluginCli.d.mts +59 -0
  30. package/dist/assembly/pluginCli.mjs +121 -0
  31. package/dist/createHotUpdaterCore.cjs +14 -16
  32. package/dist/createHotUpdaterCore.d.cts +10 -3
  33. package/dist/createHotUpdaterCore.d.mts +10 -3
  34. package/dist/createHotUpdaterCore.mjs +11 -13
  35. package/dist/database/aggregateBatching.cjs +626 -0
  36. package/dist/database/aggregateBatching.d.cts +10 -0
  37. package/dist/database/aggregateBatching.d.mts +10 -0
  38. package/dist/database/aggregateBatching.mjs +625 -0
  39. package/dist/{insights/errors.cjs → database/busy.cjs} +2 -15
  40. package/dist/database/busy.d.cts +12 -0
  41. package/dist/database/busy.d.mts +12 -0
  42. package/dist/{insights/errors.mjs → database/busy.mjs} +3 -14
  43. package/dist/database/database.cjs +22 -3
  44. package/dist/database/database.d.cts +15 -2
  45. package/dist/database/database.d.mts +15 -2
  46. package/dist/database/database.mjs +22 -3
  47. package/dist/database/definitions.d.cts +10 -0
  48. package/dist/database/definitions.d.mts +10 -0
  49. package/dist/database/engine.d.cts +2 -1
  50. package/dist/database/engine.d.mts +2 -1
  51. package/dist/database/engineAggregates.cjs +7 -4
  52. package/dist/database/engineAggregates.mjs +8 -5
  53. package/dist/database/engineReads.cjs +5 -3
  54. package/dist/database/engineReads.mjs +6 -4
  55. package/dist/database/engineTransaction.cjs +2 -6
  56. package/dist/database/engineTransaction.mjs +2 -6
  57. package/dist/database/fence.cjs +2 -1
  58. package/dist/database/fence.mjs +2 -1
  59. package/dist/database/index.cjs +17 -8
  60. package/dist/database/index.d.cts +5 -4
  61. package/dist/database/index.d.mts +5 -4
  62. package/dist/database/index.mjs +6 -5
  63. package/dist/database/kv/kvAdapter.cjs +15 -3
  64. package/dist/database/kv/kvAdapter.d.cts +8 -0
  65. package/dist/database/kv/kvAdapter.d.mts +8 -0
  66. package/dist/database/kv/kvAdapter.mjs +16 -4
  67. package/dist/database/resolveSchema.cjs +4 -1
  68. package/dist/database/resolveSchema.d.cts +1 -1
  69. package/dist/database/resolveSchema.d.mts +1 -1
  70. package/dist/database/resolveSchema.mjs +4 -1
  71. package/dist/database/retention.cjs +92 -0
  72. package/dist/database/retention.mjs +90 -0
  73. package/dist/database/schema.cjs +5 -2
  74. package/dist/database/schema.d.cts +30 -1
  75. package/dist/database/schema.d.mts +30 -1
  76. package/dist/database/schema.mjs +5 -2
  77. package/dist/database/sql/sqlAdapter.cjs +8 -0
  78. package/dist/database/sql/sqlAdapter.mjs +9 -1
  79. package/dist/database/sql/sqlSchema.cjs +56 -0
  80. package/dist/database/sql/sqlSchema.mjs +55 -1
  81. package/dist/db/coreDatabase.cjs +85 -0
  82. package/dist/db/coreDatabase.d.cts +57 -0
  83. package/dist/db/coreDatabase.d.mts +57 -0
  84. package/dist/db/coreDatabase.mjs +78 -0
  85. package/dist/db/index.cjs +11 -3
  86. package/dist/db/index.d.cts +7 -3
  87. package/dist/db/index.d.mts +7 -3
  88. package/dist/db/index.mjs +6 -3
  89. package/dist/db/types.d.cts +3 -3
  90. package/dist/db/types.d.mts +3 -3
  91. package/dist/diff.cjs +3 -0
  92. package/dist/diff.d.cts +2 -0
  93. package/dist/diff.d.mts +2 -0
  94. package/dist/diff.mjs +2 -0
  95. package/dist/handler.cjs +2 -14
  96. package/dist/handler.mjs +1 -13
  97. package/dist/handlerReleaseCatalogRoutes.cjs +21 -2
  98. package/dist/handlerReleaseCatalogRoutes.mjs +21 -2
  99. package/dist/index.cjs +2 -6
  100. package/dist/index.d.cts +4 -7
  101. package/dist/index.d.mts +4 -7
  102. package/dist/index.mjs +2 -4
  103. package/dist/package.cjs +1 -1
  104. package/dist/package.mjs +1 -1
  105. package/dist/{apiKeys.cjs → plugins/api-keys/apiKeys.cjs} +1 -1
  106. package/dist/{apiKeys.d.cts → plugins/api-keys/apiKeys.d.cts} +2 -2
  107. package/dist/{apiKeys.d.mts → plugins/api-keys/apiKeys.d.mts} +2 -2
  108. package/dist/{apiKeys.mjs → plugins/api-keys/apiKeys.mjs} +1 -1
  109. package/dist/plugins/api-keys/cli.cjs +115 -0
  110. package/dist/plugins/api-keys/cli.mjs +114 -0
  111. package/dist/plugins/api-keys/index.cjs +9 -6
  112. package/dist/plugins/api-keys/index.d.cts +4 -5
  113. package/dist/plugins/api-keys/index.d.mts +4 -5
  114. package/dist/plugins/api-keys/index.mjs +9 -7
  115. package/dist/plugins/api-keys/model.d.cts +20 -2
  116. package/dist/plugins/api-keys/model.d.mts +20 -2
  117. package/dist/plugins/definePlugin.cjs +1 -1
  118. package/dist/plugins/definePlugin.d.cts +130 -3
  119. package/dist/plugins/definePlugin.d.mts +130 -3
  120. package/dist/plugins/definePlugin.mjs +1 -1
  121. package/dist/plugins/index.cjs +25 -4
  122. package/dist/plugins/index.d.cts +7 -4
  123. package/dist/plugins/index.d.mts +7 -4
  124. package/dist/plugins/index.mjs +6 -4
  125. package/dist/plugins/insights/contract.cjs +193 -0
  126. package/dist/plugins/insights/contract.mjs +189 -0
  127. package/dist/{insights → plugins/insights}/domain.d.cts +60 -15
  128. package/dist/{insights → plugins/insights}/domain.d.mts +60 -15
  129. package/dist/plugins/insights/errors.cjs +15 -0
  130. package/dist/plugins/insights/errors.mjs +14 -0
  131. package/dist/{insights → plugins/insights}/eventInput.cjs +155 -22
  132. package/dist/{insights → plugins/insights}/eventInput.mjs +155 -22
  133. package/dist/plugins/insights/eventRow.cjs +49 -0
  134. package/dist/plugins/insights/eventRow.d.cts +64 -0
  135. package/dist/plugins/insights/eventRow.d.mts +64 -0
  136. package/dist/plugins/insights/eventRow.mjs +47 -0
  137. package/dist/plugins/insights/index.cjs +106 -26
  138. package/dist/plugins/insights/index.d.cts +130 -27
  139. package/dist/plugins/insights/index.d.mts +130 -27
  140. package/dist/plugins/insights/index.mjs +106 -29
  141. package/dist/plugins/insights/model.cjs +2 -2
  142. package/dist/plugins/insights/model.d.cts +1 -1
  143. package/dist/plugins/insights/model.d.mts +1 -1
  144. package/dist/plugins/insights/model.mjs +1 -1
  145. package/dist/plugins/insights/modelTypes.d.cts +176 -0
  146. package/dist/plugins/insights/modelTypes.d.mts +176 -0
  147. package/dist/plugins/insights/overview.cjs +109 -0
  148. package/dist/plugins/insights/overview.d.cts +15 -0
  149. package/dist/plugins/insights/overview.d.mts +15 -0
  150. package/dist/plugins/insights/overview.mjs +107 -0
  151. package/dist/{insights → plugins/insights}/provider.cjs +33 -14
  152. package/dist/{insights → plugins/insights}/provider.d.cts +2 -2
  153. package/dist/{insights → plugins/insights}/provider.d.mts +2 -2
  154. package/dist/{insights → plugins/insights}/provider.mjs +30 -11
  155. package/dist/{insights → plugins/insights}/queryInput.cjs +2 -2
  156. package/dist/{insights → plugins/insights}/queryInput.mjs +2 -2
  157. package/dist/plugins/insights/reads.cjs +298 -88
  158. package/dist/plugins/insights/reads.d.cts +61 -0
  159. package/dist/plugins/insights/reads.d.mts +61 -0
  160. package/dist/plugins/insights/reads.mjs +298 -90
  161. package/dist/plugins/insights/recordEvent.cjs +223 -39
  162. package/dist/plugins/insights/recordEvent.d.cts +9 -4
  163. package/dist/plugins/insights/recordEvent.d.mts +9 -4
  164. package/dist/plugins/insights/recordEvent.mjs +221 -37
  165. package/dist/{insights → plugins/insights}/routes.cjs +3 -30
  166. package/dist/{insights → plugins/insights}/routes.mjs +4 -28
  167. package/dist/plugins/insights/schema.cjs +182 -40
  168. package/dist/plugins/insights/schema.d.cts +446 -6
  169. package/dist/plugins/insights/schema.d.mts +446 -6
  170. package/dist/plugins/insights/schema.mjs +180 -41
  171. package/dist/plugins/insights/testing/eventRow.d.mts +64 -0
  172. package/dist/plugins/insights/testing/expectInsightsIndex.mjs +18 -0
  173. package/dist/plugins/insights/testing/fixtures.d.mts +8 -0
  174. package/dist/plugins/insights/testing/fixtures.mjs +25 -0
  175. package/dist/plugins/insights/testing/index.d.mts +24 -0
  176. package/dist/plugins/insights/testing/index.mjs +25 -0
  177. package/dist/plugins/insights/testing/insightsModelTests.mjs +714 -0
  178. package/dist/plugins/insights/testing/modelTypes.d.mts +176 -0
  179. package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.d.mts +11 -0
  180. package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.mjs +107 -0
  181. package/dist/plugins/insights/testing/setupInsightsModelTestSuite.d.mts +11 -0
  182. package/dist/plugins/insights/testing/setupInsightsModelTestSuite.mjs +31 -0
  183. package/dist/plugins/insights/testing/types.d.mts +26 -0
  184. package/dist/{insights → plugins/insights}/types.d.cts +3 -2
  185. package/dist/{insights → plugins/insights}/types.d.mts +3 -2
  186. package/package.json +18 -7
  187. package/src/adapters/drizzle.conformance.integration.spec.ts +2 -2
  188. package/src/adapters/drizzle.readBudgets.integration.spec.ts +6 -4
  189. package/src/adapters/drizzle.spec.ts +15 -7
  190. package/src/adapters/drizzle.ts +6 -6
  191. package/src/adapters/kysely.conformance.integration.spec.ts +2 -2
  192. package/src/adapters/kysely.readBudgets.integration.spec.ts +4 -2
  193. package/src/adapters/kysely.spec.ts +13 -9
  194. package/src/adapters/kysely.ts +2 -2
  195. package/src/adapters/mongodb.integration.spec.ts +98 -7
  196. package/src/adapters/mongodb.ts +2 -2
  197. package/src/adapters/mongodbAdapter.ts +14 -0
  198. package/src/adapters/prisma.conformance.integration.spec.ts +2 -2
  199. package/src/adapters/prisma.integration.spec.ts +16 -8
  200. package/src/adapters/prisma.readBudgets.integration.spec.ts +5 -2
  201. package/src/adapters/prisma.spec.ts +17 -9
  202. package/src/adapters/prisma.ts +6 -6
  203. package/src/adapters/prismaTestClients.ts +8 -1
  204. package/src/assembly/assemblePlugins.ts +73 -40
  205. package/src/assembly/assembly.spec.ts +63 -11
  206. package/src/assembly/assembly.types.spec.ts +50 -2
  207. package/src/assembly/clientPlugins.ts +113 -0
  208. package/src/assembly/configError.ts +4 -0
  209. package/src/assembly/databasePlugins.ts +11 -5
  210. package/src/assembly/pluginCli.spec.ts +254 -0
  211. package/src/assembly/pluginCli.ts +248 -0
  212. package/src/assembly/{builtInRoutes.spec.ts → pluginRoutes.spec.ts} +10 -37
  213. package/src/createHotUpdaterCore.ts +21 -17
  214. package/src/database/aggregateBatching.spec.ts +577 -0
  215. package/src/database/aggregateBatching.ts +803 -0
  216. package/src/{insights/errors.spec.ts → database/busy.spec.ts} +2 -5
  217. package/src/{insights/errors.ts → database/busy.ts} +1 -13
  218. package/src/database/database.ts +39 -8
  219. package/src/database/definitions.ts +4 -0
  220. package/src/database/engineAggregates.spec.ts +4 -7
  221. package/src/database/engineAggregates.ts +5 -9
  222. package/src/database/engineReads.ts +7 -5
  223. package/src/database/engineTransaction.ts +1 -7
  224. package/src/database/fence.spec.ts +5 -5
  225. package/src/database/fence.ts +4 -0
  226. package/src/database/index.ts +13 -7
  227. package/src/database/kv/kvAdapter.batching.integration.spec.ts +15 -0
  228. package/src/database/kv/kvAdapter.conformance.integration.spec.ts +2 -0
  229. package/src/database/kv/kvAdapter.spec.ts +128 -1
  230. package/src/database/kv/kvAdapter.ts +30 -1
  231. package/src/database/kv/kvTestStore.ts +28 -1
  232. package/src/database/resolveSchema.ts +4 -1
  233. package/src/database/retention.spec.ts +314 -0
  234. package/src/database/retention.ts +129 -0
  235. package/src/database/schema.ts +44 -0
  236. package/src/database/sql/sqlAdapter.integration.spec.ts +4 -7
  237. package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +18 -4
  238. package/src/database/sql/sqlAdapter.spec.ts +91 -3
  239. package/src/database/sql/sqlAdapter.ts +20 -0
  240. package/src/database/sql/sqlSchema.ts +81 -0
  241. package/src/databaseTestSuite.spec.ts +9 -4
  242. package/src/db/coreDatabase.ts +153 -0
  243. package/src/db/engineSql.spec.ts +8 -7
  244. package/src/db/index.ts +19 -2
  245. package/src/db/pluginTables.spec.ts +57 -27
  246. package/src/db/types.ts +3 -3
  247. package/src/diff.ts +6 -0
  248. package/src/handler-standalone.integration.spec.ts +2 -3
  249. package/src/handler.ts +1 -32
  250. package/src/handlerReleaseCatalogRoutes.ts +26 -2
  251. package/src/index.ts +0 -10
  252. package/src/{apiKeys.integration.spec.ts → plugins/api-keys/apiKeys.integration.spec.ts} +4 -4
  253. package/src/{apiKeys.spec.ts → plugins/api-keys/apiKeys.spec.ts} +3 -3
  254. package/src/{apiKeys.ts → plugins/api-keys/apiKeys.ts} +1 -1
  255. package/src/plugins/api-keys/apiKeysPlugin.spec.ts +11 -15
  256. package/src/plugins/api-keys/cli.spec.ts +187 -0
  257. package/src/plugins/api-keys/cli.ts +140 -0
  258. package/src/plugins/api-keys/index.ts +48 -41
  259. package/src/plugins/api-keys/model.ts +21 -2
  260. package/src/plugins/definePlugin.ts +144 -2
  261. package/src/plugins/index.ts +20 -2
  262. package/src/plugins/insights/contract.spec.ts +285 -0
  263. package/src/plugins/insights/contract.ts +372 -0
  264. package/src/{insights → plugins/insights}/domain.ts +73 -15
  265. package/src/plugins/insights/errors.ts +11 -0
  266. package/src/{insights → plugins/insights}/eventInput.ts +189 -29
  267. package/src/plugins/insights/eventRow.ts +209 -0
  268. package/src/plugins/insights/index.ts +181 -45
  269. package/src/{insights → plugins/insights}/insights.integration.spec.ts +330 -34
  270. package/src/plugins/insights/insightsRollout.integration.spec.ts +1 -2
  271. package/src/plugins/insights/model.spec.ts +3 -5
  272. package/src/plugins/insights/model.ts +2 -3
  273. package/src/plugins/insights/modelTypes.ts +197 -0
  274. package/src/plugins/insights/overview.spec.ts +64 -0
  275. package/src/plugins/insights/overview.ts +214 -0
  276. package/src/{insights → plugins/insights}/provider.spec.ts +21 -10
  277. package/src/{insights → plugins/insights}/provider.ts +58 -21
  278. package/src/{insights → plugins/insights}/queryInput.ts +2 -2
  279. package/src/plugins/insights/reads.spec.ts +340 -52
  280. package/src/plugins/insights/reads.ts +453 -123
  281. package/src/plugins/insights/recordEvent.spec.ts +474 -20
  282. package/src/plugins/insights/recordEvent.ts +301 -63
  283. package/src/plugins/insights/retention.spec.ts +115 -0
  284. package/src/{insights → plugins/insights}/routes.ts +1 -31
  285. package/src/plugins/insights/schema.ts +356 -176
  286. package/src/plugins/insights/testing/expectInsightsIndex.spec.ts +42 -0
  287. package/src/plugins/insights/testing/expectInsightsIndex.ts +20 -0
  288. package/src/plugins/insights/testing/fixtures.ts +30 -0
  289. package/src/plugins/insights/testing/index.ts +45 -0
  290. package/src/plugins/insights/testing/insightsModelTests.ts +860 -0
  291. package/src/plugins/insights/testing/setupInsightsHttpTestSuite.ts +152 -0
  292. package/src/plugins/insights/testing/setupInsightsModelTestSuite.ts +36 -0
  293. package/src/plugins/insights/testing/types.ts +30 -0
  294. package/src/{insights → plugins/insights}/types.ts +1 -1
  295. package/src/readBudgets.testFixtures.ts +2 -2
  296. package/src/releaseCatalogRoutes.integration.spec.ts +7 -0
  297. package/src/retention.spec.ts +73 -0
  298. package/src/runtime.spec.ts +11 -12
  299. package/src/runtime.testFixtures.ts +7 -2
  300. package/src/testUtilsMutation.integration.spec.ts +2 -1
  301. package/src/testUtilsPackage.integration.spec.ts +7 -3
  302. package/dist/db/builtInDatabase.cjs +0 -104
  303. package/dist/db/builtInDatabase.d.cts +0 -38
  304. package/dist/db/builtInDatabase.d.mts +0 -38
  305. package/dist/db/builtInDatabase.mjs +0 -97
  306. package/dist/plugins/builtIn.cjs +0 -7
  307. package/dist/plugins/builtIn.mjs +0 -6
  308. package/src/db/builtInDatabase.ts +0 -149
  309. package/src/plugins/builtIn.ts +0 -5
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_settingsMigrator = require("../db/settingsMigrator.cjs");
3
- const require_builtInDatabase = require("../db/builtInDatabase.cjs");
3
+ const require_coreDatabase = require("../db/coreDatabase.cjs");
4
4
  const require_sqlAdapter = require("../database/sql/sqlAdapter.cjs");
5
5
  const require_sqlProviders = require("./sqlProviders.cjs");
6
6
  const require_engineDrizzleSchema = require("../db/engineDrizzleSchema.cjs");
@@ -16,19 +16,19 @@ const drizzleAdapter = (config) => {
16
16
  const provider = require_sqlProviders.checkSqlProvider("drizzleAdapter", config.provider);
17
17
  const executor = require_drizzleExecutor.drizzleExecutor(config.db, provider);
18
18
  return {
19
- ...require_builtInDatabase.createEngineDatabase({
19
+ ...require_coreDatabase.createEngineDatabase({
20
20
  name: "drizzle",
21
21
  adapter: require_sqlAdapter.createSqlAdapter({ executor })
22
22
  }),
23
23
  provider,
24
- generateSchema: ((version, _name, { schema } = require_builtInDatabase.builtInTarget) => {
25
- if (version !== "latest" && version !== require_builtInDatabase.builtInSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
24
+ generateSchema: ((version, _name, { schema } = require_coreDatabase.coreTarget) => {
25
+ if (version !== "latest" && version !== require_coreDatabase.coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
26
26
  return {
27
27
  code: require_engineDrizzleSchema.generateDrizzleEngineSchema(provider, schema),
28
28
  path: "hot-updater-schema.ts"
29
29
  };
30
30
  }),
31
- createMigrator: ({ settings } = require_builtInDatabase.builtInTarget) => require_settingsMigrator.createSettingsMigrator({
31
+ createMigrator: ({ settings } = require_coreDatabase.coreTarget) => require_settingsMigrator.createSettingsMigrator({
32
32
  adapterName: "drizzle",
33
33
  executor,
34
34
  settings,
@@ -1,5 +1,5 @@
1
1
  import { createSettingsMigrator } from "../db/settingsMigrator.mjs";
2
- import { builtInSettings, builtInTarget, createEngineDatabase } from "../db/builtInDatabase.mjs";
2
+ import { coreSettings, coreTarget, createEngineDatabase } from "../db/coreDatabase.mjs";
3
3
  import { createSqlAdapter } from "../database/sql/sqlAdapter.mjs";
4
4
  import { checkSqlProvider } from "./sqlProviders.mjs";
5
5
  import { generateDrizzleEngineSchema } from "../db/engineDrizzleSchema.mjs";
@@ -20,14 +20,14 @@ const drizzleAdapter = (config) => {
20
20
  adapter: createSqlAdapter({ executor })
21
21
  }),
22
22
  provider,
23
- generateSchema: ((version, _name, { schema } = builtInTarget) => {
24
- if (version !== "latest" && version !== builtInSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
23
+ generateSchema: ((version, _name, { schema } = coreTarget) => {
24
+ if (version !== "latest" && version !== coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
25
25
  return {
26
26
  code: generateDrizzleEngineSchema(provider, schema),
27
27
  path: "hot-updater-schema.ts"
28
28
  };
29
29
  }),
30
- createMigrator: ({ settings } = builtInTarget) => createSettingsMigrator({
30
+ createMigrator: ({ settings } = coreTarget) => createSettingsMigrator({
31
31
  adapterName: "drizzle",
32
32
  executor,
33
33
  settings,
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_builtInDatabase = require("../db/builtInDatabase.cjs");
2
+ const require_coreDatabase = require("../db/coreDatabase.cjs");
3
3
  const require_sqlAdapter = require("../database/sql/sqlAdapter.cjs");
4
4
  const require_engineSqlMigrator = require("../db/engineSqlMigrator.cjs");
5
5
  const require_kyselyExecutor = require("./kyselyExecutor.cjs");
@@ -14,12 +14,12 @@ const kyselyAdapter = (config) => {
14
14
  const provider = require_sqlProviders.checkSqlProvider("kyselyAdapter", config.provider);
15
15
  const executor = require_kyselyExecutor.kyselyExecutor(config.db, provider);
16
16
  return {
17
- ...require_builtInDatabase.createEngineDatabase({
17
+ ...require_coreDatabase.createEngineDatabase({
18
18
  name: "kysely",
19
19
  adapter: require_sqlAdapter.createSqlAdapter({ executor })
20
20
  }),
21
21
  provider,
22
- createMigrator: ({ schema, settings } = require_builtInDatabase.builtInTarget) => require_engineSqlMigrator.createEngineSqlMigrator({
22
+ createMigrator: ({ schema, settings } = require_coreDatabase.coreTarget) => require_engineSqlMigrator.createEngineSqlMigrator({
23
23
  adapterName: "kysely",
24
24
  executor,
25
25
  schema,
@@ -1,4 +1,4 @@
1
- import { builtInTarget, createEngineDatabase } from "../db/builtInDatabase.mjs";
1
+ import { coreTarget, createEngineDatabase } from "../db/coreDatabase.mjs";
2
2
  import { createSqlAdapter } from "../database/sql/sqlAdapter.mjs";
3
3
  import { createEngineSqlMigrator } from "../db/engineSqlMigrator.mjs";
4
4
  import { kyselyExecutor } from "./kyselyExecutor.mjs";
@@ -18,7 +18,7 @@ const kyselyAdapter = (config) => {
18
18
  adapter: createSqlAdapter({ executor })
19
19
  }),
20
20
  provider,
21
- createMigrator: ({ schema, settings } = builtInTarget) => createEngineSqlMigrator({
21
+ createMigrator: ({ schema, settings } = coreTarget) => createEngineSqlMigrator({
22
22
  adapterName: "kysely",
23
23
  executor,
24
24
  schema,
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_fence = require("../database/fence.cjs");
3
3
  const require_engineMigrator = require("../db/engineMigrator.cjs");
4
- const require_builtInDatabase = require("../db/builtInDatabase.cjs");
4
+ const require_coreDatabase = require("../db/coreDatabase.cjs");
5
5
  const require_mongodbAdapter = require("./mongodbAdapter.cjs");
6
6
  //#region src/adapters/mongodb.ts
7
7
  /** Settings rows by their `key` field: the engine's rows and a v0 database's alike. */
@@ -17,12 +17,12 @@ const readSettings = (client) => async () => {
17
17
  const mongoAdapter = (config) => {
18
18
  const adapter = require_mongodbAdapter.createMongoAdapter({ client: config.client });
19
19
  return {
20
- ...require_builtInDatabase.createEngineDatabase({
20
+ ...require_coreDatabase.createEngineDatabase({
21
21
  name: "mongodb",
22
22
  adapter
23
23
  }),
24
24
  provider: "mongodb",
25
- createMigrator: ({ schema, settings } = require_builtInDatabase.builtInTarget) => require_engineMigrator.createEngineMigrator({
25
+ createMigrator: ({ schema, settings } = require_coreDatabase.coreTarget) => require_engineMigrator.createEngineMigrator({
26
26
  adapterName: "mongodb",
27
27
  adapter,
28
28
  schema,
@@ -1,6 +1,6 @@
1
1
  import { SETTINGS_TABLE } from "../database/fence.mjs";
2
2
  import { createEngineMigrator } from "../db/engineMigrator.mjs";
3
- import { builtInTarget, createEngineDatabase } from "../db/builtInDatabase.mjs";
3
+ import { coreTarget, createEngineDatabase } from "../db/coreDatabase.mjs";
4
4
  import { MongoTransactionUnsupportedError, createMongoAdapter } from "./mongodbAdapter.mjs";
5
5
  //#region src/adapters/mongodb.ts
6
6
  /** Settings rows by their `key` field: the engine's rows and a v0 database's alike. */
@@ -21,7 +21,7 @@ const mongoAdapter = (config) => {
21
21
  adapter
22
22
  }),
23
23
  provider: "mongodb",
24
- createMigrator: ({ schema, settings } = builtInTarget) => createEngineMigrator({
24
+ createMigrator: ({ schema, settings } = coreTarget) => createEngineMigrator({
25
25
  adapterName: "mongodb",
26
26
  adapter,
27
27
  schema,
@@ -14,10 +14,22 @@ const byId = (_id, v) => v === void 0 ? { _id } : {
14
14
  _id,
15
15
  [_hot_updater_plugin_core_internal.DATABASE_VERSION_COLUMN]: v
16
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
+ };
17
28
  /** Null columns are left out, so unique indexes skip them as SQL's do. */
18
29
  const toDocument = (table, row) => ({
19
30
  _id: idOf(table, (0, _hot_updater_plugin_core_internal.rowKey)(table, row)),
20
- ...Object.fromEntries(table.columns.flatMap(({ name }) => row[name] === null || row[name] === void 0 ? [] : [[name, row[name]]]))
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) }
21
33
  });
22
34
  /** `columns op bound` over a tuple prefix, expanded into ORs. */
23
35
  const compare = (columns, { values, inclusive }, op) => {
@@ -64,6 +76,10 @@ const createMongoAdapter = (options) => {
64
76
  const $unset = {};
65
77
  for (const [name, value] of Object.entries(op.set)) if (value === null) $unset[name] = "";
66
78
  else $set[name] = value;
79
+ if (op.table.retention) $set[TTL.name] = expireAt(op.table, {
80
+ ...op.previous,
81
+ ...op.set
82
+ });
67
83
  return update(byId(_id, op.guard.v), {
68
84
  $set,
69
85
  $unset
@@ -84,6 +100,7 @@ const createMongoAdapter = (options) => {
84
100
  if (by !== void 0) set[name] = { $add: [stored, by] };
85
101
  else if (start !== null) set[name] = stored;
86
102
  }
103
+ if (op.table.retention) set[TTL.name] = expireAt(op.table, op.init);
87
104
  await target.updateOne(byId(_id), [{ $set: set }], {
88
105
  upsert: true,
89
106
  session
@@ -163,6 +180,7 @@ const createMongoAdapter = (options) => {
163
180
  await client.db().createCollection(tablePrefix + table.name).catch((error) => {
164
181
  if (mongoError(error)?.code !== 48) throw error;
165
182
  });
183
+ if (table.retention) await collection(table).createIndexes([TTL]);
166
184
  if (table.indexes.length === 0) continue;
167
185
  await collection(table).createIndexes(table.indexes.map((index) => indexDescription(table, index)));
168
186
  }
@@ -14,10 +14,22 @@ const byId = (_id, v) => v === void 0 ? { _id } : {
14
14
  _id,
15
15
  [DATABASE_VERSION_COLUMN]: v
16
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
+ };
17
28
  /** Null columns are left out, so unique indexes skip them as SQL's do. */
18
29
  const toDocument = (table, row) => ({
19
30
  _id: idOf(table, rowKey(table, row)),
20
- ...Object.fromEntries(table.columns.flatMap(({ name }) => row[name] === null || row[name] === void 0 ? [] : [[name, row[name]]]))
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) }
21
33
  });
22
34
  /** `columns op bound` over a tuple prefix, expanded into ORs. */
23
35
  const compare = (columns, { values, inclusive }, op) => {
@@ -64,6 +76,10 @@ const createMongoAdapter = (options) => {
64
76
  const $unset = {};
65
77
  for (const [name, value] of Object.entries(op.set)) if (value === null) $unset[name] = "";
66
78
  else $set[name] = value;
79
+ if (op.table.retention) $set[TTL.name] = expireAt(op.table, {
80
+ ...op.previous,
81
+ ...op.set
82
+ });
67
83
  return update(byId(_id, op.guard.v), {
68
84
  $set,
69
85
  $unset
@@ -84,6 +100,7 @@ const createMongoAdapter = (options) => {
84
100
  if (by !== void 0) set[name] = { $add: [stored, by] };
85
101
  else if (start !== null) set[name] = stored;
86
102
  }
103
+ if (op.table.retention) set[TTL.name] = expireAt(op.table, op.init);
87
104
  await target.updateOne(byId(_id), [{ $set: set }], {
88
105
  upsert: true,
89
106
  session
@@ -163,6 +180,7 @@ const createMongoAdapter = (options) => {
163
180
  await client.db().createCollection(tablePrefix + table.name).catch((error) => {
164
181
  if (mongoError(error)?.code !== 48) throw error;
165
182
  });
183
+ if (table.retention) await collection(table).createIndexes([TTL]);
166
184
  if (table.indexes.length === 0) continue;
167
185
  await collection(table).createIndexes(table.indexes.map((index) => indexDescription(table, index)));
168
186
  }
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_settingsMigrator = require("../db/settingsMigrator.cjs");
3
- const require_builtInDatabase = require("../db/builtInDatabase.cjs");
3
+ const require_coreDatabase = require("../db/coreDatabase.cjs");
4
4
  const require_sqlAdapter = require("../database/sql/sqlAdapter.cjs");
5
5
  const require_sqlProviders = require("./sqlProviders.cjs");
6
6
  const require_enginePrismaSchema = require("../db/enginePrismaSchema.cjs");
@@ -16,19 +16,19 @@ const prismaAdapter = (config) => {
16
16
  const provider = require_sqlProviders.checkSqlProvider("prismaAdapter", config.provider);
17
17
  const executor = require_prismaExecutor.prismaExecutor(config.prisma, provider);
18
18
  return {
19
- ...require_builtInDatabase.createEngineDatabase({
19
+ ...require_coreDatabase.createEngineDatabase({
20
20
  name: "prisma",
21
21
  adapter: require_sqlAdapter.createSqlAdapter({ executor })
22
22
  }),
23
23
  provider,
24
- generateSchema: ((version, _name, { schema } = require_builtInDatabase.builtInTarget) => {
25
- if (version !== "latest" && version !== require_builtInDatabase.builtInSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
24
+ generateSchema: ((version, _name, { schema } = require_coreDatabase.coreTarget) => {
25
+ if (version !== "latest" && version !== require_coreDatabase.coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
26
26
  return {
27
27
  code: require_enginePrismaSchema.generatePrismaEngineSchema(provider, schema),
28
28
  path: "prisma/schema.prisma"
29
29
  };
30
30
  }),
31
- createMigrator: ({ schema, settings } = require_builtInDatabase.builtInTarget) => {
31
+ createMigrator: ({ schema, settings } = require_coreDatabase.coreTarget) => {
32
32
  const collations = require_enginePrismaSchema.prismaCollationStatements(provider, schema);
33
33
  return require_settingsMigrator.createSettingsMigrator({
34
34
  adapterName: "prisma",
@@ -1,5 +1,5 @@
1
1
  import { createSettingsMigrator } from "../db/settingsMigrator.mjs";
2
- import { builtInSettings, builtInTarget, createEngineDatabase } from "../db/builtInDatabase.mjs";
2
+ import { coreSettings, coreTarget, createEngineDatabase } from "../db/coreDatabase.mjs";
3
3
  import { createSqlAdapter } from "../database/sql/sqlAdapter.mjs";
4
4
  import { checkSqlProvider } from "./sqlProviders.mjs";
5
5
  import { generatePrismaEngineSchema, prismaCollationStatements } from "../db/enginePrismaSchema.mjs";
@@ -20,14 +20,14 @@ const prismaAdapter = (config) => {
20
20
  adapter: createSqlAdapter({ executor })
21
21
  }),
22
22
  provider,
23
- generateSchema: ((version, _name, { schema } = builtInTarget) => {
24
- if (version !== "latest" && version !== builtInSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
23
+ generateSchema: ((version, _name, { schema } = coreTarget) => {
24
+ if (version !== "latest" && version !== coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
25
25
  return {
26
26
  code: generatePrismaEngineSchema(provider, schema),
27
27
  path: "prisma/schema.prisma"
28
28
  };
29
29
  }),
30
- createMigrator: ({ schema, settings } = builtInTarget) => {
30
+ createMigrator: ({ schema, settings } = coreTarget) => {
31
31
  const collations = prismaCollationStatements(provider, schema);
32
32
  return createSettingsMigrator({
33
33
  adapterName: "prisma",
@@ -1,22 +1,28 @@
1
+ const require_aggregateBatching = require("../database/aggregateBatching.cjs");
2
+ const require_retention = require("../database/retention.cjs");
1
3
  const require_resolveSchema = require("../database/resolveSchema.cjs");
2
4
  const require_database = require("../database/database.cjs");
3
5
  const require_reads = require("../core/reads.cjs");
4
6
  const require_schema = require("../core/schema.cjs");
5
7
  const require_api = require("../core/api.cjs");
6
8
  const require_fence = require("../database/fence.cjs");
7
- const require_builtIn = require("../plugins/builtIn.cjs");
8
- const require_builtInDatabase = require("../db/builtInDatabase.cjs");
9
+ const require_coreDatabase = require("../db/coreDatabase.cjs");
10
+ const require_configError = require("./configError.cjs");
11
+ const require_clientPlugins = require("./clientPlugins.cjs");
9
12
  //#region src/assembly/assemblePlugins.ts
10
- /** A misconfigured `createHotUpdater` call, reported at startup. */
11
- var HotUpdaterConfigError = class extends Error {
12
- name = "HotUpdaterConfigError";
13
- };
14
13
  const PLUGIN_KEYS = /* @__PURE__ */ new Set([
15
14
  "id",
16
15
  "provides",
17
16
  "schemaVersion",
18
17
  "schema",
19
- "init"
18
+ "namespace",
19
+ "init",
20
+ "cli"
21
+ ]);
22
+ const CLI_KEYS = /* @__PURE__ */ new Set([
23
+ "commands",
24
+ "clientCredential",
25
+ "clientPlugin"
20
26
  ]);
21
27
  const INSTANCE_KEYS = /* @__PURE__ */ new Set([
22
28
  "api",
@@ -30,11 +36,12 @@ const METHODS = /* @__PURE__ */ new Set([
30
36
  "PATCH",
31
37
  "DELETE"
32
38
  ]);
33
- const BUILT_IN_ID = /^[a-z][A-Za-z0-9]*$/u;
34
- const PLUGIN_ID = /^[a-z][a-z0-9_]*$/u;
39
+ /** An id that prefixes table names is a SQL name; one that does not may use camelCase. */
40
+ const PREFIX_ID = /^[a-z][a-z0-9_]*$/u;
41
+ const UNPREFIXED_ID = /^[a-z][A-Za-z0-9_]*$/u;
35
42
  const PATH = /^(\/(:?[A-Za-z0-9_.~-]+))+$/u;
36
43
  const fail = (message) => {
37
- throw new HotUpdaterConfigError(message);
44
+ throw new require_configError.HotUpdaterConfigError(message);
38
45
  };
39
46
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
40
47
  const checkPlugin = (value, at) => {
@@ -43,12 +50,18 @@ const checkPlugin = (value, at) => {
43
50
  const unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));
44
51
  if (unknown !== void 0) fail(`${at} has an unknown key "${unknown}".`);
45
52
  const plugin = value;
46
- const pattern = plugin[require_builtIn.builtInPlugin] ? BUILT_IN_ID : PLUGIN_ID;
53
+ if (plugin.namespace !== void 0 && plugin.namespace !== false) fail(`${at} may only set namespace: false.`);
54
+ const pattern = plugin.namespace === false ? UNPREFIXED_ID : PREFIX_ID;
47
55
  if (typeof plugin.id !== "string" || !pattern.test(plugin.id)) fail(`${at} needs an id matching ${pattern.source}.`);
48
56
  if (plugin.id === require_schema.coreModule.id) fail(`${at} uses the id "core", which is core's own.`);
49
57
  if (typeof plugin.schemaVersion !== "string" || !isRecord(plugin.schema) || typeof plugin.init !== "function") fail(`Plugin "${plugin.id}" needs a schemaVersion, a schema, and init.`);
50
58
  const provides = plugin.provides;
51
59
  if (provides !== void 0 && (!isRecord(provides) || Object.entries(provides).some(([key, flag]) => key !== "clientAuth" || flag !== true))) fail(`Plugin "${plugin.id}" may only declare provides: { clientAuth: true }.`);
60
+ const cli = value.cli;
61
+ if (cli !== void 0) {
62
+ if (!isRecord(cli) || Object.keys(cli).some((key) => !CLI_KEYS.has(key)) || cli.commands !== void 0 && !Array.isArray(cli.commands)) fail(`Plugin "${plugin.id}" cli may only hold commands (an array), clientCredential, and clientPlugin.`);
63
+ if (cli.clientCredential !== void 0 && plugin.provides?.clientAuth !== true) fail(`Plugin "${plugin.id}" adds cli.clientCredential without declaring provides: { clientAuth: true }.`);
64
+ }
52
65
  return plugin;
53
66
  };
54
67
  const checkEndpoint = (id, value) => {
@@ -82,7 +95,7 @@ const checkInstance = (plugin, instance) => {
82
95
  * database's storage adapter, and collects APIs, endpoints, and clientAuth.
83
96
  * Core's reads run on the same engine, so plugins read core through `ctx.core`.
84
97
  */
85
- const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFileUrl: async () => null }, verify = false, onCachedRoutesChange } = {}) => {
98
+ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFileUrl: async () => null }, verify = false, onCachedRoutesChange, batching } = {}) => {
86
99
  if (!Array.isArray(value)) return fail("plugins must be an array of plugins.");
87
100
  const plugins = value.map((plugin, position) => checkPlugin(plugin, `plugins[${position}]`));
88
101
  const ids = /* @__PURE__ */ new Set();
@@ -90,22 +103,27 @@ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFi
90
103
  if (ids.has(id)) fail(`Plugin "${id}" is registered twice.`);
91
104
  ids.add(id);
92
105
  }
93
- const modules = plugins.map((plugin) => ({
94
- id: plugin.id,
95
- schema: plugin.schema,
96
- ...plugin[require_builtIn.builtInPlugin] ? {} : { namespace: plugin.id }
97
- }));
98
- const added = modules.filter(({ namespace }) => namespace !== void 0);
99
- if (added.length > 0) {
100
- const taken = added.find(({ id }) => require_builtInDatabase.builtInModules.some((module) => module.id === id));
101
- if (taken !== void 0) fail(`Plugin "${taken.id}" uses a built-in plugin's id.`);
102
- require_resolveSchema.validateSchema([...require_builtInDatabase.builtInModules, ...added]);
103
- }
106
+ require_clientPlugins.clientPluginsOf(plugins);
107
+ const modules = plugins.map(require_coreDatabase.pluginModule);
108
+ if (modules.length > 0) require_resolveSchema.validateSchema([require_schema.coreModule, ...modules]);
104
109
  const name = require_fence.fencedName(adapter);
110
+ const fenced = name === void 0 || plugins.length === 0 ? adapter : require_fence.withSchemaFence(adapter, name, require_coreDatabase.pluginSettings(plugins));
111
+ const schema = require_resolveSchema.resolveSchema([
112
+ require_schema.coreModule,
113
+ ...modules,
114
+ ...batching === void 0 ? [] : [require_aggregateBatching.aggregateBatchingModule]
115
+ ]);
105
116
  const engine = require_database.createDatabaseEngine({
106
- adapter: name === void 0 || added.length === 0 ? adapter : require_fence.withSchemaFence(adapter, name, require_builtInDatabase.addedSettings(plugins)),
107
- schema: require_resolveSchema.resolveSchema([require_schema.coreModule, ...modules]),
108
- verify
117
+ adapter: verify ? fenced : require_retention.pruneDuringWrites(fenced, schema.tables, {
118
+ leaseTable: require_fence.SETTINGS_TABLE,
119
+ now
120
+ }),
121
+ schema,
122
+ verify,
123
+ ...batching === void 0 ? {} : {
124
+ batching,
125
+ now
126
+ }
109
127
  });
110
128
  const coreDatabase = engine.database(require_schema.coreModule);
111
129
  const core = require_api.createCoreApi(coreDatabase, storage, {
@@ -139,9 +157,10 @@ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFi
139
157
  api,
140
158
  endpoints,
141
159
  ...clientAuth === void 0 ? {} : { clientAuth },
142
- ...verify ? { measureReads: engine.measureReads } : {}
160
+ ...verify ? { measureReads: engine.measureReads } : {},
161
+ flush: engine.flush
143
162
  };
144
163
  };
145
164
  //#endregion
146
- exports.HotUpdaterConfigError = HotUpdaterConfigError;
165
+ exports.HotUpdaterConfigError = require_configError.HotUpdaterConfigError;
147
166
  exports.assemblePlugins = assemblePlugins;
@@ -1,12 +1,8 @@
1
1
  import "../database/engine.cjs";
2
2
  import "../core/reads.cjs";
3
- import "../core/api.cjs";
4
3
  import "../plugins/definePlugin.cjs";
4
+ import "../core/api.cjs";
5
+ import { HotUpdaterConfigError } from "./configError.cjs";
6
+ import { AggregateBatching } from "@hot-updater/plugin-core";
5
7
  import { DatabaseAdapter } from "@hot-updater/plugin-core/internal";
6
- //#region src/assembly/assemblePlugins.d.ts
7
- /** A misconfigured `createHotUpdater` call, reported at startup. */
8
- declare class HotUpdaterConfigError extends Error {
9
- readonly name = "HotUpdaterConfigError";
10
- }
11
- //#endregion
12
8
  export { HotUpdaterConfigError };
@@ -1,12 +1,8 @@
1
1
  import "../database/engine.mjs";
2
2
  import "../core/reads.mjs";
3
- import "../core/api.mjs";
4
3
  import "../plugins/definePlugin.mjs";
4
+ import "../core/api.mjs";
5
+ import { HotUpdaterConfigError } from "./configError.mjs";
6
+ import { AggregateBatching } from "@hot-updater/plugin-core";
5
7
  import { DatabaseAdapter } from "@hot-updater/plugin-core/internal";
6
- //#region src/assembly/assemblePlugins.d.ts
7
- /** A misconfigured `createHotUpdater` call, reported at startup. */
8
- declare class HotUpdaterConfigError extends Error {
9
- readonly name = "HotUpdaterConfigError";
10
- }
11
- //#endregion
12
8
  export { HotUpdaterConfigError };
@@ -1,22 +1,28 @@
1
+ import { aggregateBatchingModule } from "../database/aggregateBatching.mjs";
2
+ import { pruneDuringWrites } from "../database/retention.mjs";
1
3
  import { resolveSchema, validateSchema } from "../database/resolveSchema.mjs";
2
4
  import { createDatabaseEngine } from "../database/database.mjs";
3
5
  import { createCoreReads } from "../core/reads.mjs";
4
6
  import { coreModule } from "../core/schema.mjs";
5
7
  import { createCoreApi } from "../core/api.mjs";
6
- import { fencedName, withSchemaFence } from "../database/fence.mjs";
7
- import { builtInPlugin } from "../plugins/builtIn.mjs";
8
- import { addedSettings, builtInModules } from "../db/builtInDatabase.mjs";
8
+ import { SETTINGS_TABLE, fencedName, withSchemaFence } from "../database/fence.mjs";
9
+ import { pluginModule, pluginSettings } from "../db/coreDatabase.mjs";
10
+ import { HotUpdaterConfigError } from "./configError.mjs";
11
+ import { clientPluginsOf } from "./clientPlugins.mjs";
9
12
  //#region src/assembly/assemblePlugins.ts
10
- /** A misconfigured `createHotUpdater` call, reported at startup. */
11
- var HotUpdaterConfigError = class extends Error {
12
- name = "HotUpdaterConfigError";
13
- };
14
13
  const PLUGIN_KEYS = /* @__PURE__ */ new Set([
15
14
  "id",
16
15
  "provides",
17
16
  "schemaVersion",
18
17
  "schema",
19
- "init"
18
+ "namespace",
19
+ "init",
20
+ "cli"
21
+ ]);
22
+ const CLI_KEYS = /* @__PURE__ */ new Set([
23
+ "commands",
24
+ "clientCredential",
25
+ "clientPlugin"
20
26
  ]);
21
27
  const INSTANCE_KEYS = /* @__PURE__ */ new Set([
22
28
  "api",
@@ -30,8 +36,9 @@ const METHODS = /* @__PURE__ */ new Set([
30
36
  "PATCH",
31
37
  "DELETE"
32
38
  ]);
33
- const BUILT_IN_ID = /^[a-z][A-Za-z0-9]*$/u;
34
- const PLUGIN_ID = /^[a-z][a-z0-9_]*$/u;
39
+ /** An id that prefixes table names is a SQL name; one that does not may use camelCase. */
40
+ const PREFIX_ID = /^[a-z][a-z0-9_]*$/u;
41
+ const UNPREFIXED_ID = /^[a-z][A-Za-z0-9_]*$/u;
35
42
  const PATH = /^(\/(:?[A-Za-z0-9_.~-]+))+$/u;
36
43
  const fail = (message) => {
37
44
  throw new HotUpdaterConfigError(message);
@@ -43,12 +50,18 @@ const checkPlugin = (value, at) => {
43
50
  const unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));
44
51
  if (unknown !== void 0) fail(`${at} has an unknown key "${unknown}".`);
45
52
  const plugin = value;
46
- const pattern = plugin[builtInPlugin] ? BUILT_IN_ID : PLUGIN_ID;
53
+ if (plugin.namespace !== void 0 && plugin.namespace !== false) fail(`${at} may only set namespace: false.`);
54
+ const pattern = plugin.namespace === false ? UNPREFIXED_ID : PREFIX_ID;
47
55
  if (typeof plugin.id !== "string" || !pattern.test(plugin.id)) fail(`${at} needs an id matching ${pattern.source}.`);
48
56
  if (plugin.id === coreModule.id) fail(`${at} uses the id "core", which is core's own.`);
49
57
  if (typeof plugin.schemaVersion !== "string" || !isRecord(plugin.schema) || typeof plugin.init !== "function") fail(`Plugin "${plugin.id}" needs a schemaVersion, a schema, and init.`);
50
58
  const provides = plugin.provides;
51
59
  if (provides !== void 0 && (!isRecord(provides) || Object.entries(provides).some(([key, flag]) => key !== "clientAuth" || flag !== true))) fail(`Plugin "${plugin.id}" may only declare provides: { clientAuth: true }.`);
60
+ const cli = value.cli;
61
+ if (cli !== void 0) {
62
+ if (!isRecord(cli) || Object.keys(cli).some((key) => !CLI_KEYS.has(key)) || cli.commands !== void 0 && !Array.isArray(cli.commands)) fail(`Plugin "${plugin.id}" cli may only hold commands (an array), clientCredential, and clientPlugin.`);
63
+ if (cli.clientCredential !== void 0 && plugin.provides?.clientAuth !== true) fail(`Plugin "${plugin.id}" adds cli.clientCredential without declaring provides: { clientAuth: true }.`);
64
+ }
52
65
  return plugin;
53
66
  };
54
67
  const checkEndpoint = (id, value) => {
@@ -82,7 +95,7 @@ const checkInstance = (plugin, instance) => {
82
95
  * database's storage adapter, and collects APIs, endpoints, and clientAuth.
83
96
  * Core's reads run on the same engine, so plugins read core through `ctx.core`.
84
97
  */
85
- const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFileUrl: async () => null }, verify = false, onCachedRoutesChange } = {}) => {
98
+ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFileUrl: async () => null }, verify = false, onCachedRoutesChange, batching } = {}) => {
86
99
  if (!Array.isArray(value)) return fail("plugins must be an array of plugins.");
87
100
  const plugins = value.map((plugin, position) => checkPlugin(plugin, `plugins[${position}]`));
88
101
  const ids = /* @__PURE__ */ new Set();
@@ -90,22 +103,27 @@ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFi
90
103
  if (ids.has(id)) fail(`Plugin "${id}" is registered twice.`);
91
104
  ids.add(id);
92
105
  }
93
- const modules = plugins.map((plugin) => ({
94
- id: plugin.id,
95
- schema: plugin.schema,
96
- ...plugin[builtInPlugin] ? {} : { namespace: plugin.id }
97
- }));
98
- const added = modules.filter(({ namespace }) => namespace !== void 0);
99
- if (added.length > 0) {
100
- const taken = added.find(({ id }) => builtInModules.some((module) => module.id === id));
101
- if (taken !== void 0) fail(`Plugin "${taken.id}" uses a built-in plugin's id.`);
102
- validateSchema([...builtInModules, ...added]);
103
- }
106
+ clientPluginsOf(plugins);
107
+ const modules = plugins.map(pluginModule);
108
+ if (modules.length > 0) validateSchema([coreModule, ...modules]);
104
109
  const name = fencedName(adapter);
110
+ const fenced = name === void 0 || plugins.length === 0 ? adapter : withSchemaFence(adapter, name, pluginSettings(plugins));
111
+ const schema = resolveSchema([
112
+ coreModule,
113
+ ...modules,
114
+ ...batching === void 0 ? [] : [aggregateBatchingModule]
115
+ ]);
105
116
  const engine = createDatabaseEngine({
106
- adapter: name === void 0 || added.length === 0 ? adapter : withSchemaFence(adapter, name, addedSettings(plugins)),
107
- schema: resolveSchema([coreModule, ...modules]),
108
- verify
117
+ adapter: verify ? fenced : pruneDuringWrites(fenced, schema.tables, {
118
+ leaseTable: SETTINGS_TABLE,
119
+ now
120
+ }),
121
+ schema,
122
+ verify,
123
+ ...batching === void 0 ? {} : {
124
+ batching,
125
+ now
126
+ }
109
127
  });
110
128
  const coreDatabase = engine.database(coreModule);
111
129
  const core = createCoreApi(coreDatabase, storage, {
@@ -139,7 +157,8 @@ const assemblePlugins = (value, adapter, { now = Date.now, storage = { resolveFi
139
157
  api,
140
158
  endpoints,
141
159
  ...clientAuth === void 0 ? {} : { clientAuth },
142
- ...verify ? { measureReads: engine.measureReads } : {}
160
+ ...verify ? { measureReads: engine.measureReads } : {},
161
+ flush: engine.flush
143
162
  };
144
163
  };
145
164
  //#endregion