@hot-updater/server 1.0.0-rc.18 → 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.
- package/LICENSE +12 -14
- package/dist/adapters/drizzle.cjs +6 -8
- package/dist/adapters/drizzle.d.cts +2 -2
- package/dist/adapters/drizzle.d.mts +2 -2
- package/dist/adapters/drizzle.mjs +1 -3
- package/dist/adapters/drizzleExecutor.d.cts +1 -1
- package/dist/adapters/drizzleExecutor.d.mts +1 -1
- package/dist/adapters/kysely.cjs +4 -6
- package/dist/adapters/kysely.d.cts +3 -3
- package/dist/adapters/kysely.d.mts +3 -3
- package/dist/adapters/kysely.mjs +1 -3
- package/dist/adapters/kyselyExecutor.d.cts +1 -2
- package/dist/adapters/kyselyExecutor.d.mts +1 -2
- package/dist/adapters/mongodb.cjs +10 -21
- package/dist/adapters/mongodb.d.cts +1 -1
- package/dist/adapters/mongodb.d.mts +1 -1
- package/dist/adapters/mongodb.mjs +9 -20
- package/dist/adapters/mongodbAdapter.cjs +11 -11
- package/dist/adapters/mongodbAdapter.d.cts +1 -1
- package/dist/adapters/mongodbAdapter.d.mts +1 -1
- package/dist/adapters/mongodbAdapter.mjs +1 -1
- package/dist/adapters/prisma.cjs +7 -9
- package/dist/adapters/prisma.d.cts +1 -1
- package/dist/adapters/prisma.d.mts +1 -1
- package/dist/adapters/prisma.mjs +1 -3
- package/dist/adapters/prismaExecutor.cjs +2 -3
- package/dist/adapters/prismaExecutor.mjs +1 -2
- package/dist/adapters/sqlProviders.cjs +7 -2
- package/dist/adapters/sqlProviders.mjs +6 -1
- package/dist/assembly/assemblePlugins.cjs +26 -48
- package/dist/assembly/assemblePlugins.d.cts +2 -5
- package/dist/assembly/assemblePlugins.d.mts +2 -5
- package/dist/assembly/assemblePlugins.mjs +19 -45
- package/dist/assembly/clientPlugins.cjs +6 -4
- package/dist/assembly/clientPlugins.mjs +2 -0
- package/dist/assembly/configError.d.cts +1 -6
- package/dist/assembly/configError.d.mts +1 -6
- package/dist/assembly/configError.mjs +1 -6
- package/dist/core/api.cjs +0 -40
- package/dist/core/api.d.cts +5 -16
- package/dist/core/api.d.mts +5 -16
- package/dist/core/api.mjs +1 -37
- package/dist/core/baseCandidates.cjs +0 -43
- package/dist/core/baseCandidates.mjs +2 -43
- package/dist/core/operations.cjs +13 -12
- package/dist/core/operations.mjs +6 -5
- package/dist/core/reads.cjs +4 -4
- package/dist/core/reads.d.cts +2 -41
- package/dist/core/reads.d.mts +2 -41
- package/dist/core/reads.mjs +3 -3
- package/dist/core/releases.cjs +6 -6
- package/dist/core/releases.mjs +1 -1
- package/dist/core/writes.cjs +2 -2
- package/dist/core/writes.mjs +1 -1
- package/dist/createHotUpdaterCore.cjs +39 -39
- package/dist/createHotUpdaterCore.d.cts +61 -8
- package/dist/createHotUpdaterCore.d.mts +61 -8
- package/dist/createHotUpdaterCore.mjs +35 -32
- package/dist/db/engineDrizzleSchema.cjs +3 -4
- package/dist/db/engineDrizzleSchema.mjs +1 -2
- package/dist/db/enginePrismaSchema.cjs +4 -5
- package/dist/db/enginePrismaSchema.d.cts +1 -1
- package/dist/db/enginePrismaSchema.d.mts +1 -1
- package/dist/db/enginePrismaSchema.mjs +1 -2
- package/dist/db/releaseCatalog.cjs +6 -6
- package/dist/db/releaseCatalog.mjs +1 -1
- package/dist/db/updateArtifacts.cjs +6 -6
- package/dist/db/updateArtifacts.mjs +1 -1
- package/dist/handler.cjs +3 -4
- package/dist/handler.mjs +1 -1
- package/dist/handlerAdminRoutes.cjs +1 -2
- package/dist/handlerAdminRoutes.mjs +1 -2
- package/dist/handlerVersionRoutes.cjs +2 -2
- package/dist/handlerVersionRoutes.mjs +2 -2
- package/dist/index.cjs +9 -2
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +2 -1
- package/dist/node.cjs +3 -6
- package/dist/node.d.cts +3 -3
- package/dist/node.d.mts +3 -3
- package/dist/node.mjs +4 -4
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/api-keys/index.cjs +8 -52
- package/dist/plugins/api-keys/index.d.cts +1 -84
- package/dist/plugins/api-keys/index.d.mts +1 -84
- package/dist/plugins/api-keys/index.mjs +2 -49
- package/dist/plugins/definePlugin.d.cts +2 -200
- package/dist/plugins/definePlugin.d.mts +2 -200
- package/dist/plugins/insights/index.cjs +7 -126
- package/dist/plugins/insights/index.d.cts +1 -398
- package/dist/plugins/insights/index.d.mts +1 -398
- package/dist/plugins/insights/index.mjs +2 -121
- package/dist/plugins/official.cjs +30 -0
- package/dist/plugins/official.mjs +29 -0
- package/dist/storageAccess.cjs +13 -10
- package/dist/storageAccess.mjs +13 -10
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.mts +1 -1
- package/package.json +15 -37
- package/dist/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/assembly/clientPlugins.d.cts +0 -16
- package/dist/assembly/clientPlugins.d.mts +0 -16
- package/dist/assembly/configError.cjs +0 -7
- package/dist/assembly/databasePlugins.cjs +0 -27
- package/dist/assembly/databasePlugins.d.cts +0 -43
- package/dist/assembly/databasePlugins.d.mts +0 -43
- package/dist/assembly/databasePlugins.mjs +0 -26
- package/dist/assembly/pluginCli.cjs +0 -125
- package/dist/assembly/pluginCli.d.cts +0 -59
- package/dist/assembly/pluginCli.d.mts +0 -59
- package/dist/assembly/pluginCli.mjs +0 -121
- package/dist/core/baseCandidates.d.cts +0 -17
- package/dist/core/baseCandidates.d.mts +0 -17
- package/dist/core/schema.cjs +0 -279
- package/dist/core/schema.d.cts +0 -307
- package/dist/core/schema.d.mts +0 -307
- package/dist/core/schema.mjs +0 -277
- package/dist/database/aggregateBatching.cjs +0 -626
- package/dist/database/aggregateBatching.d.cts +0 -10
- package/dist/database/aggregateBatching.d.mts +0 -10
- package/dist/database/aggregateBatching.mjs +0 -625
- package/dist/database/busy.cjs +0 -36
- package/dist/database/busy.d.cts +0 -12
- package/dist/database/busy.d.mts +0 -12
- package/dist/database/busy.mjs +0 -36
- package/dist/database/cursor.cjs +0 -44
- package/dist/database/cursor.d.cts +0 -7
- package/dist/database/cursor.d.mts +0 -7
- package/dist/database/cursor.mjs +0 -40
- package/dist/database/database.cjs +0 -63
- package/dist/database/database.d.cts +0 -136
- package/dist/database/database.d.mts +0 -136
- package/dist/database/database.mjs +0 -63
- package/dist/database/definitions.d.cts +0 -78
- package/dist/database/definitions.d.mts +0 -78
- package/dist/database/engine.cjs +0 -37
- package/dist/database/engine.d.cts +0 -41
- package/dist/database/engine.d.mts +0 -41
- package/dist/database/engine.mjs +0 -37
- package/dist/database/engineAggregates.cjs +0 -118
- package/dist/database/engineAggregates.mjs +0 -115
- package/dist/database/engineReads.cjs +0 -182
- package/dist/database/engineReads.d.cts +0 -35
- package/dist/database/engineReads.d.mts +0 -35
- package/dist/database/engineReads.mjs +0 -181
- package/dist/database/engineTransaction.cjs +0 -399
- package/dist/database/engineTransaction.d.cts +0 -26
- package/dist/database/engineTransaction.d.mts +0 -26
- package/dist/database/engineTransaction.mjs +0 -398
- package/dist/database/errors.cjs +0 -27
- package/dist/database/errors.d.cts +0 -21
- package/dist/database/errors.d.mts +0 -21
- package/dist/database/errors.mjs +0 -24
- package/dist/database/fence.cjs +0 -125
- package/dist/database/fence.d.cts +0 -42
- package/dist/database/fence.d.mts +0 -42
- package/dist/database/fence.mjs +0 -117
- package/dist/database/index.cjs +0 -136
- package/dist/database/index.d.cts +0 -18
- package/dist/database/index.d.mts +0 -18
- package/dist/database/index.mjs +0 -16
- package/dist/database/kv/kvAdapter.cjs +0 -285
- package/dist/database/kv/kvAdapter.d.cts +0 -109
- package/dist/database/kv/kvAdapter.d.mts +0 -109
- package/dist/database/kv/kvAdapter.mjs +0 -284
- package/dist/database/resolveSchema.cjs +0 -199
- package/dist/database/resolveSchema.d.cts +0 -42
- package/dist/database/resolveSchema.d.mts +0 -42
- package/dist/database/resolveSchema.mjs +0 -196
- package/dist/database/retention.cjs +0 -92
- package/dist/database/retention.mjs +0 -90
- package/dist/database/schema.cjs +0 -24
- package/dist/database/schema.d.cts +0 -90
- package/dist/database/schema.d.mts +0 -90
- package/dist/database/schema.mjs +0 -23
- package/dist/database/sql/sqlAdapter.cjs +0 -290
- package/dist/database/sql/sqlAdapter.d.cts +0 -46
- package/dist/database/sql/sqlAdapter.d.mts +0 -46
- package/dist/database/sql/sqlAdapter.mjs +0 -287
- package/dist/database/sql/sqlSchema.cjs +0 -171
- package/dist/database/sql/sqlSchema.d.cts +0 -8
- package/dist/database/sql/sqlSchema.d.mts +0 -8
- package/dist/database/sql/sqlSchema.mjs +0 -165
- package/dist/db/coreDatabase.cjs +0 -85
- package/dist/db/coreDatabase.d.cts +0 -57
- package/dist/db/coreDatabase.d.mts +0 -57
- package/dist/db/coreDatabase.mjs +0 -78
- package/dist/db/createBundleDiff.cjs +0 -144
- package/dist/db/createBundleDiff.d.cts +0 -17
- package/dist/db/createBundleDiff.d.mts +0 -17
- package/dist/db/createBundleDiff.mjs +0 -141
- package/dist/db/engineMigrator.cjs +0 -53
- package/dist/db/engineMigrator.mjs +0 -53
- package/dist/db/engineSql.cjs +0 -26
- package/dist/db/engineSql.d.cts +0 -17
- package/dist/db/engineSql.d.mts +0 -17
- package/dist/db/engineSql.mjs +0 -25
- package/dist/db/engineSqlMigrator.cjs +0 -66
- package/dist/db/engineSqlMigrator.mjs +0 -66
- package/dist/db/fixedMigratorShared.cjs +0 -12
- package/dist/db/fixedMigratorShared.mjs +0 -11
- package/dist/db/index.cjs +0 -50
- package/dist/db/index.d.cts +0 -23
- package/dist/db/index.d.mts +0 -23
- package/dist/db/index.mjs +0 -33
- package/dist/db/releaseCatalog.d.cts +0 -16
- package/dist/db/releaseCatalog.d.mts +0 -16
- package/dist/db/schemaSettings.cjs +0 -63
- package/dist/db/schemaSettings.d.cts +0 -12
- package/dist/db/schemaSettings.d.mts +0 -12
- package/dist/db/schemaSettings.mjs +0 -62
- package/dist/db/settingsMigrator.cjs +0 -92
- package/dist/db/settingsMigrator.mjs +0 -89
- package/dist/db/types.cjs +0 -11
- package/dist/db/types.d.cts +0 -78
- package/dist/db/types.d.mts +0 -78
- package/dist/db/types.mjs +0 -10
- package/dist/diff.cjs +0 -3
- package/dist/diff.d.cts +0 -2
- package/dist/diff.d.mts +0 -2
- package/dist/diff.mjs +0 -2
- package/dist/plugins/api-keys/apiKeys.cjs +0 -139
- package/dist/plugins/api-keys/apiKeys.d.cts +0 -27
- package/dist/plugins/api-keys/apiKeys.d.mts +0 -27
- package/dist/plugins/api-keys/apiKeys.mjs +0 -129
- package/dist/plugins/api-keys/cli.cjs +0 -115
- package/dist/plugins/api-keys/cli.mjs +0 -114
- package/dist/plugins/api-keys/model.cjs +0 -58
- package/dist/plugins/api-keys/model.d.cts +0 -26
- package/dist/plugins/api-keys/model.d.mts +0 -26
- package/dist/plugins/api-keys/model.mjs +0 -58
- package/dist/plugins/api-keys/schema.cjs +0 -38
- package/dist/plugins/api-keys/schema.d.cts +0 -44
- package/dist/plugins/api-keys/schema.d.mts +0 -44
- package/dist/plugins/api-keys/schema.mjs +0 -39
- package/dist/plugins/definePlugin.cjs +0 -5
- package/dist/plugins/definePlugin.mjs +0 -5
- package/dist/plugins/index.cjs +0 -38
- package/dist/plugins/index.d.cts +0 -12
- package/dist/plugins/index.d.mts +0 -12
- package/dist/plugins/index.mjs +0 -9
- package/dist/plugins/insights/contract.cjs +0 -193
- package/dist/plugins/insights/contract.mjs +0 -189
- package/dist/plugins/insights/domain.d.cts +0 -149
- package/dist/plugins/insights/domain.d.mts +0 -149
- package/dist/plugins/insights/errors.cjs +0 -15
- package/dist/plugins/insights/errors.mjs +0 -14
- package/dist/plugins/insights/eventInput.cjs +0 -284
- package/dist/plugins/insights/eventInput.mjs +0 -282
- package/dist/plugins/insights/eventRow.cjs +0 -49
- package/dist/plugins/insights/eventRow.d.cts +0 -64
- package/dist/plugins/insights/eventRow.d.mts +0 -64
- package/dist/plugins/insights/eventRow.mjs +0 -47
- package/dist/plugins/insights/model.cjs +0 -17
- package/dist/plugins/insights/model.d.cts +0 -10
- package/dist/plugins/insights/model.d.mts +0 -10
- package/dist/plugins/insights/model.mjs +0 -17
- package/dist/plugins/insights/modelTypes.d.cts +0 -176
- package/dist/plugins/insights/modelTypes.d.mts +0 -176
- package/dist/plugins/insights/overview.cjs +0 -109
- package/dist/plugins/insights/overview.d.cts +0 -15
- package/dist/plugins/insights/overview.d.mts +0 -15
- package/dist/plugins/insights/overview.mjs +0 -107
- package/dist/plugins/insights/provider.cjs +0 -375
- package/dist/plugins/insights/provider.d.cts +0 -6
- package/dist/plugins/insights/provider.d.mts +0 -6
- package/dist/plugins/insights/provider.mjs +0 -374
- package/dist/plugins/insights/queryInput.cjs +0 -93
- package/dist/plugins/insights/queryInput.mjs +0 -91
- package/dist/plugins/insights/reads.cjs +0 -681
- package/dist/plugins/insights/reads.d.cts +0 -61
- package/dist/plugins/insights/reads.d.mts +0 -61
- package/dist/plugins/insights/reads.mjs +0 -674
- package/dist/plugins/insights/recordEvent.cjs +0 -319
- package/dist/plugins/insights/recordEvent.d.cts +0 -18
- package/dist/plugins/insights/recordEvent.d.mts +0 -18
- package/dist/plugins/insights/recordEvent.mjs +0 -316
- package/dist/plugins/insights/routes.cjs +0 -96
- package/dist/plugins/insights/routes.mjs +0 -95
- package/dist/plugins/insights/schema.cjs +0 -489
- package/dist/plugins/insights/schema.d.cts +0 -698
- package/dist/plugins/insights/schema.d.mts +0 -698
- package/dist/plugins/insights/schema.mjs +0 -483
- package/dist/plugins/insights/testing/eventRow.d.mts +0 -64
- package/dist/plugins/insights/testing/expectInsightsIndex.mjs +0 -18
- package/dist/plugins/insights/testing/fixtures.d.mts +0 -8
- package/dist/plugins/insights/testing/fixtures.mjs +0 -25
- package/dist/plugins/insights/testing/index.d.mts +0 -24
- package/dist/plugins/insights/testing/index.mjs +0 -25
- package/dist/plugins/insights/testing/insightsModelTests.mjs +0 -714
- package/dist/plugins/insights/testing/modelTypes.d.mts +0 -176
- package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.d.mts +0 -11
- package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.mjs +0 -107
- package/dist/plugins/insights/testing/setupInsightsModelTestSuite.d.mts +0 -11
- package/dist/plugins/insights/testing/setupInsightsModelTestSuite.mjs +0 -31
- package/dist/plugins/insights/testing/types.d.mts +0 -26
- package/dist/plugins/insights/types.d.cts +0 -33
- package/dist/plugins/insights/types.d.mts +0 -33
- package/src/adapters/drizzle.conformance.integration.spec.ts +0 -34
- package/src/adapters/drizzle.readBudgets.integration.spec.ts +0 -43
- package/src/adapters/drizzle.spec.ts +0 -314
- package/src/adapters/drizzle.ts +0 -64
- package/src/adapters/drizzleExecutor.ts +0 -166
- package/src/adapters/kysely.conformance.integration.spec.ts +0 -36
- package/src/adapters/kysely.readBudgets.integration.spec.ts +0 -44
- package/src/adapters/kysely.spec.ts +0 -244
- package/src/adapters/kysely.ts +0 -46
- package/src/adapters/kyselyExecutor.ts +0 -53
- package/src/adapters/mongodb.integration.spec.ts +0 -271
- package/src/adapters/mongodb.readBudgets.integration.spec.ts +0 -61
- package/src/adapters/mongodb.ts +0 -45
- package/src/adapters/mongodbAdapter.ts +0 -307
- package/src/adapters/prisma.conformance.integration.spec.ts +0 -36
- package/src/adapters/prisma.integration.spec.ts +0 -146
- package/src/adapters/prisma.readBudgets.integration.spec.ts +0 -43
- package/src/adapters/prisma.spec.ts +0 -257
- package/src/adapters/prisma.ts +0 -74
- package/src/adapters/prismaExecutor.ts +0 -107
- package/src/adapters/prismaTestClients.ts +0 -182
- package/src/adapters/sqlProviders.ts +0 -14
- package/src/assembly/assemblePlugins.ts +0 -302
- package/src/assembly/assembly.spec.ts +0 -377
- package/src/assembly/assembly.types.spec.ts +0 -203
- package/src/assembly/clientPlugins.ts +0 -113
- package/src/assembly/configError.ts +0 -4
- package/src/assembly/databasePlugins.spec.ts +0 -71
- package/src/assembly/databasePlugins.ts +0 -102
- package/src/assembly/pluginCli.spec.ts +0 -254
- package/src/assembly/pluginCli.ts +0 -248
- package/src/assembly/pluginRoutes.spec.ts +0 -186
- package/src/core/api.ts +0 -139
- package/src/core/baseCandidates.spec.ts +0 -378
- package/src/core/baseCandidates.ts +0 -136
- package/src/core/index.ts +0 -44
- package/src/core/operations.spec.ts +0 -415
- package/src/core/operations.ts +0 -551
- package/src/core/reads.spec.ts +0 -300
- package/src/core/reads.ts +0 -417
- package/src/core/releases.spec.ts +0 -308
- package/src/core/releases.ts +0 -345
- package/src/core/schema.ts +0 -173
- package/src/core/writes.ts +0 -160
- package/src/createHotUpdaterCore.ts +0 -260
- package/src/database/aggregateBatching.spec.ts +0 -577
- package/src/database/aggregateBatching.ts +0 -803
- package/src/database/busy.spec.ts +0 -45
- package/src/database/busy.ts +0 -50
- package/src/database/cursor.ts +0 -65
- package/src/database/database.ts +0 -366
- package/src/database/database.types.spec.ts +0 -135
- package/src/database/definitions.ts +0 -76
- package/src/database/engine.ts +0 -62
- package/src/database/engineAggregates.spec.ts +0 -536
- package/src/database/engineAggregates.ts +0 -189
- package/src/database/engineReads.spec.ts +0 -219
- package/src/database/engineReads.ts +0 -304
- package/src/database/engineTransaction.spec.ts +0 -710
- package/src/database/engineTransaction.ts +0 -582
- package/src/database/errors.ts +0 -30
- package/src/database/fence.spec.ts +0 -223
- package/src/database/fence.ts +0 -175
- package/src/database/index.ts +0 -160
- package/src/database/kv/kvAdapter.batching.integration.spec.ts +0 -15
- package/src/database/kv/kvAdapter.conformance.integration.spec.ts +0 -19
- package/src/database/kv/kvAdapter.readBudgets.integration.spec.ts +0 -17
- package/src/database/kv/kvAdapter.spec.ts +0 -595
- package/src/database/kv/kvAdapter.ts +0 -479
- package/src/database/kv/kvTestStore.ts +0 -118
- package/src/database/memory.readBudgets.integration.spec.ts +0 -13
- package/src/database/resolveSchema.spec.ts +0 -230
- package/src/database/resolveSchema.ts +0 -375
- package/src/database/retention.spec.ts +0 -314
- package/src/database/retention.ts +0 -129
- package/src/database/schema.ts +0 -213
- package/src/database/schema.types.spec.ts +0 -94
- package/src/database/sql/docker-compose.yml +0 -36
- package/src/database/sql/sqlAdapter.integration.spec.ts +0 -145
- package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +0 -123
- package/src/database/sql/sqlAdapter.spec.ts +0 -343
- package/src/database/sql/sqlAdapter.ts +0 -552
- package/src/database/sql/sqlSchema.ts +0 -286
- package/src/database/sql/sqlTestExecutors.ts +0 -183
- package/src/databaseTestSuite.spec.ts +0 -44
- package/src/db/bundleRows.spec.ts +0 -164
- package/src/db/bundleRows.ts +0 -10
- package/src/db/coreDatabase.ts +0 -153
- package/src/db/createBundleDiff.spec.ts +0 -464
- package/src/db/createBundleDiff.ts +0 -370
- package/src/db/engineDrizzleSchema.ts +0 -72
- package/src/db/engineMigrator.ts +0 -105
- package/src/db/enginePrismaSchema.ts +0 -147
- package/src/db/engineSql.spec.ts +0 -130
- package/src/db/engineSql.ts +0 -48
- package/src/db/engineSqlMigrator.ts +0 -116
- package/src/db/fixedMigratorShared.ts +0 -17
- package/src/db/index.spec.ts +0 -554
- package/src/db/index.ts +0 -93
- package/src/db/node-sqlite.d.ts +0 -25
- package/src/db/pluginTables.spec.ts +0 -248
- package/src/db/releaseCatalog.ts +0 -106
- package/src/db/schemaSettings.ts +0 -104
- package/src/db/settingsMigrator.spec.ts +0 -65
- package/src/db/settingsMigrator.ts +0 -152
- package/src/db/types.ts +0 -82
- package/src/db/updateArtifacts.spec.ts +0 -235
- package/src/db/updateArtifacts.ts +0 -473
- package/src/db/updateCheck.bench.ts +0 -47
- package/src/diff.ts +0 -6
- package/src/handler-standalone.integration.spec.ts +0 -321
- package/src/handler.spec.ts +0 -273
- package/src/handler.testFixtures.ts +0 -25
- package/src/handler.ts +0 -302
- package/src/handlerAdminRoutes.spec.ts +0 -183
- package/src/handlerAdminRoutes.ts +0 -536
- package/src/handlerAuth.integration.spec.ts +0 -33
- package/src/handlerErrors.ts +0 -7
- package/src/handlerManagement.spec.ts +0 -202
- package/src/handlerParameters.ts +0 -105
- package/src/handlerReleaseCatalogRoutes.ts +0 -176
- package/src/handlerTypes.ts +0 -19
- package/src/handlerVersionRoutes.ts +0 -25
- package/src/index.ts +0 -13
- package/src/internalRouter.ts +0 -104
- package/src/lintRules.spec.ts +0 -76
- package/src/node.spec.ts +0 -119
- package/src/node.ts +0 -111
- package/src/plugins/api-keys/apiKeys.integration.spec.ts +0 -92
- package/src/plugins/api-keys/apiKeys.spec.ts +0 -166
- package/src/plugins/api-keys/apiKeys.ts +0 -214
- package/src/plugins/api-keys/apiKeysPlugin.spec.ts +0 -168
- package/src/plugins/api-keys/cli.spec.ts +0 -187
- package/src/plugins/api-keys/cli.ts +0 -140
- package/src/plugins/api-keys/index.ts +0 -73
- package/src/plugins/api-keys/model.ts +0 -88
- package/src/plugins/api-keys/schema.ts +0 -22
- package/src/plugins/definePlugin.ts +0 -242
- package/src/plugins/index.ts +0 -73
- package/src/plugins/insights/contract.spec.ts +0 -285
- package/src/plugins/insights/contract.ts +0 -372
- package/src/plugins/insights/domain.ts +0 -176
- package/src/plugins/insights/errors.ts +0 -11
- package/src/plugins/insights/eventInput.ts +0 -381
- package/src/plugins/insights/eventRow.ts +0 -209
- package/src/plugins/insights/index.ts +0 -222
- package/src/plugins/insights/insights.integration.spec.ts +0 -921
- package/src/plugins/insights/insightsRollout.integration.spec.ts +0 -186
- package/src/plugins/insights/model.spec.ts +0 -64
- package/src/plugins/insights/model.ts +0 -18
- package/src/plugins/insights/modelTypes.ts +0 -197
- package/src/plugins/insights/overview.spec.ts +0 -64
- package/src/plugins/insights/overview.ts +0 -214
- package/src/plugins/insights/provider.spec.ts +0 -585
- package/src/plugins/insights/provider.ts +0 -704
- package/src/plugins/insights/queryInput.ts +0 -142
- package/src/plugins/insights/reads.spec.ts +0 -1013
- package/src/plugins/insights/reads.ts +0 -1037
- package/src/plugins/insights/recordEvent.spec.ts +0 -897
- package/src/plugins/insights/recordEvent.ts +0 -476
- package/src/plugins/insights/retention.spec.ts +0 -115
- package/src/plugins/insights/routes.ts +0 -149
- package/src/plugins/insights/schema.ts +0 -409
- package/src/plugins/insights/testing/expectInsightsIndex.spec.ts +0 -42
- package/src/plugins/insights/testing/expectInsightsIndex.ts +0 -20
- package/src/plugins/insights/testing/fixtures.ts +0 -30
- package/src/plugins/insights/testing/index.ts +0 -45
- package/src/plugins/insights/testing/insightsModelTests.ts +0 -860
- package/src/plugins/insights/testing/setupInsightsHttpTestSuite.ts +0 -152
- package/src/plugins/insights/testing/setupInsightsModelTestSuite.ts +0 -36
- package/src/plugins/insights/testing/types.ts +0 -30
- package/src/plugins/insights/types.ts +0 -55
- package/src/plugins/pluginTestHarness.spec.ts +0 -56
- package/src/readBudgets.testFixtures.ts +0 -15
- package/src/releaseCatalogRoutes.integration.spec.ts +0 -200
- package/src/retention.spec.ts +0 -73
- package/src/runtime.spec.ts +0 -207
- package/src/runtime.testFixtures.ts +0 -60
- package/src/runtimeBundles.integration.spec.ts +0 -112
- package/src/storageAccess.spec.ts +0 -152
- package/src/storageAccess.ts +0 -141
- package/src/testUtilsMutation.integration.spec.ts +0 -216
- package/src/testUtilsPackage.integration.spec.ts +0 -180
- package/src/types/index.ts +0 -2
- package/src/version.ts +0 -3
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import "./resolveSchema.cjs";
|
|
2
|
-
import { DatabaseAdapter, DatabaseKeyValue, StoredRow } from "@hot-updater/plugin-core/internal";
|
|
3
|
-
//#region src/database/engineReads.d.ts
|
|
4
|
-
declare class DatabaseQueryError extends Error {
|
|
5
|
-
readonly name = "DatabaseQueryError";
|
|
6
|
-
}
|
|
7
|
-
/** A value of the index's first order field, or a prefix of its order tuple. */
|
|
8
|
-
type RangeValue = DatabaseKeyValue | readonly DatabaseKeyValue[];
|
|
9
|
-
interface ReadRange {
|
|
10
|
-
readonly gt?: RangeValue;
|
|
11
|
-
readonly gte?: RangeValue;
|
|
12
|
-
readonly lt?: RangeValue;
|
|
13
|
-
readonly lte?: RangeValue;
|
|
14
|
-
}
|
|
15
|
-
interface ReadInput {
|
|
16
|
-
readonly index: string;
|
|
17
|
-
/** Values for every eq field of the index. */
|
|
18
|
-
readonly where?: Readonly<Record<string, DatabaseKeyValue>>;
|
|
19
|
-
/** Bounds on the index's first order field, or on a prefix of its order tuple. */
|
|
20
|
-
readonly range?: ReadRange;
|
|
21
|
-
readonly order?: "asc" | "desc";
|
|
22
|
-
readonly limit: number;
|
|
23
|
-
readonly cursor?: string;
|
|
24
|
-
}
|
|
25
|
-
interface Page<TRow> {
|
|
26
|
-
readonly rows: readonly TRow[];
|
|
27
|
-
/** Present only after a full page. */
|
|
28
|
-
readonly next?: string;
|
|
29
|
-
}
|
|
30
|
-
interface EngineReadCount {
|
|
31
|
-
readonly calls: number;
|
|
32
|
-
readonly rows: number;
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
export { DatabaseQueryError, EngineReadCount, Page, RangeValue, ReadInput, ReadRange };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import "./resolveSchema.mjs";
|
|
2
|
-
import { DatabaseAdapter, DatabaseKeyValue, StoredRow } from "@hot-updater/plugin-core/internal";
|
|
3
|
-
//#region src/database/engineReads.d.ts
|
|
4
|
-
declare class DatabaseQueryError extends Error {
|
|
5
|
-
readonly name = "DatabaseQueryError";
|
|
6
|
-
}
|
|
7
|
-
/** A value of the index's first order field, or a prefix of its order tuple. */
|
|
8
|
-
type RangeValue = DatabaseKeyValue | readonly DatabaseKeyValue[];
|
|
9
|
-
interface ReadRange {
|
|
10
|
-
readonly gt?: RangeValue;
|
|
11
|
-
readonly gte?: RangeValue;
|
|
12
|
-
readonly lt?: RangeValue;
|
|
13
|
-
readonly lte?: RangeValue;
|
|
14
|
-
}
|
|
15
|
-
interface ReadInput {
|
|
16
|
-
readonly index: string;
|
|
17
|
-
/** Values for every eq field of the index. */
|
|
18
|
-
readonly where?: Readonly<Record<string, DatabaseKeyValue>>;
|
|
19
|
-
/** Bounds on the index's first order field, or on a prefix of its order tuple. */
|
|
20
|
-
readonly range?: ReadRange;
|
|
21
|
-
readonly order?: "asc" | "desc";
|
|
22
|
-
readonly limit: number;
|
|
23
|
-
readonly cursor?: string;
|
|
24
|
-
}
|
|
25
|
-
interface Page<TRow> {
|
|
26
|
-
readonly rows: readonly TRow[];
|
|
27
|
-
/** Present only after a full page. */
|
|
28
|
-
readonly next?: string;
|
|
29
|
-
}
|
|
30
|
-
interface EngineReadCount {
|
|
31
|
-
readonly calls: number;
|
|
32
|
-
readonly rows: number;
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
export { DatabaseQueryError, EngineReadCount, Page, RangeValue, ReadInput, ReadRange };
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { cursorScope, decodeCursor, encodeCursor } from "./cursor.mjs";
|
|
2
|
-
import { SHARD_COLUMN } from "./resolveSchema.mjs";
|
|
3
|
-
import { DATABASE_MAX_QUERY_LIMIT, indexOrderColumns, indexOrderTuple, isKeyValue, mergeDistinct } from "@hot-updater/plugin-core/internal";
|
|
4
|
-
//#region src/database/engineReads.ts
|
|
5
|
-
var DatabaseQueryError = class extends Error {
|
|
6
|
-
name = "DatabaseQueryError";
|
|
7
|
-
};
|
|
8
|
-
const sameFields = (left, right) => left.length === right.length && left.every((field) => right.includes(field));
|
|
9
|
-
const keyValue = (value, field) => {
|
|
10
|
-
if (isKeyValue(value)) return value;
|
|
11
|
-
throw new DatabaseQueryError(`${field} needs a string, number, or boolean.`);
|
|
12
|
-
};
|
|
13
|
-
const bound = (exclusive, inclusive, columns) => {
|
|
14
|
-
if (exclusive !== void 0 && inclusive !== void 0) throw new DatabaseQueryError(`range on ${columns[0]} sets both bounds of one side.`);
|
|
15
|
-
const value = exclusive ?? inclusive;
|
|
16
|
-
if (value === void 0) return void 0;
|
|
17
|
-
const values = Array.isArray(value) ? value : [value];
|
|
18
|
-
if (values.length === 0 || values.length > columns.length) throw new DatabaseQueryError(`range on ${columns[0]} takes 1–${columns.length} values of ${columns.join(", ")}.`);
|
|
19
|
-
return {
|
|
20
|
-
values: values.map((item, position) => keyValue(item, columns[position])),
|
|
21
|
-
inclusive: inclusive !== void 0
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
const createEngineReads = ({ adapter, schema, maxPageSize: requested = DATABASE_MAX_QUERY_LIMIT }) => {
|
|
25
|
-
const maxPageSize = Math.min(requested, DATABASE_MAX_QUERY_LIMIT);
|
|
26
|
-
let count = {
|
|
27
|
-
calls: 0,
|
|
28
|
-
rows: 0
|
|
29
|
-
};
|
|
30
|
-
const returned = (rows) => {
|
|
31
|
-
const size = Array.isArray(rows) ? rows.length : rows === null ? 0 : 1;
|
|
32
|
-
count = {
|
|
33
|
-
calls: count.calls + 1,
|
|
34
|
-
rows: count.rows + size
|
|
35
|
-
};
|
|
36
|
-
return rows;
|
|
37
|
-
};
|
|
38
|
-
/** A model of `kind` by physical table name, for reads and transactions. */
|
|
39
|
-
const modelOf = (name, kind = "table") => {
|
|
40
|
-
const model = schema.models.get(name);
|
|
41
|
-
if (model?.definition.kind === kind) return model;
|
|
42
|
-
throw new DatabaseQueryError(model === void 0 ? `Unknown model ${name}.` : kind === "table" ? `${name} is an aggregate; read it with findAggregates and change it with aggregate.` : `${name} is a table; read it with findMany and change it with create, update, or delete.`);
|
|
43
|
-
};
|
|
44
|
-
const plan = ({ table }, input) => {
|
|
45
|
-
const index = table.indexes.find(({ name }) => name === input.index);
|
|
46
|
-
if (index === void 0) throw new DatabaseQueryError(`${table.name} has no index ${input.index}.`);
|
|
47
|
-
const where = input.where ?? {};
|
|
48
|
-
if (!sameFields(Object.keys(where), index.eq)) throw new DatabaseQueryError(`${table.name}.${index.name} reads need where on exactly: ${index.eq.join(", ") || "(none)"}.`);
|
|
49
|
-
const { limit, order = "asc", range } = input;
|
|
50
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > maxPageSize) throw new DatabaseQueryError(`limit must be 1–${maxPageSize}.`);
|
|
51
|
-
const columns = indexOrderColumns(table, index);
|
|
52
|
-
const eq = index.eq.map((field) => keyValue(where[field], `${table.name}.${field}`));
|
|
53
|
-
const scope = cursorScope([
|
|
54
|
-
table.name,
|
|
55
|
-
index.name,
|
|
56
|
-
eq,
|
|
57
|
-
order,
|
|
58
|
-
range
|
|
59
|
-
]);
|
|
60
|
-
let lower = bound(range?.gt, range?.gte, columns);
|
|
61
|
-
let upper = bound(range?.lt, range?.lte, columns);
|
|
62
|
-
if (input.cursor !== void 0) {
|
|
63
|
-
const values = decodeCursor(scope, input.cursor);
|
|
64
|
-
if (order === "asc") lower = {
|
|
65
|
-
values,
|
|
66
|
-
inclusive: false
|
|
67
|
-
};
|
|
68
|
-
else upper = {
|
|
69
|
-
values,
|
|
70
|
-
inclusive: false
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
request: {
|
|
75
|
-
index: index.name,
|
|
76
|
-
eq,
|
|
77
|
-
order,
|
|
78
|
-
limit,
|
|
79
|
-
...lower === void 0 ? {} : { lower },
|
|
80
|
-
...upper === void 0 ? {} : { upper }
|
|
81
|
-
},
|
|
82
|
-
index,
|
|
83
|
-
scope
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
/** Reads rows by key in one batch; the results follow the keys' order. */
|
|
87
|
-
const findByKeys = async (name, lookups) => {
|
|
88
|
-
const { table } = modelOf(name, "table");
|
|
89
|
-
const keys = lookups.map((lookup) => {
|
|
90
|
-
if (!sameFields(Object.keys(lookup), table.key)) throw new DatabaseQueryError(`findByKeys on ${name} takes its key: ${table.key.join(", ")}.`);
|
|
91
|
-
return table.key.map((field) => keyValue(lookup[field], `${name}.${field}`));
|
|
92
|
-
});
|
|
93
|
-
const rows = keys.length === 0 ? [] : await adapter.get(table, keys);
|
|
94
|
-
returned(rows.filter((row) => row !== null));
|
|
95
|
-
return rows.map((row) => row ?? null);
|
|
96
|
-
};
|
|
97
|
-
return {
|
|
98
|
-
maxPageSize,
|
|
99
|
-
modelOf,
|
|
100
|
-
reads: {
|
|
101
|
-
total: () => count,
|
|
102
|
-
reset: () => {
|
|
103
|
-
count = {
|
|
104
|
-
calls: 0,
|
|
105
|
-
rows: 0
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
findByKeys,
|
|
110
|
-
/** Reads one row by its key or by the eq fields of a unique index. */
|
|
111
|
-
async findOne(name, lookup) {
|
|
112
|
-
const { table } = modelOf(name, "table");
|
|
113
|
-
const fields = Object.keys(lookup);
|
|
114
|
-
if (sameFields(fields, table.key)) return (await findByKeys(name, [lookup]))[0];
|
|
115
|
-
const index = table.indexes.find(({ unique, eq }) => unique && sameFields(fields, eq));
|
|
116
|
-
if (index === void 0) throw new DatabaseQueryError(`findOne on ${name} needs its key or a unique field, not ${fields.join(", ")}.`);
|
|
117
|
-
const [row] = await adapter.query(table, {
|
|
118
|
-
index: index.name,
|
|
119
|
-
eq: index.eq.map((field) => keyValue(lookup[field], `${name}.${field}`)),
|
|
120
|
-
order: "asc",
|
|
121
|
-
limit: 1
|
|
122
|
-
});
|
|
123
|
-
return returned(row ?? null);
|
|
124
|
-
},
|
|
125
|
-
/** Reads one page of an index range; `next` resumes right after it. */
|
|
126
|
-
async findMany(name, input) {
|
|
127
|
-
const model = modelOf(name, "table");
|
|
128
|
-
const { request, index, scope } = plan(model, input);
|
|
129
|
-
const rows = returned(await adapter.query(model.table, request));
|
|
130
|
-
const last = rows.at(-1);
|
|
131
|
-
return rows.length === input.limit && last !== void 0 ? {
|
|
132
|
-
rows,
|
|
133
|
-
next: encodeCursor(scope, indexOrderTuple(model.table, index, last))
|
|
134
|
-
} : { rows };
|
|
135
|
-
},
|
|
136
|
-
/**
|
|
137
|
-
* Reads one page of logical aggregate rows, summing counters and gauges
|
|
138
|
-
* and merging sketches across each row's shards. A row cut off by the
|
|
139
|
-
* limit is completed by reading only its remaining shards.
|
|
140
|
-
*/
|
|
141
|
-
async findAggregates(name, input) {
|
|
142
|
-
const model = modelOf(name, "aggregate");
|
|
143
|
-
const { table, definition } = model;
|
|
144
|
-
if (definition.kind !== "aggregate") throw new DatabaseQueryError(name);
|
|
145
|
-
const { request, index, scope } = plan(model, input);
|
|
146
|
-
const rows = await adapter.query(table, request);
|
|
147
|
-
const logicalKey = (row) => definition.key.map((column) => keyValue(row[column], column));
|
|
148
|
-
const groups = /* @__PURE__ */ new Map();
|
|
149
|
-
for (const row of rows) {
|
|
150
|
-
const key = JSON.stringify(logicalKey(row));
|
|
151
|
-
groups.set(key, [...groups.get(key) ?? [], row]);
|
|
152
|
-
}
|
|
153
|
-
const full = rows.length === input.limit;
|
|
154
|
-
const last = [...groups.values()].at(-1);
|
|
155
|
-
if (full && last !== void 0) {
|
|
156
|
-
const seen = new Set(last.map((row) => row[SHARD_COLUMN]));
|
|
157
|
-
const missing = Array.from({ length: definition.shards }, (_, shard) => shard).filter((shard) => !seen.has(shard));
|
|
158
|
-
if (missing.length > 0) {
|
|
159
|
-
const key = logicalKey(last[0]);
|
|
160
|
-
const rest = await adapter.get(table, missing.map((shard) => [...key, shard]));
|
|
161
|
-
last.push(...rest.filter((row) => row !== null));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const merged = [...groups.values()].map((shards) => {
|
|
165
|
-
const row = Object.fromEntries(definition.key.map((field) => [field, shards[0][field]]));
|
|
166
|
-
for (const metric of [...definition.counters, ...definition.gauges]) row[metric] = shards.reduce((sum, shard) => sum + Number(shard[metric] ?? 0), 0);
|
|
167
|
-
for (const metric of definition.distinct) row[metric] = mergeDistinct(shards.map((shard) => shard[metric]));
|
|
168
|
-
return row;
|
|
169
|
-
});
|
|
170
|
-
returned(merged);
|
|
171
|
-
if (!full || last === void 0) return { rows: merged };
|
|
172
|
-
const tuple = indexOrderTuple(table, index, last[0]);
|
|
173
|
-
return {
|
|
174
|
-
rows: merged,
|
|
175
|
-
next: encodeCursor(scope, tuple.slice(0, -1))
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
};
|
|
180
|
-
//#endregion
|
|
181
|
-
export { DatabaseQueryError, createEngineReads };
|
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
const require_errors = require("./errors.cjs");
|
|
2
|
-
const require_engineAggregates = require("./engineAggregates.cjs");
|
|
3
|
-
const require_engineReads = require("./engineReads.cjs");
|
|
4
|
-
let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
|
|
5
|
-
//#region src/database/engineTransaction.ts
|
|
6
|
-
/** A row this attempt read changed while it ran; the attempt reruns. */
|
|
7
|
-
var StaleReadError = class extends Error {};
|
|
8
|
-
const idOf = (table, key) => JSON.stringify([table, key]);
|
|
9
|
-
const versionOf = (row) => Number(row[_hot_updater_plugin_core_internal.DATABASE_VERSION_COLUMN]);
|
|
10
|
-
const isKeyed = (value) => value !== null && value !== void 0;
|
|
11
|
-
const misuse = (table, message) => new require_errors.DatabaseTransactionError(`${table}: ${message}`);
|
|
12
|
-
const once = (table) => misuse(table, "a transaction writes one key once.");
|
|
13
|
-
const hooks = globalThis.process?.getBuiltinModule?.("node:async_hooks");
|
|
14
|
-
/** Where the runtime tracks async context, `db.*` inside a transaction throws. */
|
|
15
|
-
const transactionScope = hooks && new hooks.AsyncLocalStorage();
|
|
16
|
-
const assertOutsideTransaction = () => {
|
|
17
|
-
if (transactionScope?.getStore() !== void 0) throw new require_errors.DatabaseTransactionError("Inside transaction(), read and write through its handle; db and core are not part of it.");
|
|
18
|
-
};
|
|
19
|
-
const createTransactions = ({ adapter, schema, reads, retry = {} }) => {
|
|
20
|
-
const { attempts = 8, baseDelayMs = 5, maxDelayMs = 250, onRetry } = retry;
|
|
21
|
-
const { modelOf } = reads;
|
|
22
|
-
/**
|
|
23
|
-
* A key-value index copy has no `_v`. A transaction guards what it reads,
|
|
24
|
-
* so it reads such a row whole, and reruns if it changed since the copy.
|
|
25
|
-
*/
|
|
26
|
-
const complete = async ({ table }, rows) => {
|
|
27
|
-
const copies = rows.filter((row) => !(_hot_updater_plugin_core_internal.DATABASE_VERSION_COLUMN in row));
|
|
28
|
-
if (copies.length === 0) return [...rows];
|
|
29
|
-
const current = await adapter.get(table, copies.map((copy) => (0, _hot_updater_plugin_core_internal.rowKey)(table, copy)));
|
|
30
|
-
return rows.map((row) => {
|
|
31
|
-
const at = copies.indexOf(row);
|
|
32
|
-
if (at < 0) return row;
|
|
33
|
-
const whole = current[at];
|
|
34
|
-
if (!whole || Object.keys(row).some((column) => (0, _hot_updater_plugin_core_internal.canonicalJson)(row[column]) !== (0, _hot_updater_plugin_core_internal.canonicalJson)(whole[column]))) throw new StaleReadError();
|
|
35
|
-
return whole;
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
const attempt = async (fn) => {
|
|
39
|
-
const read = /* @__PURE__ */ new Map();
|
|
40
|
-
/** Rows of rooted ranges: their root guards them, so they need no check of their own. */
|
|
41
|
-
const ranged = /* @__PURE__ */ new Map();
|
|
42
|
-
const writes = /* @__PURE__ */ new Map();
|
|
43
|
-
/** Deleted keys, children before their parents. */
|
|
44
|
-
const deleted = [];
|
|
45
|
-
const aggregates = /* @__PURE__ */ new Map();
|
|
46
|
-
let open = true;
|
|
47
|
-
let failure;
|
|
48
|
-
/** A failed call fails the attempt even when `fn` catches it. */
|
|
49
|
-
const step = (method) => (...args) => {
|
|
50
|
-
if (!open) throw new require_errors.DatabaseTransactionError("The transaction has ended.");
|
|
51
|
-
const fail = (error) => {
|
|
52
|
-
failure ??= { error };
|
|
53
|
-
throw error;
|
|
54
|
-
};
|
|
55
|
-
try {
|
|
56
|
-
const result = method(...args);
|
|
57
|
-
return result instanceof Promise ? result.catch(fail) : result;
|
|
58
|
-
} catch (error) {
|
|
59
|
-
return fail(error);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const remember = (model, key, row) => {
|
|
63
|
-
const id = idOf(model.table.name, key);
|
|
64
|
-
const known = read.get(id);
|
|
65
|
-
if (known !== void 0 && (known && row ? versionOf(known) !== versionOf(row) : known !== row)) throw new StaleReadError();
|
|
66
|
-
read.set(id, row);
|
|
67
|
-
return row;
|
|
68
|
-
};
|
|
69
|
-
const readRow = ({ table }, row) => {
|
|
70
|
-
const id = idOf(table.name, (0, _hot_updater_plugin_core_internal.rowKey)(table, row));
|
|
71
|
-
const known = read.get(id) ?? ranged.get(id);
|
|
72
|
-
if (known && versionOf(known) === versionOf(row)) return known;
|
|
73
|
-
throw misuse(table.name, "update and delete take a row this transaction read.");
|
|
74
|
-
};
|
|
75
|
-
const checkFields = ({ table, definition: { fields } }, values, creating) => {
|
|
76
|
-
for (const field of Object.keys(values)) if (!(field in fields) || !creating && table.key.includes(field)) throw misuse(table.name, `${field} cannot be ${creating ? "set" : "changed"}.`);
|
|
77
|
-
for (const [field, { required }] of Object.entries(fields)) if (required !== false && (creating || field in values) && !isKeyed(values[field])) throw misuse(table.name, `${field} is required.`);
|
|
78
|
-
};
|
|
79
|
-
/** Adds counter deltas to a key's pending op; an empty `by` still bumps `_v`. */
|
|
80
|
-
const bump = (model, key, by) => {
|
|
81
|
-
const id = idOf(model.table.name, key);
|
|
82
|
-
const pending = writes.get(id);
|
|
83
|
-
if (pending === void 0) writes.set(id, {
|
|
84
|
-
model,
|
|
85
|
-
key,
|
|
86
|
-
type: "increment",
|
|
87
|
-
row: { ...by }
|
|
88
|
-
});
|
|
89
|
-
else if (pending.type !== "delete") for (const [column, delta] of Object.entries(by)) pending.row[column] = Number(pending.row[column] ?? pending.read?.[column] ?? 0) + delta;
|
|
90
|
-
else if (Object.values(by).some((delta) => delta > 0)) throw new require_errors.DatabaseConstraintError("not_found", model.table.name);
|
|
91
|
-
};
|
|
92
|
-
/** Moves parent counters when a reference changes and bumps every rooted parent. */
|
|
93
|
-
const touchParents = (model, before, after) => {
|
|
94
|
-
for (const { field, counter, target } of model.references) {
|
|
95
|
-
const [from, to] = [before?.[field], after?.[field]];
|
|
96
|
-
if (counter === void 0 || from === to) continue;
|
|
97
|
-
if (isKeyed(from)) bump(modelOf(target), [from], { [counter]: -1 });
|
|
98
|
-
if (isKeyed(to)) bump(modelOf(target), [to], { [counter]: 1 });
|
|
99
|
-
}
|
|
100
|
-
for (const [index, root] of model.roots) {
|
|
101
|
-
const parent = modelOf(root);
|
|
102
|
-
const { eq } = model.table.indexes.find(({ name }) => name === index);
|
|
103
|
-
for (const row of [before, after]) {
|
|
104
|
-
const key = eq.slice(0, parent.table.key.length).map((field) => row?.[field]);
|
|
105
|
-
if (row && key.every(isKeyed)) bump(parent, key, {});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const derive = ({ definition }, row) => {
|
|
110
|
-
if (definition.kind === "table") for (const [name, derived] of Object.entries(definition.derived)) row[name] = derived.compute(row);
|
|
111
|
-
return row;
|
|
112
|
-
};
|
|
113
|
-
/** Deletes a row after its cascaded children, or refuses a restricted delete. */
|
|
114
|
-
const remove = async (model, known) => {
|
|
115
|
-
const { table } = model;
|
|
116
|
-
const key = (0, _hot_updater_plugin_core_internal.rowKey)(table, known);
|
|
117
|
-
const id = idOf(table.name, key);
|
|
118
|
-
const pending = writes.get(id);
|
|
119
|
-
if (pending?.type === "delete") return;
|
|
120
|
-
if (pending && pending.type !== "increment") throw once(table.name);
|
|
121
|
-
writes.set(id, {
|
|
122
|
-
model,
|
|
123
|
-
key,
|
|
124
|
-
type: "delete",
|
|
125
|
-
row: {},
|
|
126
|
-
read: known
|
|
127
|
-
});
|
|
128
|
-
touchParents(model, known, null);
|
|
129
|
-
for (const reference of model.referencedBy) {
|
|
130
|
-
const { counter, field, onDelete, table: name } = reference;
|
|
131
|
-
if (counter === void 0) continue;
|
|
132
|
-
const stored = Number(known[counter] ?? 0);
|
|
133
|
-
const added = Number(pending?.row[counter] ?? 0);
|
|
134
|
-
if (added > 0) throw new require_errors.DatabaseConstraintError("referenced", table.name);
|
|
135
|
-
if (stored + added <= 0) continue;
|
|
136
|
-
if (onDelete === "restrict") {
|
|
137
|
-
const [current] = await adapter.get(table, [key]);
|
|
138
|
-
if (current && versionOf(current) === versionOf(known)) throw new require_errors.DatabaseConstraintError("referenced", table.name);
|
|
139
|
-
throw new StaleReadError();
|
|
140
|
-
}
|
|
141
|
-
const child = modelOf(name);
|
|
142
|
-
const index = child.table.indexes.find(({ eq }) => eq.length === 1 && eq[0] === field);
|
|
143
|
-
let cursor;
|
|
144
|
-
let seen = 0;
|
|
145
|
-
do {
|
|
146
|
-
const page = await reads.findMany(name, {
|
|
147
|
-
index: index.name,
|
|
148
|
-
where: { [field]: key[0] },
|
|
149
|
-
limit: Math.min(stored - seen, reads.maxPageSize),
|
|
150
|
-
...cursor === void 0 ? {} : { cursor }
|
|
151
|
-
});
|
|
152
|
-
for (const row of await complete(child, page.rows)) {
|
|
153
|
-
remember(child, (0, _hot_updater_plugin_core_internal.rowKey)(child.table, row), row);
|
|
154
|
-
await remove(child, row);
|
|
155
|
-
}
|
|
156
|
-
seen += page.rows.length;
|
|
157
|
-
cursor = page.next;
|
|
158
|
-
} while (cursor !== void 0 && seen < stored);
|
|
159
|
-
}
|
|
160
|
-
deleted.push(id);
|
|
161
|
-
};
|
|
162
|
-
const tx = {
|
|
163
|
-
findOne: step(async (name, lookup) => {
|
|
164
|
-
const model = modelOf(name);
|
|
165
|
-
const { table } = model;
|
|
166
|
-
const found = await reads.findOne(name, lookup);
|
|
167
|
-
if (found === null && !table.key.every((field) => field in lookup)) return null;
|
|
168
|
-
const [row = null] = found ? await complete(model, [found]) : [];
|
|
169
|
-
const key = row ? (0, _hot_updater_plugin_core_internal.rowKey)(table, row) : table.key.map((field) => lookup[field]);
|
|
170
|
-
return remember(model, key, row);
|
|
171
|
-
}),
|
|
172
|
-
findMany: step(async (name, input) => {
|
|
173
|
-
const model = modelOf(name);
|
|
174
|
-
const root = model.roots.get(input.index);
|
|
175
|
-
if (root === void 0) throw new require_engineReads.DatabaseQueryError(`${name}.${input.index} is not rooted; a transaction reads a range only under a guarded parent.`);
|
|
176
|
-
const parent = modelOf(root);
|
|
177
|
-
const { eq } = model.table.indexes.find(({ name: index }) => index === input.index);
|
|
178
|
-
const where = input.where ?? {};
|
|
179
|
-
const lookup = Object.fromEntries(parent.table.key.map((field, at) => [field, where[eq[at]]]));
|
|
180
|
-
remember(parent, Object.values(lookup), await reads.findOne(root, lookup));
|
|
181
|
-
const found = await reads.findMany(name, input);
|
|
182
|
-
const rows = await complete(model, found.rows);
|
|
183
|
-
for (const row of rows) ranged.set(idOf(name, (0, _hot_updater_plugin_core_internal.rowKey)(model.table, row)), row);
|
|
184
|
-
return {
|
|
185
|
-
...found,
|
|
186
|
-
rows
|
|
187
|
-
};
|
|
188
|
-
}),
|
|
189
|
-
create: step((name, values) => {
|
|
190
|
-
const model = modelOf(name);
|
|
191
|
-
checkFields(model, values, true);
|
|
192
|
-
const defaults = model.table.columns.flatMap((column) => column.nullable || column.default !== void 0 ? [[column.name, column.default ?? null]] : []);
|
|
193
|
-
const row = derive(model, {
|
|
194
|
-
...Object.fromEntries(defaults),
|
|
195
|
-
...values
|
|
196
|
-
});
|
|
197
|
-
const key = (0, _hot_updater_plugin_core_internal.rowKey)(model.table, row);
|
|
198
|
-
const id = idOf(name, key);
|
|
199
|
-
const pending = writes.get(id);
|
|
200
|
-
if (pending && pending.type !== "increment") throw once(name);
|
|
201
|
-
for (const [column, delta] of Object.entries(pending?.row ?? {})) row[column] = Number(row[column]) + Number(delta);
|
|
202
|
-
writes.set(id, {
|
|
203
|
-
model,
|
|
204
|
-
key,
|
|
205
|
-
type: "insert",
|
|
206
|
-
row
|
|
207
|
-
});
|
|
208
|
-
touchParents(model, null, row);
|
|
209
|
-
}),
|
|
210
|
-
update: step((name, row, set) => {
|
|
211
|
-
const model = modelOf(name);
|
|
212
|
-
const known = readRow(model, row);
|
|
213
|
-
checkFields(model, set, false);
|
|
214
|
-
const key = (0, _hot_updater_plugin_core_internal.rowKey)(model.table, known);
|
|
215
|
-
const id = idOf(name, key);
|
|
216
|
-
const pending = writes.get(id);
|
|
217
|
-
if (pending?.type === "insert" || pending?.type === "delete") throw once(name);
|
|
218
|
-
const before = pending?.type === "patch" ? {
|
|
219
|
-
...known,
|
|
220
|
-
...pending.row
|
|
221
|
-
} : known;
|
|
222
|
-
const next = derive(model, {
|
|
223
|
-
...before,
|
|
224
|
-
...set
|
|
225
|
-
});
|
|
226
|
-
const changed = Object.entries(next).filter(([column, value]) => column !== _hot_updater_plugin_core_internal.DATABASE_VERSION_COLUMN && JSON.stringify(value) !== JSON.stringify(known[column]));
|
|
227
|
-
const patch = Object.fromEntries(changed);
|
|
228
|
-
writes.set(id, {
|
|
229
|
-
model,
|
|
230
|
-
key,
|
|
231
|
-
type: "patch",
|
|
232
|
-
row: patch,
|
|
233
|
-
read: known
|
|
234
|
-
});
|
|
235
|
-
if (pending?.type === "increment") bump(model, key, pending.row);
|
|
236
|
-
touchParents(model, before, next);
|
|
237
|
-
}),
|
|
238
|
-
delete: step(async (name, row) => {
|
|
239
|
-
const model = modelOf(name);
|
|
240
|
-
await remove(model, readRow(model, row));
|
|
241
|
-
}),
|
|
242
|
-
aggregate: step((name, identity, values, options) => {
|
|
243
|
-
const model = modelOf(name, "aggregate");
|
|
244
|
-
require_engineAggregates.recordAggregate(aggregates, model, identity, values, options?.shardBy);
|
|
245
|
-
})
|
|
246
|
-
};
|
|
247
|
-
try {
|
|
248
|
-
const result = await (transactionScope ? transactionScope.run(tx, () => fn(tx)) : fn(tx));
|
|
249
|
-
if (failure) throw failure.error;
|
|
250
|
-
return {
|
|
251
|
-
result,
|
|
252
|
-
read,
|
|
253
|
-
ops: compile(writes, read, deleted),
|
|
254
|
-
aggregates: [...aggregates.values()]
|
|
255
|
-
};
|
|
256
|
-
} catch (error) {
|
|
257
|
-
throw failure?.error instanceof StaleReadError ? failure.error : error;
|
|
258
|
-
} finally {
|
|
259
|
-
open = false;
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
/** Inserts first, then patches and increments, then checks, then deletes, children before parents. */
|
|
263
|
-
const compile = (writes, read, deleted) => {
|
|
264
|
-
const toOp = (id) => {
|
|
265
|
-
const { model, key, type, row, read: previous } = writes.get(id);
|
|
266
|
-
const { table } = model;
|
|
267
|
-
if (type === "insert") return {
|
|
268
|
-
type,
|
|
269
|
-
table,
|
|
270
|
-
row
|
|
271
|
-
};
|
|
272
|
-
if (type === "increment") {
|
|
273
|
-
const known = read.get(id);
|
|
274
|
-
const by = row;
|
|
275
|
-
return known ? {
|
|
276
|
-
type,
|
|
277
|
-
table,
|
|
278
|
-
key,
|
|
279
|
-
by,
|
|
280
|
-
guard: { v: versionOf(known) }
|
|
281
|
-
} : {
|
|
282
|
-
type,
|
|
283
|
-
table,
|
|
284
|
-
key,
|
|
285
|
-
by
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
const guard = { v: versionOf(previous) };
|
|
289
|
-
return type === "patch" ? {
|
|
290
|
-
type,
|
|
291
|
-
table,
|
|
292
|
-
key,
|
|
293
|
-
set: row,
|
|
294
|
-
guard,
|
|
295
|
-
previous
|
|
296
|
-
} : {
|
|
297
|
-
type,
|
|
298
|
-
table,
|
|
299
|
-
key,
|
|
300
|
-
guard,
|
|
301
|
-
previous
|
|
302
|
-
};
|
|
303
|
-
};
|
|
304
|
-
const checks = [...read].flatMap(([id, row]) => {
|
|
305
|
-
if (row === null || writes.has(id)) return [];
|
|
306
|
-
const { table } = schema.models.get(JSON.parse(id)[0]);
|
|
307
|
-
const guard = { v: versionOf(row) };
|
|
308
|
-
return [{
|
|
309
|
-
type: "check",
|
|
310
|
-
table,
|
|
311
|
-
key: (0, _hot_updater_plugin_core_internal.rowKey)(table, row),
|
|
312
|
-
guard
|
|
313
|
-
}];
|
|
314
|
-
});
|
|
315
|
-
const ofType = (...types) => [...writes.keys()].filter((id) => types.includes(writes.get(id).type));
|
|
316
|
-
return [
|
|
317
|
-
...[...ofType("insert"), ...ofType("patch", "increment")].map(toOp),
|
|
318
|
-
...checks,
|
|
319
|
-
...deleted.map(toOp)
|
|
320
|
-
];
|
|
321
|
-
};
|
|
322
|
-
/** Only a constraint the current state confirms is reported; anything else reruns. */
|
|
323
|
-
const classify = async (op, read) => {
|
|
324
|
-
if (op.type === "check" || op.type === "delete") return void 0;
|
|
325
|
-
if (op.type === "increment" && op.guard) return void 0;
|
|
326
|
-
const { table } = op;
|
|
327
|
-
const key = op.type === "insert" ? (0, _hot_updater_plugin_core_internal.rowKey)(table, op.row) : op.key;
|
|
328
|
-
const [current] = await adapter.get(table, [key]);
|
|
329
|
-
if (op.type === "increment") return current ? void 0 : "not_found";
|
|
330
|
-
if (op.type === "insert" && current) {
|
|
331
|
-
const known = read.get(idOf(table.name, key));
|
|
332
|
-
return known === null || known !== void 0 && versionOf(known) !== versionOf(current) ? void 0 : "exists";
|
|
333
|
-
}
|
|
334
|
-
if (op.type === "patch" && current?.[_hot_updater_plugin_core_internal.DATABASE_VERSION_COLUMN] !== op.guard.v) return;
|
|
335
|
-
const row = op.type === "insert" ? op.row : {
|
|
336
|
-
...current,
|
|
337
|
-
...op.set
|
|
338
|
-
};
|
|
339
|
-
for (const index of table.indexes) {
|
|
340
|
-
if (!index.unique) continue;
|
|
341
|
-
for (const eq of (0, _hot_updater_plugin_core_internal.indexEntries)(table, index, row)) if ((await adapter.query(table, {
|
|
342
|
-
index: index.name,
|
|
343
|
-
eq,
|
|
344
|
-
order: "asc",
|
|
345
|
-
limit: 2
|
|
346
|
-
})).some((other) => (0, _hot_updater_plugin_core_internal.compareTuples)((0, _hot_updater_plugin_core_internal.rowKey)(table, other), key))) return "unique";
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
return { async transaction(fn) {
|
|
350
|
-
assertOutsideTransaction();
|
|
351
|
-
let run;
|
|
352
|
-
let negative;
|
|
353
|
-
for (let round = 0; round < attempts; round += 1) {
|
|
354
|
-
const delay = round && Math.min(maxDelayMs, baseDelayMs * 2 ** (round - 1));
|
|
355
|
-
if (delay > 0) await new Promise((resolve) => setTimeout(resolve, delay / 2 + Math.random() * (delay / 2)));
|
|
356
|
-
run ??= await attempt(fn).catch((error) => {
|
|
357
|
-
if (error instanceof StaleReadError) return void 0;
|
|
358
|
-
throw error;
|
|
359
|
-
});
|
|
360
|
-
if (run === void 0) {
|
|
361
|
-
onRetry?.("rerun", round + 1);
|
|
362
|
-
continue;
|
|
363
|
-
}
|
|
364
|
-
let aggregates;
|
|
365
|
-
try {
|
|
366
|
-
aggregates = await require_engineAggregates.compileAggregates(adapter, run.aggregates);
|
|
367
|
-
} catch (error) {
|
|
368
|
-
if (!(error instanceof require_engineAggregates.NegativeGaugeError)) throw error;
|
|
369
|
-
negative = error;
|
|
370
|
-
onRetry?.("rerun", round + 1);
|
|
371
|
-
run = void 0;
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
const ops = [...run.ops, ...aggregates];
|
|
375
|
-
if (ops.length <= 1 && ops.every(({ type }) => type === "check")) return run.result;
|
|
376
|
-
if (!adapter.fits(ops)) throw new require_errors.DatabaseConstraintError("too_large", ops[0].table.name);
|
|
377
|
-
let outcome;
|
|
378
|
-
try {
|
|
379
|
-
outcome = await adapter.write(ops);
|
|
380
|
-
} catch (cause) {
|
|
381
|
-
throw new require_errors.DatabaseAmbiguousCommitError("The commit outcome is unknown.", { cause });
|
|
382
|
-
}
|
|
383
|
-
if (outcome.ok) return run.result;
|
|
384
|
-
const failed = "failedOp" in outcome ? outcome.failedOp : void 0;
|
|
385
|
-
if (failed === void 0 || failed >= run.ops.length) {
|
|
386
|
-
onRetry?.("resend", round + 1);
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
const reason = await classify(ops[failed], run.read);
|
|
390
|
-
if (reason) throw new require_errors.DatabaseConstraintError(reason, ops[failed].table.name);
|
|
391
|
-
onRetry?.("rerun", round + 1);
|
|
392
|
-
run = void 0;
|
|
393
|
-
}
|
|
394
|
-
throw negative ?? new require_errors.DatabaseConflictError(`The transaction conflicted ${attempts} times.`);
|
|
395
|
-
} };
|
|
396
|
-
};
|
|
397
|
-
//#endregion
|
|
398
|
-
exports.assertOutsideTransaction = assertOutsideTransaction;
|
|
399
|
-
exports.createTransactions = createTransactions;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import "./resolveSchema.cjs";
|
|
2
|
-
import { Page, ReadInput } from "./engineReads.cjs";
|
|
3
|
-
import { DatabaseAdapter, DatabaseKeyValue, StoredRow } from "@hot-updater/plugin-core/internal";
|
|
4
|
-
//#region src/database/engineTransaction.d.ts
|
|
5
|
-
interface RetryOptions {
|
|
6
|
-
readonly attempts?: number;
|
|
7
|
-
readonly baseDelayMs?: number;
|
|
8
|
-
readonly maxDelayMs?: number;
|
|
9
|
-
/** Called before each rerun of `fn` and each resend of the same write, with the attempt that failed (from 1). */
|
|
10
|
-
readonly onRetry?: (kind: "rerun" | "resend", attempt: number) => void;
|
|
11
|
-
}
|
|
12
|
-
type Row = Record<string, unknown>;
|
|
13
|
-
type Lookup = Readonly<Record<string, DatabaseKeyValue>>;
|
|
14
|
-
/** The handle `fn` receives, by physical table name; `database()` types it per module. */
|
|
15
|
-
interface TransactionEngine {
|
|
16
|
-
findOne(table: string, lookup: Lookup): Promise<StoredRow | null>;
|
|
17
|
-
findMany(table: string, input: ReadInput): Promise<Page<StoredRow>>;
|
|
18
|
-
create(table: string, row: Readonly<Row>): void;
|
|
19
|
-
update(table: string, row: StoredRow, set: Readonly<Row>): void;
|
|
20
|
-
delete(table: string, row: StoredRow): Promise<void>;
|
|
21
|
-
aggregate(table: string, identity: Readonly<Row>, values: Readonly<Row>, options?: {
|
|
22
|
-
readonly shardBy?: string;
|
|
23
|
-
}): void;
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
export { RetryOptions, TransactionEngine };
|