hot-updater 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.mjs +1 -1
- package/dist/{fingerprint-D0Q1Sl5G.mjs → fingerprint-DyKBEn51.mjs} +339 -685
- package/dist/index.mjs +1 -1
- package/dist/infra-templates/aws/lambda/index.cjs +1 -1
- package/dist/infra-templates/aws/template.json +10 -10
- package/dist/infra-templates/azure/azure/function/index.mjs +1 -1
- package/dist/infra-templates/azure/template.json +11 -11
- package/dist/infra-templates/cloudflare/template.json +10 -10
- package/dist/infra-templates/cloudflare/worker/dist/README.md +1 -1
- package/dist/infra-templates/cloudflare/worker/dist/index.js +1 -1
- package/dist/infra-templates/cloudflare/worker/dist/index.js.map +1 -1
- package/dist/infra-templates/firebase/firebase/functions/index.cjs +1 -1
- package/dist/infra-templates/firebase/template.json +11 -11
- package/dist/infra-templates/supabase/supabase/functions/hot-updater-v1/_hot-updater/hot-updater-server/dist/package.cjs +1 -1
- package/dist/infra-templates/supabase/supabase/functions/hot-updater-v1/_hot-updater/hot-updater-server/dist/package.mjs +1 -1
- package/dist/infra-templates/supabase/template.json +10 -10
- package/dist/infra-templates/vercel/template.json +12 -12
- package/dist/infra-templates/vercel/vercel/api/index.mjs +1 -1
- package/package.json +24 -26
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../plugin-core/dist/contentAddressedAssets.mjs", "../../../plugin-core/dist/createStorageKeyBuilder.mjs", "../../../plugin-core/dist/parseStorageUri.mjs", "../../../plugin-core/dist/assetStorageLayout.mjs", "../../../plugin-core/dist/bundleStorageLayout.mjs", "../../../plugin-core/dist/databaseErrors.mjs", "../../../plugin-core/dist/createStorageAdapter.mjs", "../../../plugin-core/dist/databaseJsonValue.mjs", "../../../plugin-core/dist/databaseMetadata.mjs", "../../../../packages/protocol/dist/index.mjs", "../../../plugin-core/dist/databaseRows.mjs", "../../../plugin-core/dist/uuidv7.mjs", "../../../plugin-core/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs", "../../../plugin-core/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.mjs", "../../../plugin-core/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs", "../../../plugin-core/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs", "../../../plugin-core/dist/releaseCatalogCompiler.mjs", "../../../plugin-core/dist/releaseManagement.mjs", "../../../plugin-core/dist/releaseCatalogMutation.mjs", "../../../plugin-core/dist/semverSatisfies.mjs", "../../../plugin-core/dist/serverPlugin/definePlugin.mjs", "../../../plugin-core/dist/serverPlugin/schema.mjs", "../../../plugin-core/dist/serverPlugin/errors.mjs", "../../../plugin-core/dist/serverPlugin/busy.mjs", "../../../plugin-core/dist/database/distinct.mjs", "../../../plugin-core/dist/serverPlugin/configError.mjs", "../../../plugin-core/dist/baseCandidateKey.mjs", "../../../plugin-core/dist/database/adapter.mjs", "../../../plugin-core/dist/database/values.mjs", "../../../plugin-core/dist/database/verifyAdapter.mjs", "../../../plugin-core/dist/engine/database/fence.mjs", "../../../plugin-core/dist/engine/database/readMeter.mjs", "../../../plugin-core/dist/engine/db/schemaSettings.mjs", "../../../plugin-core/dist/engine/database/sql/sqlSchema.mjs", "../../../plugin-core/dist/engine/core/schema.mjs", "../../../plugin-core/dist/engine/db/fixedMigratorShared.mjs", "../../../plugin-core/dist/engine/db/settingsMigrator.mjs", "../../../plugin-core/dist/engine/database/cursor.mjs", "../../../plugin-core/dist/engine/database/engineAggregates.mjs", "../../../plugin-core/dist/engine/database/aggregateBatching.mjs", "../../../plugin-core/dist/engine/database/retention.mjs", "../../../plugin-core/dist/engine/database/resolveSchema.mjs", "../../../plugin-core/dist/engine/db/engineMigrator.mjs", "../../../plugin-core/dist/engine/db/coreDatabase.mjs", "../../../plugin-core/dist/engine/database/engineTransaction.mjs", "../../../plugin-core/dist/engine/database/engineReads.mjs", "../../../plugin-core/dist/engine/database/engine.mjs", "../../../plugin-core/dist/engine/database/database.mjs", "../../../plugin-core/dist/engine/createEngine.mjs", "../../../plugin-core/dist/engine/database/sql/sqlAdapter.mjs", "../../../../packages/server/dist/package.mjs", "../../../../packages/server/dist/version.mjs", "../../../../packages/server/dist/handlerVersionRoutes.mjs", "../../../../packages/server/dist/plugins/official.mjs", "../../../../packages/server/dist/assembly/clientPlugins.mjs", "../../../../packages/server/dist/db/releaseCatalog.mjs", "../../../../packages/server/dist/db/updateArtifacts.mjs", "../../../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js", "../../../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.js", "../../../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.js", "../../../../packages/server/dist/core/baseCandidates.mjs", "../../../../packages/server/dist/core/reads.mjs", "../../../../packages/server/dist/core/writes.mjs", "../../../../packages/server/dist/core/releases.mjs", "../../../../packages/server/dist/core/operations.mjs", "../../../../packages/server/dist/core/api.mjs", "../../../../packages/server/dist/assembly/assemblePlugins.mjs", "../../../../packages/server/dist/handlerErrors.mjs", "../../../../packages/server/dist/handlerParameters.mjs", "../../../../packages/server/dist/handlerAdminRoutes.mjs", "../../../../packages/server/dist/handlerReleaseCatalogRoutes.mjs", "../../../../packages/server/dist/internalRouter.mjs", "../../../../packages/server/dist/handler.mjs", "../../../../packages/server/dist/storageAccess.mjs", "../../../../packages/server/dist/createHotUpdaterCore.mjs", "../../../api-keys/dist/server/apiKeys.mjs", "../../../api-keys/dist/server/cli.mjs", "../../../api-keys/dist/server/model.mjs", "../../../api-keys/dist/server/official.mjs", "../../../api-keys/dist/server/schema.mjs", "../../../api-keys/dist/server/index.mjs", "../../../insights/dist/server/schema.mjs", "../../../insights/dist/server/eventRow.mjs", "../../../insights/dist/server/contract.mjs", "../../../insights/dist/server/model.mjs", "../../../insights/dist/server/official.mjs", "../../../insights/dist/server/errors.mjs", "../../../insights/dist/server/eventInput.mjs", "../../../insights/dist/server/provider.mjs", "../../../insights/dist/server/overview.mjs", "../../../insights/dist/server/recordEvent.mjs", "../../../insights/dist/server/reads.mjs", "../../../insights/dist/server/queryInput.mjs", "../../../insights/dist/server/routes.mjs", "../../../insights/dist/server/index.mjs", "../../../remote-config/dist/shared/ownEntry.mjs", "../../../remote-config/dist/server/template.mjs", "../../../remote-config/dist/server/api.mjs", "../../../remote-config/dist/server/official.mjs", "../../../remote-config/dist/shared/wire.mjs", "../../../remote-config/dist/server/routes.mjs", "../../../remote-config/dist/server/schema.mjs", "../../../remote-config/dist/server/index.mjs", "../src/index.ts", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/compose.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/request/constants.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/buffer.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/body.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/url.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/request.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/html.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/context.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/constants.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/hono-base.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/reg-exp-router/matcher.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/reg-exp-router/node.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/reg-exp-router/trie.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/reg-exp-router/router.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/smart-router/router.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/trie-router/node.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/router/trie-router/router.js", "../../../../node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/hono.js", "../../src/d1Executor.ts", "../../src/worker/d1Database.ts", "../../src/presignR2Url.ts", "../../src/r2WorkerStorage.ts"],
|
|
4
4
|
"sourceRoot": "./worker/dist",
|
|
5
|
-
"sourcesContent": ["//#region src/contentAddressedAssets.ts\nconst CONTENT_ADDRESSED_ASSET_PREFIX = \"assets\";\nconst SHA256_FILE_HASH_RE = /^[0-9a-f]{64}$/;\nconst isContentAddressedAssetFileHash = (value) => {\n\treturn typeof value === \"string\" && SHA256_FILE_HASH_RE.test(value);\n};\nconst getContentAddressedAssetStoragePath = ({ assetPath, fileHash }) => {\n\tconst extension = assetPath.endsWith(\".br\") ? \".br\" : assetPath.includes(\".\") ? `.${assetPath.split(\".\").pop()}` : \"\";\n\treturn `sha256/${fileHash.slice(0, 2)}/${fileHash}${extension}`;\n};\n//#endregion\nexport { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash };\n", "//#region src/createStorageKeyBuilder.ts\nconst normalizeStorageKeyParts = (values) => {\n\tif (values.some((value) => value.includes(\"\\\\\"))) throw new Error(\"Storage keys must use '/' as the hierarchy separator.\");\n\tconst segments = values.flatMap((value) => value.split(\"/\").filter(Boolean));\n\tif (segments.some((segment) => segment === \".\" || segment === \"..\")) throw new Error(\"Storage key segments must not be '.' or '..'.\");\n\treturn segments;\n};\nconst createStorageKeyBuilder = (basePath) => {\n\tconst baseSegments = normalizeStorageKeyParts([basePath ?? \"\"]);\n\treturn (...args) => [...baseSegments, ...normalizeStorageKeyParts(args)].join(\"/\");\n};\n//#endregion\nexport { createStorageKeyBuilder };\n", "//#region src/parseStorageUri.ts\nconst PROTOCOL_PATTERN = /^[a-z][a-z\\d+.-]*$/;\nconst INVALID_BUCKET_CHARACTER_PATTERN = /[\\s/?#%@:\\\\]/;\nconst assertProtocol = (protocol) => {\n\tif (!PROTOCOL_PATTERN.test(protocol)) throw new Error(`Invalid storage URI protocol: ${protocol}`);\n};\nconst assertBucket = (bucket) => {\n\tif (bucket.length === 0 || INVALID_BUCKET_CHARACTER_PATTERN.test(bucket)) throw new Error(`Invalid storage URI bucket: ${bucket}`);\n};\nconst getKeySegments = (key) => {\n\tif (key.length === 0) throw new Error(\"Invalid storage URI key: key must not be empty\");\n\tconst segments = key.split(\"/\");\n\tif (segments.some((segment) => segment.length === 0 || segment === \".\" || segment === \"..\" || segment.includes(\"\\\\\"))) throw new Error(\"Invalid storage URI key: segments must not be empty, '.', '..' or contain '\\\\'\");\n\treturn segments;\n};\n/**\n* Creates a hierarchical storage identifier in the form\n* `protocol://bucket/slash-separated-encoded-key`.\n*/\nconst createStorageUri = ({ protocol, bucket, key }) => {\n\tassertProtocol(protocol);\n\tassertBucket(bucket);\n\treturn `${protocol}://${bucket}/${getKeySegments(key).map(encodeURIComponent).join(\"/\")}`;\n};\n/**\n* Parses a hierarchical storage identifier and decodes each key segment.\n*\n* Search parameters and fragments are not part of a storage identifier.\n*/\nfunction parseStorageUri(storageUri, expectedProtocol) {\n\tassertProtocol(expectedProtocol);\n\tif (storageUri.includes(\"?\") || storageUri.includes(\"#\")) throw new Error(`Invalid storage URI format: ${storageUri}`);\n\tconst match = /^([a-z][a-z\\d+.-]*):\\/\\/([^/]+)\\/(.*)$/.exec(storageUri);\n\tif (!match) throw new Error(`Invalid storage URI format: ${storageUri}`);\n\tconst [, protocol, bucket, encodedKey] = match;\n\tif (protocol !== expectedProtocol) throw new Error(`Invalid storage URI protocol. Expected ${expectedProtocol}, got ${protocol}`);\n\tassertBucket(bucket);\n\tlet segments;\n\ttry {\n\t\tsegments = getKeySegments(encodedKey).map((segment) => {\n\t\t\tconst decoded = decodeURIComponent(segment);\n\t\t\tif (decoded.includes(\"/\") || decoded.includes(\"\\\\\")) throw new Error(\"encoded hierarchy separator\");\n\t\t\tif (encodeURIComponent(decoded) !== segment) throw new Error(\"non-canonical segment\");\n\t\t\treturn decoded;\n\t\t});\n\t} catch {\n\t\tthrow new Error(`Invalid storage URI format: ${storageUri}`);\n\t}\n\treturn {\n\t\tprotocol,\n\t\tbucket,\n\t\tkey: segments.join(\"/\")\n\t};\n}\n//#endregion\nexport { createStorageUri, parseStorageUri };\n", "import { getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash } from \"./contentAddressedAssets.mjs\";\nimport { createStorageKeyBuilder } from \"./createStorageKeyBuilder.mjs\";\nimport { createStorageUri, parseStorageUri } from \"./parseStorageUri.mjs\";\n//#region src/assetStorageLayout.ts\nconst isBrotliManifestAssetPath = (assetPath) => /(^|\\/)index\\.[^/]+\\.bundle$/.test(assetPath.replace(/\\\\/g, \"/\"));\nconst getManifestAssetDownloadPath = (assetPath) => isBrotliManifestAssetPath(assetPath) ? `${assetPath}.br` : assetPath;\nconst createStorageUriWithRelativePath = ({ baseStorageUri, relativePath }) => {\n\tconst protocol = new URL(baseStorageUri).protocol.replace(\":\", \"\");\n\tconst parsed = parseStorageUri(baseStorageUri, protocol);\n\tconst childKey = createStorageKeyBuilder(void 0)(relativePath);\n\tif (!childKey) throw new Error(\"Relative storage key must not be empty.\");\n\treturn createStorageUri({\n\t\tprotocol: parsed.protocol,\n\t\tbucket: parsed.bucket,\n\t\tkey: createStorageKeyBuilder(parsed.key)(childKey)\n\t});\n};\nconst replaceStorageUriKeySuffix = ({ storageUri, keySuffix, replacement }) => {\n\tconst protocol = new URL(storageUri).protocol.replace(\":\", \"\");\n\tconst parsed = parseStorageUri(storageUri, protocol);\n\tconst normalizedSuffix = createStorageKeyBuilder(void 0)(keySuffix);\n\tconst normalizedReplacement = createStorageKeyBuilder(void 0)(replacement);\n\tif (!normalizedSuffix || !normalizedReplacement) throw new Error(\"Storage URI key suffix and replacement must not be empty.\");\n\tconst keySegments = parsed.key.split(\"/\");\n\tconst suffixSegments = normalizedSuffix.split(\"/\");\n\tconst suffixOffset = keySegments.length - suffixSegments.length;\n\tif (suffixOffset < 0 || suffixSegments.some((segment, index) => keySegments[suffixOffset + index] !== segment)) throw new Error(\"Storage URI key does not end with the expected suffix.\");\n\tconst prefix = keySegments.slice(0, suffixOffset).join(\"/\");\n\treturn createStorageUri({\n\t\tprotocol: parsed.protocol,\n\t\tbucket: parsed.bucket,\n\t\tkey: createStorageKeyBuilder(prefix)(normalizedReplacement)\n\t});\n};\nconst resolveManifestAssetStorageFileHash = ({ downloadFileHash, fileHash }) => isContentAddressedAssetFileHash(downloadFileHash) ? downloadFileHash : fileHash;\nconst getManifestAssetStoragePath = ({ assetPath, downloadFileHash, fileHash }) => getContentAddressedAssetStoragePath({\n\tassetPath,\n\tfileHash: resolveManifestAssetStorageFileHash({\n\t\tdownloadFileHash,\n\t\tfileHash\n\t})\n});\nconst resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, downloadFileHash, fileHash }) => createStorageUriWithRelativePath({\n\tbaseStorageUri: assetBaseStorageUri,\n\trelativePath: getManifestAssetStoragePath({\n\t\tassetPath,\n\t\tdownloadFileHash,\n\t\tfileHash\n\t})\n});\n//#endregion\nexport { createStorageUriWithRelativePath, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, replaceStorageUriKeySuffix, resolveManifestAssetStorageFileHash, resolveManifestAssetStorageUri };\n", "import { replaceStorageUriKeySuffix } from \"./assetStorageLayout.mjs\";\n//#region src/bundleStorageLayout.ts\nconst BUNDLE_STORAGE_PREFIX = \"bundles\";\nconst createBundleStorageKey = (bundleId, ...relativePaths) => [\n\tBUNDLE_STORAGE_PREFIX,\n\tbundleId,\n\t...relativePaths\n].filter(Boolean).join(\"/\");\nconst getBundleArchiveStorageUri = ({ manifestStorageUri, bundleId }) => replaceStorageUriKeySuffix({\n\tstorageUri: manifestStorageUri,\n\tkeySuffix: createBundleStorageKey(bundleId, \"manifest.json\"),\n\treplacement: createBundleStorageKey(bundleId, \"bundle.tar.br\")\n});\nconst createStorageRootUriWithPath = (storageUri, bundleId, relativePath) => {\n\tconst storageUrl = new URL(storageUri);\n\tconst segments = storageUrl.pathname.split(\"/\").filter(Boolean);\n\tconst bundleIndex = segments.lastIndexOf(bundleId);\n\tif (bundleIndex < 1 || segments[bundleIndex - 1] !== \"bundles\") throw new Error(`Storage URI does not contain canonical bundle path: ${BUNDLE_STORAGE_PREFIX}/${bundleId}`);\n\tconst rootSegments = segments.slice(0, bundleIndex - 1);\n\tconst relativeSegments = relativePath.split(\"/\").filter(Boolean).map((segment) => encodeURIComponent(segment));\n\tstorageUrl.pathname = `/${[...rootSegments, ...relativeSegments].join(\"/\")}`;\n\treturn storageUrl.toString();\n};\n//#endregion\nexport { BUNDLE_STORAGE_PREFIX, createBundleStorageKey, createStorageRootUriWithPath, getBundleArchiveStorageUri };\n", "//#region src/databaseErrors.ts\n/** A bundle an operation names is not stored. */\nvar DatabaseBundleNotFoundError = class extends Error {\n\tbundleId;\n\tname = \"DatabaseBundleNotFoundError\";\n\tconstructor(bundleId) {\n\t\tsuper(`Bundle \"${bundleId}\" was not found.`);\n\t\tthis.bundleId = bundleId;\n\t}\n};\n/** A row a delete names is still referenced, such as a bundle a release uses. */\nvar DatabaseRowReferencedError = class extends Error {\n\tname = \"DatabaseRowReferencedError\";\n\tconstructor() {\n\t\tsuper(\"The database row is still referenced.\");\n\t}\n};\n/** Input a database operation refuses before touching storage. */\nvar DatabaseAdapterInputError = class extends Error {\n\tcode;\n\tname = \"DatabaseAdapterInputError\";\n\tconstructor(code) {\n\t\tsuper(`Invalid database adapter input: ${code}`);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { DatabaseAdapterInputError, DatabaseBundleNotFoundError, DatabaseRowReferencedError };\n", "//#region src/createStorageAdapter.ts\nconst createStorageAdapter = (options) => ({ ...options });\nfunction assertStorageOperations(adapter, operations) {\n\tfor (const operation of operations) if (typeof adapter[operation] !== \"function\") throw new Error(`Storage adapter \"${adapter.name}\" does not implement ${operation}.`);\n}\n//#endregion\nexport { assertStorageOperations, createStorageAdapter };\n", "//#region src/databaseJsonValue.ts\nconst isDatabaseJsonValue = (value) => {\n\tconst ancestors = /* @__PURE__ */ new WeakSet();\n\tconst validate = (input) => {\n\t\tif (input === null || typeof input === \"string\" || typeof input === \"boolean\") return true;\n\t\tif (typeof input === \"number\") return Number.isFinite(input);\n\t\tif (typeof input !== \"object\") return false;\n\t\tif (ancestors.has(input)) return false;\n\t\tancestors.add(input);\n\t\ttry {\n\t\t\tif (Array.isArray(input)) {\n\t\t\t\tif (Object.getPrototypeOf(input) !== Array.prototype) return false;\n\t\t\t\tif (Reflect.ownKeys(input).length !== input.length + 1) return false;\n\t\t\t\tfor (let index = 0; index < input.length; index += 1) {\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(input, String(index));\n\t\t\t\t\tif (descriptor === void 0 || !descriptor.enumerable || !(\"value\" in descriptor) || !validate(descriptor.value)) return false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst prototype = Object.getPrototypeOf(input);\n\t\t\tif (prototype !== Object.prototype && prototype !== null) return false;\n\t\t\tfor (const key of Reflect.ownKeys(input)) {\n\t\t\t\tif (typeof key !== \"string\" || key === \"__proto__\") return false;\n\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(input, key);\n\t\t\t\tif (descriptor === void 0 || !descriptor.enumerable || !(\"value\" in descriptor) || !validate(descriptor.value)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t} finally {\n\t\t\tancestors.delete(input);\n\t\t}\n\t};\n\treturn validate(value);\n};\n/**\n* Whether `value` is a plain object of JSON values a store keeps as they\n* are: no cycles, accessors, non-finite numbers, or class instances. A\n* plugin checks a `json` field's value with it before it writes, as\n* Insights does for an event's metadata.\n*/\nconst isDatabaseJsonObject = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value) && isDatabaseJsonValue(value);\nconst isDatabaseMetadataObject = (value) => isDatabaseJsonObject(value) && (!Object.hasOwn(value, \"app_version\") || typeof value[\"app_version\"] === \"string\");\n//#endregion\nexport { isDatabaseJsonObject, isDatabaseJsonValue, isDatabaseMetadataObject };\n", "import { DatabaseAdapterInputError } from \"./databaseErrors.mjs\";\nimport { isDatabaseMetadataObject } from \"./databaseJsonValue.mjs\";\n//#region src/databaseMetadata.ts\nconst bundleMetadataToRow = (metadata) => {\n\tif (metadata === void 0) return {};\n\tif (!isDatabaseMetadataObject(metadata)) throw new DatabaseAdapterInputError(\"invalid-data\");\n\treturn metadata;\n};\n//#endregion\nexport { bundleMetadataToRow };\n", "//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nString.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nString.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nString.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction formatFullVersion(version) {\n\tconst comparable = formatComparableVersion(version);\n\treturn version.build?.length ? `${comparable}+${version.build.join(\".\")}` : comparable;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.js\nconst COERCE_EXACT = safeRegex(COERCE);\nconst COERCE_FULL_EXACT = safeRegex(COERCE_FULL);\nsafeRegex(`^${PRERELEASE}$`);\nsafeRegex(`^${PRERELEASE_LOOSE}$`);\nfunction normalizeFull(version, options = {}) {\n\tconst parsed = tryParse(version, options);\n\treturn parsed ? formatFullVersion(parsed) : null;\n}\nfunction coerce(value, options = {}) {\n\tif (typeof value === \"object\") return value;\n\tconst input = typeof value === \"number\" ? String(value) : value;\n\tlet match = null;\n\tif (options.rtl) {\n\t\tconst expression = safeRegex(options.includePrerelease ? COERCE_FULL : COERCE, \"g\");\n\t\tlet next;\n\t\twhile ((next = expression.exec(input)) && (!match || match.index + match[0].length !== input.length)) {\n\t\t\tif (!match || next.index + next[0].length !== match.index + match[0].length) match = next;\n\t\t\texpression.lastIndex = next.index + next[1].length + next[2].length;\n\t\t}\n\t} else match = (options.includePrerelease ? COERCE_FULL_EXACT : COERCE_EXACT).exec(input);\n\tif (!match) return null;\n\tconst major = match[2];\n\treturn tryParse(`${major}.${match[3] || \"0\"}.${match[4] || \"0\"}${options.includePrerelease && match[5] ? `-${match[5]}` : \"\"}${options.includePrerelease && match[6] ? `+${match[6]}` : \"\"}`, options);\n}\n//#endregion\n//#region src/appVersion.ts\n/**\n* The form of an app version that the device and the server compare:\n* `major.minor.patch` of the first version in `appVersion`, such as `1.4.0`\n* for `v1.4`, or null when it holds none. Prerelease and build parts are\n* dropped.\n*/\nfunction canonicalizeAppVersion(appVersion) {\n\tconst version = coerce(appVersion);\n\treturn version ? normalizeFull(version) : null;\n}\n//#endregion\n//#region src/baseURL.ts\n/** Resolves a functional baseURL and drops trailing slashes. */\nconst resolveBaseURL = async (baseURL) => {\n\tconst resolvedBaseURL = typeof baseURL === \"function\" ? await baseURL() : baseURL;\n\tif (!resolvedBaseURL) throw new Error(\"baseURL function must return a non-empty string\");\n\treturn resolvedBaseURL.replace(/\\/+$/, \"\");\n};\n//#endregion\n//#region src/bundleArtifacts.ts\nconst getManifestStorageUri = (bundle) => bundle.manifestStorageUri;\nconst getManifestFileHash = (bundle) => bundle.manifestFileHash;\nconst getAssetBaseStorageUri = (bundle) => bundle.assetBaseStorageUri;\nconst isBundlePatchArtifact = (value) => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst candidate = value;\n\treturn typeof candidate.baseBundleId === \"string\" && typeof candidate.baseFileHash === \"string\" && typeof candidate.patchFileHash === \"string\" && typeof candidate.patchStorageUri === \"string\";\n};\nconst readBundlePatchArray = (patches) => {\n\tif (!Array.isArray(patches)) return [];\n\treturn patches.filter(isBundlePatchArtifact);\n};\nconst getBundlePatches = (bundle) => {\n\tconst patches = readBundlePatchArray(bundle.patches);\n\tconst seenBaseBundleIds = /* @__PURE__ */ new Set();\n\treturn patches.filter((patch) => {\n\t\tif (seenBaseBundleIds.has(patch.baseBundleId)) return false;\n\t\tseenBaseBundleIds.add(patch.baseBundleId);\n\t\treturn true;\n\t});\n};\nconst getBundlePatch = (bundle, baseBundleId) => {\n\treturn getBundlePatches(bundle).find((patch) => patch.baseBundleId === baseBundleId) ?? null;\n};\nconst getPrimaryPatch = (bundle) => {\n\treturn getBundlePatches(bundle)[0] ?? null;\n};\nconst getPatchBaseBundleId = (bundle) => getPrimaryPatch(bundle)?.baseBundleId ?? null;\nconst getPatchBaseFileHash = (bundle) => getPrimaryPatch(bundle)?.baseFileHash ?? null;\nconst getPatchFileHash = (bundle) => getPrimaryPatch(bundle)?.patchFileHash ?? null;\nconst getPatchStorageUri = (bundle) => getPrimaryPatch(bundle)?.patchStorageUri ?? null;\n//#endregion\n//#region src/clientPlugin.ts\n/** Declares a client plugin; built-in and third-party plugins use the same contract. */\nconst defineClientPlugin = (plugin) => plugin;\n//#endregion\n//#region src/createPluginHost.ts\n/** Storage values stay small, since native reads them on the JS thread. */\nconst MAX_STORAGE_VALUE_LENGTH = 65536;\n/** Where a plugin's key lives in native storage. */\nconst pluginStorageKey = (pluginId, key) => `plugins/${encodeURIComponent(pluginId)}/${key}`;\nconst createPluginHost = (environment) => {\n\tlet config = null;\n\t/** Hooks and API by plugin, so a plugin configured again is not set up twice. */\n\tconst setUpPlugins = /* @__PURE__ */ new WeakMap();\n\tlet activePlugins = [];\n\t/** What plugins read and wrote, so a read follows a write before native does. */\n\tconst storageValues = /* @__PURE__ */ new Map();\n\tconst reportHookError = (message, error) => {\n\t\tconst report = new Error(`[HotUpdater] ${message}`, { cause: error });\n\t\ttry {\n\t\t\tif (config?.onError) {\n\t\t\t\tconfig.onError(report);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {}\n\t\tconsole.warn(report.message, error);\n\t};\n\tconst fetchFromServer = async (path, init = {}) => {\n\t\tif (config === null) throw new Error(\"[HotUpdater] Plugins can fetch only after HotUpdater.init.\");\n\t\tif (/^[a-z][a-z\\d+.-]*:/i.test(path) || path.startsWith(\"//\")) throw new TypeError(\"[HotUpdater] Plugin fetch takes a path relative to baseURL.\");\n\t\tconst { requestHeaders, requestTimeout } = config;\n\t\tconst url = `${await resolveBaseURL(config.baseURL)}/${path.replace(/^\\/+/, \"\")}`;\n\t\tconst headers = new Headers(requestHeaders);\n\t\tnew Headers(init.headers).forEach((value, name) => {\n\t\t\theaders.set(name, value);\n\t\t});\n\t\tconst controller = new AbortController();\n\t\tconst callerSignal = init.signal;\n\t\tconst abortFromCaller = () => controller.abort();\n\t\tif (callerSignal?.aborted) controller.abort();\n\t\tcallerSignal?.addEventListener(\"abort\", abortFromCaller);\n\t\tlet timedOut = false;\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, requestTimeout ?? 5e3);\n\t\ttry {\n\t\t\treturn await environment.fetch(url, {\n\t\t\t\t...init,\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (!callerSignal?.aborted && (timedOut || error instanceof Error && error.name === \"AbortError\")) throw new Error(\"Request timed out\");\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tcallerSignal?.removeEventListener(\"abort\", abortFromCaller);\n\t\t}\n\t};\n\tconst createStorage = (pluginId) => {\n\t\tconst scopedKey = (key) => {\n\t\t\tif (typeof key !== \"string\" || key.length === 0) throw new TypeError(\"[HotUpdater] Plugin storage keys are non-empty strings.\");\n\t\t\treturn pluginStorageKey(pluginId, key);\n\t\t};\n\t\treturn {\n\t\t\tget: (key) => {\n\t\t\t\tconst storageKey = scopedKey(key);\n\t\t\t\tconst cached = storageValues.get(storageKey);\n\t\t\t\tif (cached !== void 0) return cached;\n\t\t\t\tconst value = environment.getStorageItem(storageKey);\n\t\t\t\tstorageValues.set(storageKey, value);\n\t\t\t\treturn value;\n\t\t\t},\n\t\t\tset: (key, value) => {\n\t\t\t\tconst storageKey = scopedKey(key);\n\t\t\t\tif (value !== null && typeof value !== \"string\") throw new TypeError(\"[HotUpdater] Plugin storage values are strings or null.\");\n\t\t\t\tif (value !== null && value.length > MAX_STORAGE_VALUE_LENGTH) throw new RangeError(\"[HotUpdater] Plugin storage values are at most 64 KB.\");\n\t\t\t\tenvironment.setStorageItem(storageKey, value);\n\t\t\t\tstorageValues.set(storageKey, value);\n\t\t\t}\n\t\t};\n\t};\n\tconst createContext = (pluginId) => ({\n\t\tfetch: fetchFromServer,\n\t\tget installId() {\n\t\t\treturn environment.getInstallId();\n\t\t},\n\t\tplatform: environment.platform,\n\t\tget appVersion() {\n\t\t\treturn environment.getAppVersion();\n\t\t},\n\t\tget sdkVersion() {\n\t\t\treturn environment.sdkVersion;\n\t\t},\n\t\tget minBundleId() {\n\t\t\treturn environment.getMinBundleId();\n\t\t},\n\t\tisDebugBuild: environment.isDebugBuild,\n\t\tgetBundleId: () => environment.getBundleId(),\n\t\tgetChannel: () => environment.getChannel(),\n\t\tgetCohort: () => environment.getCohort(),\n\t\tgetFingerprintHash: () => environment.getFingerprintHash(),\n\t\tstorage: createStorage(pluginId),\n\t\tnow: () => environment.now()\n\t});\n\tconst setUpPlugin = (plugin) => {\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = plugin.setup(createContext(plugin.id));\n\t\t} catch (error) {\n\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in setup`, error);\n\t\t\treturn {\n\t\t\t\thooks: {},\n\t\t\t\tapi: void 0\n\t\t\t};\n\t\t}\n\t\tif (result === void 0 || result === null) return {\n\t\t\thooks: {},\n\t\t\tapi: void 0\n\t\t};\n\t\tconst unknownKeys = Object.keys(result).filter((key) => key !== \"hooks\" && key !== \"api\");\n\t\tif (unknownKeys.length > 0) reportHookError(`Plugin \"${plugin.id}\" setup returned ${unknownKeys.map((key) => `\"${key}\"`).join(\", \")}; setup returns { hooks, api }`, /* @__PURE__ */ new TypeError(\"Unexpected setup result\"));\n\t\treturn {\n\t\t\thooks: result.hooks ?? {},\n\t\t\tapi: result.api\n\t\t};\n\t};\n\tconst configurePlugins = (plugins, nextConfig) => {\n\t\tconst ids = /* @__PURE__ */ new Set();\n\t\tfor (const plugin of plugins ?? []) {\n\t\t\tif (typeof plugin.id !== \"string\" || plugin.id.length === 0) throw new Error(\"[HotUpdater] A plugin id must be a non-empty string.\");\n\t\t\tif (ids.has(plugin.id)) throw new Error(`[HotUpdater] Two plugins use the id \"${plugin.id}\". Plugin ids must be unique.`);\n\t\t\tids.add(plugin.id);\n\t\t}\n\t\tconfig = nextConfig;\n\t\tconst apis = [];\n\t\tactivePlugins = (plugins ?? []).map((plugin) => {\n\t\t\tlet setUp = setUpPlugins.get(plugin);\n\t\t\tif (setUp === void 0) {\n\t\t\t\tsetUp = setUpPlugin(plugin);\n\t\t\t\tsetUpPlugins.set(plugin, setUp);\n\t\t\t}\n\t\t\tif (setUp.api !== void 0) apis.push([plugin.id, setUp.api]);\n\t\t\treturn {\n\t\t\t\tplugin,\n\t\t\t\thooks: setUp.hooks\n\t\t\t};\n\t\t});\n\t\treturn Object.freeze(Object.fromEntries(apis));\n\t};\n\tconst hasPluginHook = (name) => activePlugins.some(({ hooks }) => typeof hooks[name] === \"function\");\n\tconst buildPluginEvent = (name, createPayload) => {\n\t\tif (!hasPluginHook(name)) return null;\n\t\ttry {\n\t\t\treturn createPayload();\n\t\t} catch (error) {\n\t\t\treportHookError(`Failed to build the ${name} event for plugins`, error);\n\t\t\treturn null;\n\t\t}\n\t};\n\tconst dispatchPluginHook = (name, payload) => {\n\t\tconst settlements = [];\n\t\tfor (const { plugin, hooks } of activePlugins) {\n\t\t\tconst hook = hooks[name];\n\t\t\tif (typeof hook !== \"function\") continue;\n\t\t\ttry {\n\t\t\t\tconst result = hook.call(hooks, payload);\n\t\t\t\tif (result !== null && typeof result === \"object\" && typeof result.then === \"function\") settlements.push(Promise.resolve(result).then(() => void 0, (error) => {\n\t\t\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in ${name}`, error);\n\t\t\t\t}));\n\t\t\t} catch (error) {\n\t\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in ${name}`, error);\n\t\t\t}\n\t\t}\n\t\treturn settlements;\n\t};\n\tconst emitPluginHook = (name, createPayload) => {\n\t\tconst payload = buildPluginEvent(name, createPayload);\n\t\tif (payload !== null) dispatchPluginHook(name, payload);\n\t};\n\treturn {\n\t\tconfigurePlugins,\n\t\thasPluginHook,\n\t\tbuildPluginEvent,\n\t\tdispatchPluginHook,\n\t\temitPluginHook\n\t};\n};\n//#endregion\n//#region src/rollout.ts\nconst NUMERIC_COHORT_SIZE = 1e3;\nconst DEFAULT_ROLLOUT_COHORT_COUNT = NUMERIC_COHORT_SIZE;\nconst MAX_COHORT_LENGTH = 64;\nconst INVALID_COHORT_ERROR_MESSAGE = `Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.`;\nconst CUSTOM_COHORT_PATTERN = /^[a-z0-9-]+$/;\nfunction parseNumericCohortValue(cohort) {\n\tif (!/^\\d+$/.test(cohort)) return null;\n\tconst parsed = Number.parseInt(cohort, 10);\n\tif (Number.isNaN(parsed) || parsed < 1 || parsed > 1e3) return null;\n\treturn parsed;\n}\nfunction positiveMod(value, modulus) {\n\treturn (value % modulus + modulus) % modulus;\n}\nfunction hashString(value) {\n\tlet hash = 0;\n\tfor (let i = 0; i < value.length; i++) {\n\t\tconst char = value.charCodeAt(i);\n\t\thash = (hash << 5) - hash + char;\n\t\thash |= 0;\n\t}\n\treturn hash;\n}\nfunction gcd(a, b) {\n\tlet x = Math.abs(a);\n\tlet y = Math.abs(b);\n\twhile (y !== 0) {\n\t\tconst next = x % y;\n\t\tx = y;\n\t\ty = next;\n\t}\n\treturn x;\n}\nfunction modularInverse(value, modulus) {\n\tlet t = 0;\n\tlet newT = 1;\n\tlet r = modulus;\n\tlet newR = positiveMod(value, modulus);\n\twhile (newR !== 0) {\n\t\tconst quotient = Math.floor(r / newR);\n\t\t[t, newT] = [newT, t - quotient * newT];\n\t\t[r, newR] = [newR, r - quotient * newR];\n\t}\n\tif (r > 1) throw new Error(`No modular inverse for ${value} mod ${modulus}`);\n\treturn positiveMod(t, modulus);\n}\nfunction getRolloutShuffleParameters(bundleId) {\n\tlet multiplier = positiveMod(hashString(`${bundleId}:multiplier`), 997);\n\tif (multiplier === 0) multiplier = 1;\n\twhile (gcd(multiplier, NUMERIC_COHORT_SIZE) !== 1) {\n\t\tmultiplier = positiveMod(multiplier + 1, NUMERIC_COHORT_SIZE);\n\t\tif (multiplier === 0) multiplier = 1;\n\t}\n\tconst offset = positiveMod(hashString(`${bundleId}:offset`), NUMERIC_COHORT_SIZE);\n\treturn {\n\t\tmultiplier,\n\t\toffset,\n\t\tinverseMultiplier: modularInverse(multiplier, NUMERIC_COHORT_SIZE)\n\t};\n}\nfunction normalizeRolloutCohortCount(rolloutCohortCount) {\n\tif (rolloutCohortCount === null || rolloutCohortCount === void 0) return DEFAULT_ROLLOUT_COHORT_COUNT;\n\tif (rolloutCohortCount <= 0) return 0;\n\tif (rolloutCohortCount >= 1e3) return NUMERIC_COHORT_SIZE;\n\treturn Math.floor(rolloutCohortCount);\n}\nfunction normalizeCohortValue(cohort) {\n\tconst normalized = cohort.trim().toLowerCase();\n\tconst numericCohort = parseNumericCohortValue(normalized);\n\tif (numericCohort !== null) return String(numericCohort);\n\treturn normalized;\n}\nfunction getNumericCohortValue(cohort) {\n\treturn parseNumericCohortValue(normalizeCohortValue(cohort));\n}\nfunction isNumericCohort(cohort) {\n\treturn getNumericCohortValue(cohort) !== null;\n}\nfunction isCustomCohort(cohort) {\n\tconst normalized = normalizeCohortValue(cohort);\n\treturn normalized.length > 0 && normalized.length <= 64 && !/^\\d+$/.test(normalized) && CUSTOM_COHORT_PATTERN.test(normalized);\n}\nfunction isValidCohort(cohort) {\n\tconst normalized = normalizeCohortValue(cohort);\n\treturn isNumericCohort(normalized) || isCustomCohort(normalized);\n}\nfunction getDefaultNumericCohort(identifier) {\n\tconst cohortValue = positiveMod(hashString(identifier), NUMERIC_COHORT_SIZE) + 1;\n\treturn String(cohortValue);\n}\nfunction getNumericCohortRolloutPosition(bundleId, cohortValue) {\n\tif (cohortValue < 1 || cohortValue > 1e3) throw new Error(`Invalid numeric cohort: ${cohortValue}`);\n\tconst { offset, inverseMultiplier } = getRolloutShuffleParameters(bundleId);\n\treturn positiveMod(inverseMultiplier * (cohortValue - 1 - offset), NUMERIC_COHORT_SIZE);\n}\nfunction getRolledOutNumericCohorts(bundleId, rolloutCohortCount) {\n\tconst normalizedRolloutCount = normalizeRolloutCohortCount(rolloutCohortCount);\n\tif (normalizedRolloutCount <= 0) return [];\n\tif (normalizedRolloutCount >= 1e3) return Array.from({ length: NUMERIC_COHORT_SIZE }, (_, index) => index + 1);\n\tconst { multiplier, offset } = getRolloutShuffleParameters(bundleId);\n\treturn Array.from({ length: normalizedRolloutCount }, (_, position) => positiveMod(multiplier * position + offset, NUMERIC_COHORT_SIZE)).map((zeroBasedCohort) => zeroBasedCohort + 1).sort((left, right) => left - right);\n}\nfunction isCohortEligibleForUpdate(bundleId, cohort, rolloutCohortCount, targetCohorts) {\n\tconst normalizedCohort = cohort === null || cohort === void 0 ? void 0 : normalizeCohortValue(cohort);\n\tconst normalizedTargetCohorts = targetCohorts?.map((targetCohort) => normalizeCohortValue(targetCohort)) ?? [];\n\tif (normalizedCohort !== void 0 && normalizedTargetCohorts.includes(normalizedCohort)) return true;\n\tconst normalizedRolloutCount = normalizeRolloutCohortCount(rolloutCohortCount);\n\tif (normalizedRolloutCount <= 0) return false;\n\tif (normalizedCohort === void 0) return normalizedRolloutCount >= NUMERIC_COHORT_SIZE;\n\tconst numericCohort = getNumericCohortValue(normalizedCohort);\n\tif (numericCohort === null) return false;\n\tif (normalizedRolloutCount >= 1e3) return true;\n\treturn getNumericCohortRolloutPosition(bundleId, numericCohort) < normalizedRolloutCount;\n}\n//#endregion\n//#region src/releaseCatalog.ts\nconst RELEASE_CATALOG_SCHEMA_VERSION = 1;\nconst RELEASE_CATALOG_FALLBACK_POLICY = \"BUILTIN_IF_ACTIVE_INELIGIBLE\";\nconst MAX_CRASHED_BUNDLES = 10;\nconst MAX_TARGET_COHORTS_PER_RELEASE = 100;\nconst MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE = 512;\nconst MAX_COMPILED_CATALOG_BYTES = 262144;\nconst hashSelectionContext = (value) => {\n\tlet first = 2166136261;\n\tlet second = 2654435769;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst code = value.charCodeAt(index);\n\t\tfirst = Math.imul(first ^ code, 16777619);\n\t\tsecond = Math.imul(second ^ code, 2246822507);\n\t}\n\treturn `v1:${(first >>> 0).toString(16).padStart(8, \"0\")}${(second >>> 0).toString(16).padStart(8, \"0\")}`;\n};\nfunction createReleaseSelectionContextHash(input) {\n\tconst crashedBundleIds = [...new Set(input.crashedBundleIds)].sort().slice(0, 10);\n\tconst canonical = JSON.stringify({\n\t\tactiveBundleId: input.activeBundleId ?? null,\n\t\tactiveReleaseId: input.activeReleaseId ?? null,\n\t\tcohort: normalizeCohortValue(input.cohort ?? \"\"),\n\t\tcrashedBundleIds,\n\t\tminimumReleaseId: input.minimumReleaseId,\n\t\tselectorSchemaVersion: 1,\n\t\tstrategy: input.strategy,\n\t\tstrategyValue: input.strategyValue\n\t});\n\treturn hashSelectionContext(canonical);\n}\nfunction isReleaseEligibleForCohort(release, cohort) {\n\tif (isCohortEligibleForUpdate(release.releaseId, cohort, release.rolloutCohortCount, release.targetCohorts)) return true;\n\treturn cohort !== null && cohort !== void 0 && isCustomCohort(normalizeCohortValue(cohort)) && normalizeRolloutCohortCount(release.rolloutCohortCount) === 1e3;\n}\nfunction selectDesiredRelease(catalog, input) {\n\tconst crashedBundleIds = new Set(input.crashedBundleIds);\n\tconst activeReleaseId = input.activeReleaseId ?? null;\n\tconst hasActiveBundle = input.currentBundleId !== input.builtInBundleId;\n\tconst isSafeBundleRelease = (release) => release.bundleId !== null && !crashedBundleIds.has(release.bundleId) && release.bundleId >= input.minimumReleaseId;\n\tconst runningReleaseId = input.runningReleaseId === void 0 ? activeReleaseId : input.runningReleaseId;\n\tconst isNewerThanRunning = (release) => runningReleaseId !== null ? release.releaseId > runningReleaseId : release.bundleId !== null && release.bundleId > input.currentBundleId;\n\tconst passesForcedRelease = (selected) => [selected, ...catalog.rollbackReleases].some((passed) => passed.shouldForceUpdate && passed.bundleId !== null && passed.bundleId >= input.minimumReleaseId && passed.bundleId !== input.currentBundleId && passed.releaseId <= selected.releaseId && isNewerThanRunning(passed) && isReleaseEligibleForCohort(passed, input.cohort));\n\tconst desiredBundle = (release, status) => ({\n\t\tbundleId: release.bundleId,\n\t\tkind: \"BUNDLE\",\n\t\trelease,\n\t\treleaseId: release.releaseId,\n\t\tshouldForceUpdate: status === \"ROLLBACK\" || passesForcedRelease(release),\n\t\tstatus\n\t});\n\tfor (const release of catalog.releases) {\n\t\tif (!isReleaseEligibleForCohort(release, input.cohort)) continue;\n\t\tif (activeReleaseId !== null && release.releaseId <= activeReleaseId || activeReleaseId === null && hasActiveBundle && (release.bundleId === null || release.bundleId <= input.currentBundleId)) continue;\n\t\tif (isSafeBundleRelease(release)) return desiredBundle(release, \"UPDATE\");\n\t}\n\tif (activeReleaseId !== null || hasActiveBundle) {\n\t\tconst { rollbackReleases } = catalog;\n\t\tconst current = rollbackReleases.find((release) => release.releaseId === activeReleaseId || activeReleaseId === null && release.bundleId === input.currentBundleId);\n\t\tif (current !== void 0 && isSafeBundleRelease(current) && isReleaseEligibleForCohort(current, input.cohort)) return desiredBundle(current, \"UPDATE\");\n\t\tconst rollback = rollbackReleases.find((release) => isSafeBundleRelease(release) && (activeReleaseId !== null ? release.releaseId < activeReleaseId : release.bundleId < input.currentBundleId));\n\t\tif (rollback !== void 0 && isSafeBundleRelease(rollback)) return desiredBundle(rollback, \"ROLLBACK\");\n\t\tif (input.currentBundleId <= input.minimumReleaseId) return null;\n\t}\n\tif (catalog.fallbackPolicy !== \"BUILTIN_IF_ACTIVE_INELIGIBLE\") return null;\n\treturn {\n\t\tbundleId: input.builtInBundleId,\n\t\tkind: \"BUILTIN\",\n\t\trelease: null,\n\t\treleaseId: null,\n\t\tshouldForceUpdate: true,\n\t\tstatus: \"ROLLBACK\"\n\t};\n}\nfunction assessCatalogAcceptance(incoming, highestSeen) {\n\tif (highestSeen === null) return {\n\t\taccepted: true,\n\t\tshouldAdvanceHighWater: true\n\t};\n\tif (incoming.generation < highestSeen.generation) return {\n\t\taccepted: false,\n\t\treason: \"STALE_GENERATION\"\n\t};\n\tif (incoming.generation === highestSeen.generation && incoming.catalogHash !== highestSeen.catalogHash) return {\n\t\taccepted: false,\n\t\treason: \"GENERATION_HASH_MISMATCH\"\n\t};\n\treturn {\n\t\taccepted: true,\n\t\tshouldAdvanceHighWater: incoming.generation > highestSeen.generation\n\t};\n}\nfunction authorizeReleaseTransition(input) {\n\tconst { active, desired, explicitScopeSwitch } = input;\n\tif (active === null || active.scopeKey === null || active.generation === null) return {\n\t\tauthorized: true,\n\t\treason: \"FIRST_AUTHENTICATED_SELECTION\"\n\t};\n\tif (desired.catalogId !== active.catalogId || desired.scopeKey !== active.scopeKey) {\n\t\tif (!explicitScopeSwitch) return {\n\t\t\tauthorized: false,\n\t\t\treason: \"UNSOLICITED_SCOPE\"\n\t\t};\n\t\tif (desired.releaseId === null || desired.kind === \"BUILTIN\") return {\n\t\t\tauthorized: false,\n\t\t\treason: \"EMPTY_TARGET_SCOPE\"\n\t\t};\n\t\treturn {\n\t\t\tauthorized: true,\n\t\t\treason: \"EXPLICIT_SCOPE_SWITCH\"\n\t\t};\n\t}\n\tif (desired.generation === null || desired.generation < active.generation) return {\n\t\tauthorized: false,\n\t\treason: \"STALE_GENERATION\"\n\t};\n\tif (desired.generation > active.generation) return {\n\t\tauthorized: true,\n\t\treason: \"NEWER_POLICY\"\n\t};\n\tif (desired.selectionContextHash !== active.selectionContextHash) return {\n\t\tauthorized: true,\n\t\treason: \"CONTEXT_RESELECTION\"\n\t};\n\treturn {\n\t\tauthorized: false,\n\t\treason: \"BACKWARD_NOT_AUTHORIZED\"\n\t};\n}\n//#endregion\n//#region src/releaseCatalogScope.ts\nconst BASE64URL_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\nconst MAX_CATALOG_SEGMENT_LENGTH = 255;\nfunction assertCatalogSegment(value, name) {\n\tif (value.length === 0 || value.length > MAX_CATALOG_SEGMENT_LENGTH || !/^[A-Za-z0-9._~-]+$/.test(value)) throw new Error(`${name} must be 1-${MAX_CATALOG_SEGMENT_LENGTH} URL-safe ASCII characters`);\n}\nfunction encodeUtf8(value) {\n\tconst bytes = [];\n\tfor (const codePointText of value) {\n\t\tconst codePoint = codePointText.codePointAt(0);\n\t\tif (codePoint <= 127) bytes.push(codePoint);\n\t\telse if (codePoint <= 2047) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);\n\t\telse if (codePoint <= 65535) bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);\n\t\telse bytes.push(240 | codePoint >> 18, 128 | codePoint >> 12 & 63, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);\n\t}\n\treturn bytes;\n}\nfunction decodeUtf8(bytes) {\n\tlet result = \"\";\n\tfor (let index = 0; index < bytes.length;) {\n\t\tconst first = bytes[index++];\n\t\tlet codePoint;\n\t\tlet continuationCount;\n\t\tif (first <= 127) {\n\t\t\tcodePoint = first;\n\t\t\tcontinuationCount = 0;\n\t\t} else if ((first & 224) === 192) {\n\t\t\tcodePoint = first & 31;\n\t\t\tcontinuationCount = 1;\n\t\t} else if ((first & 240) === 224) {\n\t\t\tcodePoint = first & 15;\n\t\t\tcontinuationCount = 2;\n\t\t} else if ((first & 248) === 240) {\n\t\t\tcodePoint = first & 7;\n\t\t\tcontinuationCount = 3;\n\t\t} else throw new Error(\"Invalid UTF-8 channel key\");\n\t\tfor (let offset = 0; offset < continuationCount; offset += 1) {\n\t\t\tconst continuation = bytes[index++];\n\t\t\tif (continuation === void 0 || (continuation & 192) !== 128) throw new Error(\"Invalid UTF-8 channel key\");\n\t\t\tcodePoint = codePoint << 6 | continuation & 63;\n\t\t}\n\t\tif (codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343 || continuationCount === 1 && codePoint < 128 || continuationCount === 2 && codePoint < 2048 || continuationCount === 3 && codePoint < 65536) throw new Error(\"Invalid UTF-8 channel key\");\n\t\tresult += String.fromCodePoint(codePoint);\n\t}\n\treturn result;\n}\nfunction base64UrlEncode(bytes) {\n\tlet result = \"\";\n\tfor (let index = 0; index < bytes.length; index += 3) {\n\t\tconst first = bytes[index];\n\t\tconst second = bytes[index + 1];\n\t\tconst third = bytes[index + 2];\n\t\tconst value = first << 16 | (second ?? 0) << 8 | (third ?? 0);\n\t\tresult += BASE64URL_ALPHABET[value >> 18 & 63];\n\t\tresult += BASE64URL_ALPHABET[value >> 12 & 63];\n\t\tif (second !== void 0) result += BASE64URL_ALPHABET[value >> 6 & 63];\n\t\tif (third !== void 0) result += BASE64URL_ALPHABET[value & 63];\n\t}\n\treturn result;\n}\nfunction base64UrlDecode(value) {\n\tif (!/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1) throw new Error(\"Invalid channel key\");\n\tconst bytes = [];\n\tfor (let index = 0; index < value.length; index += 4) {\n\t\tconst chunk = value.slice(index, index + 4);\n\t\tconst encoded = [...chunk].map((character) => BASE64URL_ALPHABET.indexOf(character));\n\t\tif (encoded.some((part) => part < 0)) throw new Error(\"Invalid channel key\");\n\t\tconst bits = encoded[0] << 18 | encoded[1] << 12 | (encoded[2] ?? 0) << 6 | (encoded[3] ?? 0);\n\t\tbytes.push(bits >> 16 & 255);\n\t\tif (chunk.length >= 3) bytes.push(bits >> 8 & 255);\n\t\tif (chunk.length === 4) bytes.push(bits & 255);\n\t}\n\treturn bytes;\n}\nfunction normalizeChannelName(channel) {\n\treturn channel.trim().normalize(\"NFC\");\n}\nfunction assertCanonicalChannelName(channel) {\n\tconst normalized = normalizeChannelName(channel);\n\tif (normalized.length === 0 || normalized !== channel) throw new Error(\"Channel name must be non-empty, trimmed, and NFC-normalized\");\n\tlet codePointCount = 0;\n\tfor (const _codePoint of normalized) {\n\t\tcodePointCount += 1;\n\t\tif (codePointCount > 255) throw new Error(\"Channel name must not exceed 255 characters\");\n\t}\n}\nfunction encodeChannelKey(channel) {\n\tassertCanonicalChannelName(channel);\n\treturn base64UrlEncode(encodeUtf8(channel));\n}\nfunction decodeChannelKey(channelKey) {\n\tconst channel = decodeUtf8(base64UrlDecode(channelKey));\n\tassertCanonicalChannelName(channel);\n\tif (encodeChannelKey(channel) !== channelKey) throw new Error(\"Channel key is not canonically encoded\");\n\treturn channel;\n}\nfunction createReleaseCatalogScopeKey(input) {\n\tdecodeChannelKey(input.channelKey);\n\tif (input.strategy === \"APP_VERSION\") return `v1:app-version:${input.platform}:${input.channelKey}`;\n\tassertCatalogSegment(input.fingerprintHash, \"Fingerprint hash\");\n\treturn `v1:fingerprint:${input.platform}:${input.channelKey}:${input.fingerprintHash}`;\n}\nfunction parseReleaseCatalogScopeKey(scopeKey) {\n\tconst segments = scopeKey.split(\":\");\n\tconst [version, strategy, platform, channelKey] = segments;\n\tif (version !== \"v1\" || platform !== \"ios\" && platform !== \"android\" || channelKey === void 0) throw new Error(\"Invalid release catalog scope key\");\n\tconst input = strategy === \"app-version\" && segments.length === 4 ? {\n\t\tchannelKey,\n\t\tplatform,\n\t\tstrategy: \"APP_VERSION\"\n\t} : strategy === \"fingerprint\" && segments.length === 5 && segments[4] !== void 0 ? {\n\t\tchannelKey,\n\t\tfingerprintHash: segments[4],\n\t\tplatform,\n\t\tstrategy: \"FINGERPRINT\"\n\t} : (() => {\n\t\tthrow new Error(\"Invalid release catalog scope key\");\n\t})();\n\tif (createReleaseCatalogScopeKey(input) !== scopeKey) throw new Error(\"Release catalog scope key is not canonical\");\n\treturn input;\n}\n//#endregion\n//#region src/uuid.ts\nconst NIL_UUID = \"00000000-0000-0000-0000-000000000000\";\nconst UUID_V7_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst isUUIDv7 = (value) => typeof value === \"string\" && UUID_V7_PATTERN.test(value);\n//#endregion\n//#region src/releaseCatalogWire.ts\n/** The largest release catalog response body a client accepts, in UTF-8 bytes. */\nconst MAX_RELEASE_CATALOG_WIRE_BYTES = 528384;\n/** The length of `value` in UTF-8 bytes, without an encoder the device may lack. */\nconst getUtf8ByteLength = (value) => {\n\tlet bytes = 0;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst code = value.charCodeAt(index);\n\t\tif (code <= 127) bytes += 1;\n\t\telse if (code <= 2047) bytes += 2;\n\t\telse if (code >= 55296 && code <= 56319 && index + 1 < value.length && value.charCodeAt(index + 1) >= 56320 && value.charCodeAt(index + 1) <= 57343) {\n\t\t\tbytes += 4;\n\t\t\tindex += 1;\n\t\t} else bytes += 3;\n\t}\n\treturn bytes;\n};\nconst isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\nconst isValidReleaseDescriptor = (value) => {\n\tif (value === null || typeof value !== \"object\") return false;\n\tconst descriptor = value;\n\treturn isUUIDv7(descriptor.releaseId) && descriptor.kind === \"BUNDLE\" && typeof descriptor.bundleId === \"string\" && Number.isSafeInteger(descriptor.rolloutCohortCount) && descriptor.rolloutCohortCount >= 0 && descriptor.rolloutCohortCount <= 1e3 && isStringArray(descriptor.targetCohorts) && descriptor.targetCohorts.length <= 100 && typeof descriptor.shouldForceUpdate === \"boolean\" && (descriptor.message === null || typeof descriptor.message === \"string\");\n};\n/** Whether the catalog is the expected scope's. */\nconst hasExpectedReleaseCatalogScope = (catalog, expected) => {\n\ttry {\n\t\tconst parsed = parseReleaseCatalogScopeKey(catalog.scopeKey);\n\t\treturn parsed.channelKey === expected.channelKey && parsed.platform === expected.platform && parsed.strategy === expected.strategy && (parsed.strategy === \"APP_VERSION\" || expected.strategy === \"FINGERPRINT\" && parsed.fingerprintHash === expected.fingerprintHash);\n\t} catch {\n\t\treturn false;\n\t}\n};\n/**\n* Parses a release catalog response body as a client accepts it: within the\n* wire limit, in the schema's shape, for the expected scope, and within the\n* cohort limits. Any other body is null. The device's update client and\n* doctor's server checks both run this, so they accept the same catalogs.\n*/\nconst parseReleaseCatalog = (body, expectedScope) => {\n\tif (getUtf8ByteLength(body) > MAX_RELEASE_CATALOG_WIRE_BYTES) return null;\n\ttry {\n\t\tconst catalog = JSON.parse(body);\n\t\tif (catalog.schemaVersion !== 1 || typeof catalog.catalogId !== \"string\" || catalog.catalogId.length === 0 || typeof catalog.scopeKey !== \"string\" || !Number.isSafeInteger(catalog.generation) || (catalog.generation ?? 0) < 1 || typeof catalog.catalogHash !== \"string\" || !/^sha256:[0-9a-f]{64}$/.test(catalog.catalogHash) || catalog.fallbackPolicy !== \"BUILTIN_IF_ACTIVE_INELIGIBLE\" || !Array.isArray(catalog.releases) || !catalog.releases.every(isValidReleaseDescriptor) || !Array.isArray(catalog.rollbackReleases) || !catalog.rollbackReleases.every(isValidReleaseDescriptor)) return null;\n\t\tif (!hasExpectedReleaseCatalogScope(catalog, expectedScope)) return null;\n\t\tif (new Set([...catalog.releases, ...catalog.rollbackReleases].flatMap((release) => release.targetCohorts)).size > 512) return null;\n\t\treturn catalog;\n\t} catch {\n\t\treturn null;\n\t}\n};\n//#endregion\n//#region src/types.ts\nconst ARTIFACT_PROTOCOL_VERSION = 1;\n//#endregion\nexport { ARTIFACT_PROTOCOL_VERSION, DEFAULT_ROLLOUT_COHORT_COUNT, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, MAX_COMPILED_CATALOG_BYTES, MAX_CRASHED_BUNDLES, MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE, MAX_RELEASE_CATALOG_WIRE_BYTES, MAX_TARGET_COHORTS_PER_RELEASE, NIL_UUID, NUMERIC_COHORT_SIZE, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, assertCanonicalChannelName, assessCatalogAcceptance, authorizeReleaseTransition, canonicalizeAppVersion, createPluginHost, createReleaseCatalogScopeKey, createReleaseSelectionContextHash, decodeChannelKey, defineClientPlugin, encodeChannelKey, getAssetBaseStorageUri, getBundlePatch, getBundlePatches, getDefaultNumericCohort, getManifestFileHash, getManifestStorageUri, getNumericCohortRolloutPosition, getNumericCohortValue, getPatchBaseBundleId, getPatchBaseFileHash, getPatchFileHash, getPatchStorageUri, getRolledOutNumericCohorts, getUtf8ByteLength, hasExpectedReleaseCatalogScope, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isReleaseEligibleForCohort, isUUIDv7, isValidCohort, normalizeChannelName, normalizeCohortValue, normalizeRolloutCohortCount, parseReleaseCatalog, parseReleaseCatalogScopeKey, pluginStorageKey, resolveBaseURL, selectDesiredRelease };\n", "import { bundleMetadataToRow } from \"./databaseMetadata.mjs\";\nimport { getAssetBaseStorageUri, getBundlePatches, getManifestFileHash, getManifestStorageUri } from \"@hot-updater/protocol\";\n//#region src/databaseRows.ts\nconst releaseToRow = (release, scopeKey) => ({\n\tid: release.id,\n\trevision: release.revision,\n\tscope_key: scopeKey,\n\tchannel_id: release.channelId,\n\tplatform: release.platform,\n\tkind: release.kind,\n\tbundle_id: release.bundleId,\n\tstrategy: release.strategy,\n\ttarget_app_version: release.targetAppVersion,\n\tfingerprint_hash: release.fingerprintHash,\n\tenabled: release.enabled,\n\tshould_force_update: release.shouldForceUpdate,\n\tmessage: release.message,\n\trollout_cohort_count: release.rolloutCohortCount,\n\ttarget_cohorts: release.targetCohorts,\n\toperation: release.operation,\n\tsource_release_id: release.sourceReleaseId,\n\tcreated_at_ms: release.createdAtMs,\n\tupdated_at_ms: release.updatedAtMs\n});\nconst releaseRowToRelease = (row) => ({\n\tid: row.id,\n\trevision: row.revision,\n\tchannelId: row.channel_id,\n\tplatform: row.platform,\n\tkind: row.kind,\n\tbundleId: row.bundle_id,\n\tstrategy: row.strategy,\n\ttargetAppVersion: row.target_app_version,\n\tfingerprintHash: row.fingerprint_hash,\n\tenabled: row.enabled,\n\tshouldForceUpdate: row.should_force_update,\n\tmessage: row.message,\n\trolloutCohortCount: row.rollout_cohort_count,\n\ttargetCohorts: row.target_cohorts,\n\toperation: row.operation,\n\tsourceReleaseId: row.source_release_id,\n\tcreatedAtMs: row.created_at_ms,\n\tupdatedAtMs: row.updated_at_ms\n});\nconst BundleRowHydrationErrorReason = {\n\tduplicatePatchId: \"duplicate_patch_id\",\n\torphanPatchOwner: \"orphan_patch_owner\",\n\torphanPatchBase: \"orphan_patch_base\"\n};\nvar BundleRowHydrationError = class extends Error {\n\tname = \"BundleRowHydrationError\";\n\treason;\n\tpatchId;\n\tbundleId;\n\tconstructor({ reason, patchId, bundleId }) {\n\t\tsuper(`Cannot hydrate bundle rows: ${reason} for patch \"${patchId}\" and bundle \"${bundleId}\".`);\n\t\tthis.reason = reason;\n\t\tthis.patchId = patchId;\n\t\tthis.bundleId = bundleId;\n\t}\n};\nconst bundleToRow = (bundle) => {\n\tconst metadata = bundleMetadataToRow(bundle.metadata);\n\treturn {\n\t\tid: bundle.id,\n\t\tplatform: bundle.platform,\n\t\tgit_commit_hash: bundle.gitCommitHash,\n\t\tmetadata,\n\t\tmanifest_storage_uri: getManifestStorageUri(bundle),\n\t\tmanifest_file_hash: getManifestFileHash(bundle),\n\t\tasset_base_storage_uri: getAssetBaseStorageUri(bundle)\n\t};\n};\nconst bundleToPatchRows = (bundle) => getBundlePatches(bundle).map((patch, orderIndex) => ({\n\tid: `${bundle.id}:${patch.baseBundleId}`,\n\tbundle_id: bundle.id,\n\tbase_bundle_id: patch.baseBundleId,\n\tbase_file_hash: patch.baseFileHash,\n\tpatch_file_hash: patch.patchFileHash,\n\tpatch_storage_uri: patch.patchStorageUri,\n\tbyte_size: patch.byteSize,\n\torder_index: orderIndex\n}));\nconst comparePatchRows = (left, right) => left.order_index - right.order_index || left.id.localeCompare(right.id);\nconst patchRowToArtifact = (row) => ({\n\tbaseBundleId: row.base_bundle_id,\n\tbaseFileHash: row.base_file_hash,\n\tbyteSize: row.byte_size,\n\tpatchFileHash: row.patch_file_hash,\n\tpatchStorageUri: row.patch_storage_uri\n});\nconst rowToBundle = (row, patchRows = []) => {\n\tconst patches = patchRows.slice().sort(comparePatchRows).map(patchRowToArtifact);\n\treturn {\n\t\tid: row.id,\n\t\tplatform: row.platform,\n\t\tgitCommitHash: row.git_commit_hash,\n\t\tmetadata: row.metadata,\n\t\tmanifestStorageUri: row.manifest_storage_uri,\n\t\tmanifestFileHash: row.manifest_file_hash,\n\t\tassetBaseStorageUri: row.asset_base_storage_uri,\n\t\tpatches\n\t};\n};\nconst rowsToBundles = (bundleRows, patchRows, referencedBundleRows) => {\n\tconst ownerIds = new Set(bundleRows.map(({ id }) => id));\n\tconst baseIds = new Set(ownerIds);\n\tfor (const row of referencedBundleRows) baseIds.add(row.id);\n\tconst patchIds = /* @__PURE__ */ new Set();\n\tconst patchesByOwner = /* @__PURE__ */ new Map();\n\tfor (const patch of patchRows) {\n\t\tif (patchIds.has(patch.id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.duplicatePatchId,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.bundle_id\n\t\t});\n\t\tpatchIds.add(patch.id);\n\t\tif (!ownerIds.has(patch.bundle_id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.orphanPatchOwner,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.bundle_id\n\t\t});\n\t\tif (!baseIds.has(patch.base_bundle_id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.orphanPatchBase,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.base_bundle_id\n\t\t});\n\t\tconst ownerPatches = patchesByOwner.get(patch.bundle_id) ?? [];\n\t\townerPatches.push(patch);\n\t\tpatchesByOwner.set(patch.bundle_id, ownerPatches);\n\t}\n\treturn bundleRows.map((row) => rowToBundle(row, patchesByOwner.get(row.id) ?? []));\n};\n//#endregion\nexport { BundleRowHydrationError, BundleRowHydrationErrorReason, bundleToPatchRows, bundleToRow, releaseRowToRelease, releaseToRow, rowToBundle, rowsToBundles };\n", "import { isUUIDv7, isUUIDv7 as isUUIDv7$1 } from \"@hot-updater/protocol\";\n//#region src/uuidv7.ts\nconst extractTimestampFromUUIDv7 = (uuid) => {\n\tif (!isUUIDv7(uuid)) throw new TypeError(\"Expected a canonical lowercase UUIDv7\");\n\tconst timestampHex = uuid.split(\"-\").join(\"\").slice(0, 12);\n\treturn Number.parseInt(timestampHex, 16);\n};\nfunction createUUIDv7FromTimestampHex(timestampHex) {\n\tconst randomBytes = /* @__PURE__ */ new Uint8Array(10);\n\tcrypto.getRandomValues(randomBytes);\n\tconst randomHex = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\tconst randA = randomHex.slice(0, 3);\n\tconst randBHex = randomHex.slice(3, 19);\n\tconst versionAndRandA = `7${randA}`;\n\tconst variantAndFirstRandB = (128 | parseInt(randBHex.slice(0, 2), 16) & 63).toString(16).padStart(2, \"0\");\n\treturn [\n\t\ttimestampHex.slice(0, 8),\n\t\ttimestampHex.slice(8, 12),\n\t\tversionAndRandA,\n\t\tvariantAndFirstRandB + randBHex.slice(2, 4),\n\t\trandBHex.slice(4, 16)\n\t].join(\"-\");\n}\nconst createUUIDv7 = () => createUUIDv7FromTimestampHex(Date.now().toString(16).padStart(12, \"0\"));\nconst createUUIDv7After = (floor, nowMs = Date.now()) => {\n\tconst timestamp = Math.max(nowMs, floor === null ? 0 : extractTimestampFromUUIDv7(floor) + 1);\n\tif (!Number.isSafeInteger(timestamp) || timestamp < 0 || timestamp >= 2 ** 48) throw new RangeError(\"UUIDv7 timestamp is out of range\");\n\treturn createUUIDv7FromTimestampHex(timestamp.toString(16).padStart(12, \"0\"));\n};\nconst createUUIDv7WithSameTimestamp = (originalUuid) => {\n\treturn createUUIDv7FromTimestampHex(originalUuid.split(\"-\").join(\"\").slice(0, 12));\n};\n//#endregion\nexport { createUUIDv7, createUUIDv7After, createUUIDv7WithSameTimestamp, extractTimestampFromUUIDv7, isUUIDv7$1 as isUUIDv7 };\n", "//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst GREATER_LESS_THAN = \"((?:<|>)?=?)\";\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nconst XRANGE_PLAIN = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nconst XRANGE_PLAIN_LOOSE = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nconst LONE_TILDE = \"(?:~>?)\";\nconst LONE_CARET = String.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nconst NUMERIC = /^\\d+$/;\nfunction compareIdentifiers(left, right) {\n\tif (typeof left === \"number\" && typeof right === \"number\") return left === right ? 0 : left < right ? -1 : 1;\n\tconst leftNumeric = NUMERIC.test(String(left));\n\tconst rightNumeric = NUMERIC.test(String(right));\n\tconst normalizedLeft = leftNumeric ? Number(left) : left;\n\tconst normalizedRight = rightNumeric ? Number(right) : right;\n\treturn normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;\n}\nfunction compareMainParsed(left, right) {\n\treturn left.major === right.major ? left.minor === right.minor ? left.patch === right.patch ? 0 : left.patch < right.patch ? -1 : 1 : left.minor < right.minor ? -1 : 1 : left.major < right.major ? -1 : 1;\n}\nfunction comparePrereleaseParsed(left, right) {\n\tconst leftPrerelease = left.prerelease;\n\tconst rightPrerelease = right.prerelease;\n\tif (leftPrerelease?.length && !rightPrerelease?.length) return -1;\n\tif (!leftPrerelease?.length && rightPrerelease?.length) return 1;\n\tif (!leftPrerelease?.length && !rightPrerelease?.length) return 0;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = leftPrerelease?.[index];\n\t\tconst rightIdentifier = rightPrerelease?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compareParsed(left, right) {\n\treturn compareMainParsed(left, right) || comparePrereleaseParsed(left, right);\n}\nfunction compare(left, right, options = {}) {\n\treturn compareParsed(parse(left, options), parse(right, options));\n}\n//#endregion\nexport { LOOSE_PLAIN as A, BUILD as C, GREATER_LESS_THAN as D, FULL_PLAIN as E, safeRegex as F, PRERELEASE_LOOSE as M, XRANGE_PLAIN as N, LONE_CARET as O, XRANGE_PLAIN_LOOSE as P, tryParse as S, COERCE_FULL as T, compareIdentifiers as _, compareParsed as a, compareMainParsed as i, PRERELEASE as j, LONE_TILDE as k, compare as t, COERCE as w, parse as x, formatComparableVersion as y };\n", "import { A as LOOSE_PLAIN, D as GREATER_LESS_THAN, E as FULL_PLAIN, F as safeRegex, a as compareParsed, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.js\nconst STRICT_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${FULL_PLAIN})$|^$`);\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction formatComparator(comparator) {\n\treturn comparator.version ? `${comparator.operator}${formatComparableVersion(comparator.version)}` : \"\";\n}\nfunction parseComparator(comparator, options = {}) {\n\tif (typeof comparator !== \"string\") return comparator;\n\tconst normalized = comparator.trim().replaceAll(/\\s+/g, \" \");\n\tconst match = normalized.match(options.loose ? LOOSE_COMPARATOR : STRICT_COMPARATOR);\n\tif (!match) throw new TypeError(`Invalid comparator: ${normalized}`);\n\tconst operator = match[1] === \"=\" ? \"\" : match[1] || \"\";\n\tconst version = match[2] ? parse(match[2], options) : null;\n\treturn {\n\t\toperator,\n\t\toptions,\n\t\tvalue: version ? `${operator}${formatComparableVersion(version)}` : \"\",\n\t\tversion\n\t};\n}\nfunction testParsedComparator(comparator, version) {\n\tif (!comparator.version) return true;\n\tconst comparison = compareParsed(version, comparator.version);\n\tswitch (comparator.operator) {\n\t\tcase \"\": return comparison === 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t}\n}\nfunction comparatorAllowsPrerelease(comparator, version) {\n\tconst allowed = comparator.version;\n\treturn allowed !== null && !!allowed.prerelease?.length && allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch;\n}\nfunction testComparatorSet(set, version, options) {\n\tif (set.some((comparator) => !testParsedComparator(comparator, version))) return false;\n\treturn !version.prerelease?.length || !!options.includePrerelease || set.some((comparator) => comparatorAllowsPrerelease(comparator, version));\n}\n//#endregion\nexport { testParsedComparator as a, formatComparator as o, testComparatorSet as r, parseComparator as s, comparatorAllowsPrerelease as t };\n", "import { A as LOOSE_PLAIN, C as BUILD, D as GREATER_LESS_THAN, F as safeRegex, N as XRANGE_PLAIN, O as LONE_CARET, P as XRANGE_PLAIN_LOOSE, S as tryParse, k as LONE_TILDE } from \"./comparison-DenM3wCn.mjs\";\nimport { o as formatComparator, r as testComparatorSet, s as parseComparator } from \"./set-CC5YeoYX.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.js\nfunction formatRange(range) {\n\treturn range.sets.map((set) => set.map(formatComparator).join(\" \")).join(\"||\");\n}\nconst BUILD_STRIP = new RegExp(BUILD, \"g\");\nconst BUILD_SAFE = safeRegex(BUILD);\nconst STRICT_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN})\\s+-\\s+(${XRANGE_PLAIN})\\s*$`);\nconst LOOSE_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN_LOOSE})\\s+-\\s+(${XRANGE_PLAIN_LOOSE})\\s*$`);\nconst COMPARATOR_TRIM = safeRegex(String.raw`(\\s*)${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN}|${XRANGE_PLAIN})`, \"g\");\nconst TILDE_TRIM = safeRegex(String.raw`(\\s*)${LONE_TILDE}\\s+`, \"g\");\nconst CARET_TRIM = safeRegex(String.raw`(\\s*)${LONE_CARET}\\s+`, \"g\");\nconst STRICT_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN}$`);\nconst LOOSE_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN}$`);\nconst LOOSE_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN}$`);\nconst LOOSE_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN_LOOSE}$`);\nconst STAR = safeRegex(String.raw`(<|>)?=?\\s*\\*`);\nconst GTE_ZERO = /^\\s*>=\\s*0\\.0\\.0\\s*$/;\nconst GTE_ZERO_PRERELEASE = /^\\s*>=\\s*0\\.0\\.0-0\\s*$/;\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction isWildcard(value) {\n\treturn !value || String(value).toLowerCase() === \"x\" || String(value) === \"*\";\n}\nfunction hasInvalidWildcardOrder(major, minor, patch) {\n\treturn isWildcard(major) && !isWildcard(minor) || isWildcard(minor) && Boolean(patch) && !isWildcard(patch);\n}\nfunction replaceTilde(comparator, options) {\n\tconst expression = options.loose ? LOOSE_TILDE : STRICT_TILDE;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn prerelease ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;\n\t});\n}\nfunction replaceTildes(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceTilde(part, options)).join(\" \");\n}\nfunction replaceCaret(comparator, options) {\n\tconst expression = options.loose ? LOOSE_CARET : STRICT_CARET;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return major === \"0\" ? `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (prerelease) return major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch}-${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\treturn major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;\n\t});\n}\nfunction replaceCarets(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceCaret(part, options)).join(\" \");\n}\nfunction replaceXRange(comparator, options) {\n\tconst expression = options.loose ? LOOSE_XRANGE : STRICT_XRANGE;\n\treturn comparator.trim().replace(expression, (match, rawOperator, rawMajor, rawMinor, rawPatch) => {\n\t\tlet operator = rawOperator;\n\t\tlet major = rawMajor;\n\t\tlet minor = rawMinor;\n\t\tlet patch = rawPatch;\n\t\tif (hasInvalidWildcardOrder(String(major), minor === void 0 ? void 0 : String(minor), patch === void 0 ? void 0 : String(patch))) return comparator;\n\t\tconst wildcardMajor = isWildcard(major);\n\t\tconst wildcardMinor = wildcardMajor || isWildcard(minor);\n\t\tconst wildcardPatch = wildcardMinor || isWildcard(patch);\n\t\tif (operator === \"=\" && wildcardPatch) operator = \"\";\n\t\tif (wildcardMajor) return operator === \">\" || operator === \"<\" ? \"<0.0.0-0\" : \"*\";\n\t\tlet prerelease = options.includePrerelease ? \"-0\" : \"\";\n\t\tif (operator && wildcardPatch) {\n\t\t\tif (wildcardMinor) minor = 0;\n\t\t\tpatch = 0;\n\t\t\tif (operator === \">\") {\n\t\t\t\toperator = \">=\";\n\t\t\t\tif (wildcardMinor) {\n\t\t\t\t\tmajor = Number(major) + 1;\n\t\t\t\t\tminor = 0;\n\t\t\t\t} else minor = Number(minor) + 1;\n\t\t\t} else if (operator === \"<=\") {\n\t\t\t\toperator = \"<\";\n\t\t\t\tif (wildcardMinor) major = Number(major) + 1;\n\t\t\t\telse minor = Number(minor) + 1;\n\t\t\t}\n\t\t\tif (operator === \"<\") prerelease = \"-0\";\n\t\t\treturn `${operator}${major}.${minor}.${patch}${prerelease}`;\n\t\t}\n\t\tif (wildcardMinor) return `>=${major}.0.0${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (wildcardPatch) return `>=${major}.${minor}.0${prerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn match;\n\t});\n}\nfunction replaceXRanges(comparator, options) {\n\treturn comparator.split(/\\s+/).map((part) => replaceXRange(part, options)).join(\" \");\n}\nfunction replaceHyphenRange(range, options) {\n\tconst expression = options.loose ? LOOSE_HYPHEN : STRICT_HYPHEN;\n\treturn range.replace(expression, (_match, rawFrom, fromMajor, fromMinor, fromPatch, fromPrerelease, _fromBuild, rawTo, toMajor, toMinor, toPatch, toPrerelease) => {\n\t\tlet from = rawFrom;\n\t\tlet to = rawTo;\n\t\tif (isWildcard(fromMajor)) from = \"\";\n\t\telse if (isWildcard(fromMinor)) from = `>=${fromMajor}.0.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (isWildcard(fromPatch)) from = `>=${fromMajor}.${fromMinor}.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (fromPrerelease) from = `>=${from}`;\n\t\telse from = `>=${from}${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\tif (isWildcard(toMajor)) to = \"\";\n\t\telse if (isWildcard(toMinor)) to = `<${Number(toMajor) + 1}.0.0-0`;\n\t\telse if (isWildcard(toPatch)) to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;\n\t\telse if (toPrerelease) to = `<=${toMajor}.${toMinor}.${toPatch}-${toPrerelease}`;\n\t\telse if (options.includePrerelease) to = `<${toMajor}.${toMinor}.${Number(toPatch) + 1}-0`;\n\t\telse to = `<=${to}`;\n\t\treturn `${from} ${to}`.trim();\n\t});\n}\nfunction expandComparator(comparator, options) {\n\treturn replaceXRanges(replaceTildes(replaceCarets(comparator.replace(BUILD_SAFE, \"\"), options), options), options).trim().replace(STAR, \"\");\n}\nfunction parseSimpleRange(input, options) {\n\tlet parts = replaceHyphenRange(input.replace(BUILD_STRIP, \"\"), options).replace(COMPARATOR_TRIM, \"$1$2$3\").replace(TILDE_TRIM, \"$1~\").replace(CARET_TRIM, \"$1^\").split(\" \").map((part) => expandComparator(part, options)).join(\" \").split(/\\s+/).map((part) => part.trim().replace(options.includePrerelease ? GTE_ZERO_PRERELEASE : GTE_ZERO, \"\"));\n\tif (options.loose) parts = parts.filter((part) => LOOSE_COMPARATOR.test(part));\n\tconst unique = /* @__PURE__ */ new Map();\n\tfor (const comparator of parts.map((part) => parseComparator(part, options))) {\n\t\tif (comparator.value === \"<0.0.0-0\") return [comparator];\n\t\tunique.set(comparator.value, comparator);\n\t}\n\tif (unique.size > 1) unique.delete(\"\");\n\treturn [...unique.values()];\n}\nfunction parseRange(range, options = {}) {\n\tif (typeof range !== \"string\") return range;\n\tconst parsedOptions = { ...options };\n\tconst normalizedRange = range.trim().replaceAll(/\\s+/g, \" \");\n\tlet sets = normalizedRange.split(\"||\").map((part) => parseSimpleRange(part.trim(), parsedOptions)).filter((set) => set.length);\n\tif (!sets.length) throw new TypeError(`Range contains no valid comparator sets: ${normalizedRange}`);\n\tif (sets.length > 1) {\n\t\tconst first = sets[0];\n\t\tsets = sets.filter((set) => set[0]?.value !== \"<0.0.0-0\");\n\t\tif (!sets.length) sets = [first];\n\t\telse if (sets.length > 1) {\n\t\t\tconst any = sets.find((set) => set.length === 1 && set[0]?.value === \"\");\n\t\t\tif (any) sets = [any];\n\t\t}\n\t}\n\treturn {\n\t\toptions: parsedOptions,\n\t\tsets\n\t};\n}\nfunction tryParseRange(range, options = {}) {\n\ttry {\n\t\treturn parseRange(range, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nfunction testParsedRange(range, version) {\n\treturn range.sets.some((set) => testComparatorSet(set, version, range.options));\n}\nfunction testRangeVersion(range, version) {\n\tconst parsed = tryParse(version, range.options);\n\treturn parsed ? testParsedRange(range, parsed) : false;\n}\nfunction normalizeRange(range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? formatRange(parsed) || \"*\" : null;\n}\nfunction satisfies(version, range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? testRangeVersion(parsed, version) : false;\n}\n//#endregion\nexport { satisfies as f, tryParseRange as h, normalizeRange as l, parseRange as m };\n", "import { F as safeRegex, M as PRERELEASE_LOOSE, S as tryParse, T as COERCE_FULL, j as PRERELEASE, w as COERCE, y as formatComparableVersion } from \"./comparison-DenM3wCn.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.js\nconst COERCE_EXACT = safeRegex(COERCE);\nconst COERCE_FULL_EXACT = safeRegex(COERCE_FULL);\nsafeRegex(`^${PRERELEASE}$`);\nsafeRegex(`^${PRERELEASE_LOOSE}$`);\nfunction normalize(version, options = {}) {\n\tconst parsed = tryParse(version, options);\n\treturn parsed ? formatComparableVersion(parsed) : null;\n}\nfunction coerce(value, options = {}) {\n\tif (typeof value === \"object\") return value;\n\tconst input = typeof value === \"number\" ? String(value) : value;\n\tlet match = null;\n\tif (options.rtl) {\n\t\tconst source = options.includePrerelease ? COERCE_FULL : COERCE;\n\t\tconst expression = safeRegex(source, \"g\");\n\t\tlet next;\n\t\twhile ((next = expression.exec(input)) && (!match || match.index + match[0].length !== input.length)) {\n\t\t\tif (!match || next.index + next[0].length !== match.index + match[0].length) match = next;\n\t\t\texpression.lastIndex = next.index + next[1].length + next[2].length;\n\t\t}\n\t} else match = (options.includePrerelease ? COERCE_FULL_EXACT : COERCE_EXACT).exec(input);\n\tif (!match) return null;\n\tconst major = match[2];\n\tconst minor = match[3] || \"0\";\n\tconst patch = match[4] || \"0\";\n\tconst prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : \"\";\n\tconst build = options.includePrerelease && match[6] ? `+${match[6]}` : \"\";\n\treturn tryParse(`${major}.${minor}.${patch}${prerelease}${build}`, options);\n}\n//#endregion\nexport { coerce as n, normalize as p };\n", "import { t as compare } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs\";\nimport { f as satisfies, m as parseRange } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { p as normalize } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs\";\nimport { isUUIDv7 as isUUIDv7$1 } from \"./uuidv7.mjs\";\nimport { MAX_COMPILED_CATALOG_BYTES, MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE, MAX_TARGET_COHORTS_PER_RELEASE, NUMERIC_COHORT_SIZE, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, canonicalizeAppVersion, canonicalizeAppVersion as canonicalizeAppVersion$1, getNumericCohortValue, getRolledOutNumericCohorts, isCustomCohort, normalizeCohortValue, normalizeRolloutCohortCount } from \"@hot-updater/protocol\";\n//#region src/releaseCatalogCompiler.ts\nvar ReleaseCatalogCompilationError = class extends Error {\n\tcode;\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.name = \"ReleaseCatalogCompilationError\";\n\t\tthis.code = code;\n\t}\n};\nfunction compareBounds(left, right) {\n\treturn compare(left, right);\n}\nfunction strongerLower(current, candidate) {\n\tif (current === null) return candidate;\n\tconst compared = compareBounds(candidate.version, current.version);\n\tif (compared > 0) return candidate;\n\tif (compared < 0) return current;\n\treturn {\n\t\tversion: current.version,\n\t\tinclusive: current.inclusive && candidate.inclusive\n\t};\n}\nfunction strongerUpper(current, candidate) {\n\tif (current === null) return candidate;\n\tconst compared = compareBounds(candidate.version, current.version);\n\tif (compared < 0) return candidate;\n\tif (compared > 0) return current;\n\treturn {\n\t\tversion: current.version,\n\t\tinclusive: current.inclusive && candidate.inclusive\n\t};\n}\nfunction comparatorVersion(comparator) {\n\tconst version = comparator.version && normalize(comparator.version);\n\tif (version === null) throw new ReleaseCatalogCompilationError(\"INVALID_TARGET_RANGE\", `Invalid comparator: ${comparator.value}`);\n\treturn version;\n}\nfunction comparatorSetToInterval(comparators) {\n\tlet lower = null;\n\tlet upper = null;\n\tfor (const comparator of comparators) {\n\t\tif (comparator.version === null) continue;\n\t\tconst version = comparatorVersion(comparator);\n\t\tif (comparator.operator === \"\") {\n\t\t\tlower = strongerLower(lower, {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion\n\t\t\t});\n\t\t\tupper = strongerUpper(upper, {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion\n\t\t\t});\n\t\t} else if (comparator.operator === \">\") lower = strongerLower(lower, {\n\t\t\tinclusive: false,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \">=\") lower = strongerLower(lower, {\n\t\t\tinclusive: true,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \"<\") upper = strongerUpper(upper, {\n\t\t\tinclusive: false,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \"<=\") upper = strongerUpper(upper, {\n\t\t\tinclusive: true,\n\t\t\tversion\n\t\t});\n\t}\n\tif (lower !== null && upper !== null) {\n\t\tconst compared = compareBounds(lower.version, upper.version);\n\t\tif (compared > 0 || compared === 0 && (!lower.inclusive || !upper.inclusive)) return null;\n\t}\n\treturn {\n\t\tlower,\n\t\tupper\n\t};\n}\nfunction rangeToIntervals(range) {\n\ttry {\n\t\treturn parseRange(range).sets.flatMap((comparators) => {\n\t\t\tconst interval = comparatorSetToInterval(comparators);\n\t\t\treturn interval === null ? [] : [interval];\n\t\t});\n\t} catch {\n\t\tthrow new ReleaseCatalogCompilationError(\"INVALID_TARGET_RANGE\", `Invalid target app-version range: ${range}`);\n\t}\n}\nfunction releaseDescriptor(release) {\n\treturn {\n\t\treleaseId: release.id,\n\t\tkind: release.kind,\n\t\tbundleId: release.bundleId,\n\t\trolloutCohortCount: release.rolloutCohortCount,\n\t\ttargetCohorts: [...new Set(release.targetCohorts)].sort(),\n\t\tshouldForceUpdate: release.shouldForceUpdate,\n\t\tmessage: release.message\n\t};\n}\nfunction validateReleases(releases, strategy) {\n\tconst enabled = releases.filter((release) => release.enabled).sort((left, right) => right.id.localeCompare(left.id));\n\tconst seenIds = /* @__PURE__ */ new Set();\n\tfor (const release of enabled) {\n\t\tif (!isUUIDv7$1(release.id)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} must use a canonical lowercase UUIDv7 ID`);\n\t\tif (seenIds.has(release.id)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Duplicate Release ID: ${release.id}`);\n\t\tseenIds.add(release.id);\n\t\tif (release.strategy !== strategy) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has the wrong strategy`);\n\t\tif (release.bundleId === null) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has no Bundle`);\n\t\tif (release.targetCohorts.length > MAX_TARGET_COHORTS_PER_RELEASE) throw new ReleaseCatalogCompilationError(\"TARGET_COHORT_LIMIT\", `Release ${release.id} exceeds ${MAX_TARGET_COHORTS_PER_RELEASE} target cohorts`);\n\t\tif (strategy === \"APP_VERSION\" && (release.targetAppVersion === null || release.fingerprintHash !== null)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has an invalid app-version target`);\n\t\tif (strategy === \"FINGERPRINT\" && (release.fingerprintHash === null || release.targetAppVersion !== null)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has an invalid fingerprint target`);\n\t}\n\treturn enabled;\n}\nfunction collectFrontierReleaseIds(releases) {\n\tif (releases.every((release) => normalizeRolloutCohortCount(release.rolloutCohortCount) >= NUMERIC_COHORT_SIZE)) {\n\t\tconst retained = /* @__PURE__ */ new Set();\n\t\tconst bundleIds = /* @__PURE__ */ new Set();\n\t\tfor (const release of releases) {\n\t\t\tif (release.bundleId !== null && !bundleIds.has(release.bundleId)) {\n\t\t\t\tbundleIds.add(release.bundleId);\n\t\t\t\tretained.add(release.id);\n\t\t\t}\n\t\t\tif (bundleIds.size >= 11) break;\n\t\t}\n\t\treturn retained;\n\t}\n\tconst explicitTargetCohorts = new Set(releases.flatMap((release) => release.targetCohorts));\n\tconst cohortStates = [\n\t\tvoid 0,\n\t\t...Array.from({ length: 1e3 }, (_, index) => String(index + 1)),\n\t\t...[...explicitTargetCohorts].sort(),\n\t\t\"release-catalog-non-targeted-cohort\"\n\t].map((cohort) => {\n\t\tconst normalized = cohort === void 0 ? void 0 : normalizeCohortValue(cohort);\n\t\treturn {\n\t\t\tisCustom: normalized !== void 0 && isCustomCohort(normalized),\n\t\t\tnormalized,\n\t\t\tnumeric: normalized === void 0 ? null : getNumericCohortValue(normalized),\n\t\t\tbundleIds: /* @__PURE__ */ new Set(),\n\t\t\tcomplete: false\n\t\t};\n\t});\n\tconst stateIndexesByCohort = /* @__PURE__ */ new Map();\n\tconst fullRolloutStateIndexes = [];\n\tfor (const [index, state] of cohortStates.entries()) {\n\t\tif (state.normalized !== void 0) {\n\t\t\tconst indexes = stateIndexesByCohort.get(state.normalized) ?? [];\n\t\t\tindexes.push(index);\n\t\t\tstateIndexesByCohort.set(state.normalized, indexes);\n\t\t}\n\t\tif (state.normalized === void 0 || state.numeric !== null || state.isCustom) fullRolloutStateIndexes.push(index);\n\t}\n\tconst retained = /* @__PURE__ */ new Set();\n\tlet incompleteStateCount = cohortStates.length;\n\tfor (const release of releases) {\n\t\tconst rolloutCohortCount = normalizeRolloutCohortCount(release.rolloutCohortCount);\n\t\tconst eligibleStateIndexes = /* @__PURE__ */ new Set();\n\t\tif (rolloutCohortCount >= NUMERIC_COHORT_SIZE) for (const index of fullRolloutStateIndexes) eligibleStateIndexes.add(index);\n\t\telse if (rolloutCohortCount > 0) for (const numericCohort of getRolledOutNumericCohorts(release.id, rolloutCohortCount)) for (const index of stateIndexesByCohort.get(String(numericCohort)) ?? []) eligibleStateIndexes.add(index);\n\t\tfor (const targetCohort of new Set(release.targetCohorts.map(normalizeCohortValue))) for (const index of stateIndexesByCohort.get(targetCohort) ?? []) eligibleStateIndexes.add(index);\n\t\tfor (const index of eligibleStateIndexes) {\n\t\t\tconst state = cohortStates[index];\n\t\t\tif (state.complete) continue;\n\t\t\tif (release.bundleId !== null && !state.bundleIds.has(release.bundleId)) {\n\t\t\t\tstate.bundleIds.add(release.bundleId);\n\t\t\t\tretained.add(release.id);\n\t\t\t}\n\t\t\tif (state.bundleIds.size >= 11) {\n\t\t\t\tstate.complete = true;\n\t\t\t\tincompleteStateCount -= 1;\n\t\t\t}\n\t\t}\n\t\tif (incompleteStateCount === 0) break;\n\t}\n\treturn retained;\n}\nfunction intervalContainsSegment(interval, segment) {\n\tif (interval.lower !== null) {\n\t\tif (segment.lower === null) return false;\n\t\tconst compared = compareBounds(segment.lower.version, interval.lower.version);\n\t\tif (compared < 0 || compared === 0 && segment.lower.inclusive && !interval.lower.inclusive) return false;\n\t}\n\tif (interval.upper !== null) {\n\t\tif (segment.upper === null) return false;\n\t\tconst compared = compareBounds(segment.upper.version, interval.upper.version);\n\t\tif (compared > 0 || compared === 0 && segment.upper.inclusive && !interval.upper.inclusive) return false;\n\t}\n\treturn true;\n}\nfunction atomicVersionSegments(intervals) {\n\tconst endpoints = [...new Set(intervals.flatMap((interval) => [interval.lower?.version, interval.upper?.version].filter((version) => version !== void 0)))].sort(compareBounds);\n\tif (endpoints.length === 0) return [{\n\t\tlower: null,\n\t\tupper: null\n\t}];\n\tconst segments = [{\n\t\tlower: null,\n\t\tupper: {\n\t\t\tinclusive: false,\n\t\t\tversion: endpoints[0]\n\t\t}\n\t}];\n\tfor (let index = 0; index < endpoints.length; index += 1) {\n\t\tconst endpoint = endpoints[index];\n\t\tsegments.push({\n\t\t\tlower: {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion: endpoint\n\t\t\t},\n\t\t\tupper: {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion: endpoint\n\t\t\t}\n\t\t});\n\t\tconst next = endpoints[index + 1];\n\t\tif (next !== void 0) segments.push({\n\t\t\tlower: {\n\t\t\t\tinclusive: false,\n\t\t\t\tversion: endpoint\n\t\t\t},\n\t\t\tupper: {\n\t\t\t\tinclusive: false,\n\t\t\t\tversion: next\n\t\t\t}\n\t\t});\n\t}\n\tsegments.push({\n\t\tlower: {\n\t\t\tinclusive: false,\n\t\t\tversion: endpoints.at(-1)\n\t\t},\n\t\tupper: null\n\t});\n\treturn segments;\n}\nfunction sameIndexes(left, right) {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\nfunction mergeSegments(segments) {\n\tconst merged = [];\n\tfor (const segment of segments) {\n\t\tconst previous = merged.at(-1);\n\t\tif (previous && sameIndexes(previous.releaseIndexes, segment.releaseIndexes) && sameIndexes(previous.rollbackReleaseIndexes, segment.rollbackReleaseIndexes)) merged[merged.length - 1] = {\n\t\t\t...previous,\n\t\t\tupper: segment.upper\n\t\t};\n\t\telse merged.push(segment);\n\t}\n\treturn merged;\n}\nfunction compileAppVersion(releases) {\n\tconst ranges = /* @__PURE__ */ new Map();\n\tfor (const release of releases) ranges.set(release.id, rangeToIntervals(release.targetAppVersion));\n\tconst segmentReleases = atomicVersionSegments([...ranges.values()].flat()).map((segment) => {\n\t\tconst applicable = releases.filter((release) => ranges.get(release.id).some((range) => intervalContainsSegment(range, segment)));\n\t\treturn {\n\t\t\trollbackIds: new Set(applicable.map(({ id }) => id)),\n\t\t\tsegment,\n\t\t\tretainedIds: collectFrontierReleaseIds(applicable)\n\t\t};\n\t});\n\tconst retainedIds = new Set(segmentReleases.flatMap(({ retainedIds, rollbackIds }) => [...retainedIds, ...rollbackIds]));\n\tconst retainedReleases = releases.filter((release) => retainedIds.has(release.id));\n\tconst descriptorIndex = new Map(retainedReleases.map((release, index) => [release.id, index]));\n\tconst segments = mergeSegments(segmentReleases.map(({ segment, retainedIds, rollbackIds }) => ({\n\t\t...segment,\n\t\treleaseIndexes: releases.filter((release) => retainedIds.has(release.id)).map((release) => descriptorIndex.get(release.id)).filter((index) => index !== void 0),\n\t\trollbackReleaseIndexes: releases.filter((release) => rollbackIds.has(release.id)).map((release) => descriptorIndex.get(release.id)).filter((index) => index !== void 0)\n\t}))).filter((segment) => segment.releaseIndexes.length > 0 || segment.rollbackReleaseIndexes.length > 0);\n\treturn {\n\t\tenvelope: {\n\t\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\t\tsegments,\n\t\t\tstrategy: \"APP_VERSION\"\n\t\t},\n\t\tretainedReleases\n\t};\n}\nfunction compileFingerprint(releases) {\n\tconst retainedIds = collectFrontierReleaseIds(releases);\n\tconst retainedReleases = releases;\n\treturn {\n\t\tenvelope: {\n\t\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\t\treleaseIndexes: retainedReleases.map((release, index) => retainedIds.has(release.id) ? index : -1).filter((index) => index >= 0),\n\t\t\trollbackReleaseIndexes: retainedReleases.map((_, index) => index),\n\t\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\t\tstrategy: \"FINGERPRINT\"\n\t\t},\n\t\tretainedReleases\n\t};\n}\nasync function sha256(value) {\n\tconst digest = await globalThis.crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(value));\n\treturn `sha256:${[...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\nfunction canonicalStringify(value) {\n\tif (value === null || typeof value !== \"object\") return JSON.stringify(value);\n\tif (Array.isArray(value)) return `[${value.map(canonicalStringify).join(\",\")}]`;\n\tconst record = value;\n\treturn `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalStringify(record[key])}`).join(\",\")}}`;\n}\nasync function compileReleaseCatalog(input) {\n\tconst releases = validateReleases(input.releases, input.strategy);\n\tconst targetCohorts = new Set(releases.flatMap((release) => release.targetCohorts));\n\tif (targetCohorts.size > MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE) throw new ReleaseCatalogCompilationError(\"DISTINCT_TARGET_COHORT_LIMIT\", `Scope exceeds ${MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE} distinct target cohorts`);\n\tconst { envelope, retainedReleases } = input.strategy === \"APP_VERSION\" ? compileAppVersion(releases) : compileFingerprint(releases);\n\tconst payload = {\n\t\t...envelope,\n\t\treleaseDescriptors: retainedReleases.map(releaseDescriptor)\n\t};\n\tconst canonicalPayload = canonicalStringify(payload);\n\tconst byteSize = new TextEncoder().encode(canonicalPayload).byteLength;\n\tif (byteSize > MAX_COMPILED_CATALOG_BYTES) throw new ReleaseCatalogCompilationError(\"CATALOG_OVERSIZE\", `Compiled Release catalog is ${byteSize} bytes; maximum is ${MAX_COMPILED_CATALOG_BYTES}`);\n\treturn {\n\t\tbyteSize,\n\t\tcanonicalPayload,\n\t\tcatalogHash: await sha256(canonicalPayload),\n\t\tdiagnostics: {\n\t\t\tbyteSize,\n\t\t\tdescriptorCount: payload.releaseDescriptors.length,\n\t\t\tdistinctTargetCohortCount: targetCohorts.size,\n\t\t\treleaseCount: releases.length,\n\t\t\tsegmentCount: payload.strategy === \"APP_VERSION\" ? payload.segments.length : 1\n\t\t},\n\t\tpayload\n\t};\n}\nfunction versionInSegment(version, segment) {\n\tif (segment.lower !== null) {\n\t\tconst compared = compareBounds(version, segment.lower.version);\n\t\tif (compared < 0 || compared === 0 && !segment.lower.inclusive) return false;\n\t}\n\tif (segment.upper !== null) {\n\t\tconst compared = compareBounds(version, segment.upper.version);\n\t\tif (compared > 0 || compared === 0 && !segment.upper.inclusive) return false;\n\t}\n\treturn true;\n}\nfunction projectCompiledCatalog(catalog, appVersion) {\n\tlet indexes;\n\tif (catalog.strategy === \"FINGERPRINT\") indexes = catalog.releaseIndexes;\n\telse {\n\t\tconst canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);\n\t\tif (!canonicalVersion) return [];\n\t\tindexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.releaseIndexes ?? [];\n\t}\n\treturn indexes.map((index) => catalog.releaseDescriptors[index]);\n}\nfunction projectCompiledRollbackCatalog(catalog, appVersion) {\n\tlet indexes;\n\tif (catalog.strategy === \"FINGERPRINT\") indexes = catalog.rollbackReleaseIndexes;\n\telse {\n\t\tconst canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);\n\t\tif (!canonicalVersion) return [];\n\t\tindexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.rollbackReleaseIndexes ?? [];\n\t}\n\treturn indexes.map((index) => catalog.releaseDescriptors[index]);\n}\nfunction referenceCompatibleReleases(releases, appVersion) {\n\tconst canonicalVersion = canonicalizeAppVersion(appVersion);\n\tif (!canonicalVersion) return [];\n\treturn releases.filter((release) => release.enabled && release.targetAppVersion !== null && satisfies(canonicalVersion, release.targetAppVersion));\n}\n//#endregion\nexport { ReleaseCatalogCompilationError, canonicalizeAppVersion$1 as canonicalizeAppVersion, compileReleaseCatalog, projectCompiledCatalog, projectCompiledRollbackCatalog, referenceCompatibleReleases };\n", "//#region src/releaseManagement.ts\nvar ReleaseManagementError = class extends Error {\n\tcode;\n\tname = \"ReleaseManagementError\";\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { ReleaseManagementError };\n", "//#region src/releaseCatalogMutation.ts\nvar ReleaseCatalogMutationError = class extends Error {\n\tcode;\n\tname = \"ReleaseCatalogMutationError\";\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { ReleaseCatalogMutationError };\n", "import { f as satisfies } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { n as coerce } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs\";\n//#region src/semverSatisfies.ts\nconst semverSatisfies = (targetAppVersion, currentVersion) => {\n\tconst currentCoerce = coerce(currentVersion);\n\tif (!currentCoerce) return false;\n\treturn satisfies(currentCoerce, targetAppVersion);\n};\n//#endregion\nexport { semverSatisfies };\n", "//#region src/serverPlugin/definePlugin.ts\n/** Declares a plugin; Hot Updater's own plugins and third-party ones use the same contract. */\nconst definePlugin = (plugin) => plugin;\n//#endregion\nexport { definePlugin };\n", "//#region src/serverPlugin/schema.ts\nconst defineTable = (fields, options) => ({\n\tkind: \"table\",\n\tfields,\n\tkey: options.key,\n\tderived: options.derived ?? {},\n\tindexes: options.indexes ?? {},\n\t...options.retention === void 0 ? {} : { retention: options.retention }\n});\nconst defineAggregate = (fields, options) => ({\n\tkind: \"aggregate\",\n\tfields,\n\tkey: options.key,\n\tcounters: options.counters ?? [],\n\tgauges: options.gauges ?? [],\n\tdistinct: options.distinct ?? [],\n\tshards: options.shards ?? 1,\n\tindexes: options.indexes ?? {},\n\t...options.batched ? { batched: true } : {},\n\t...options.retention === void 0 ? {} : { retention: options.retention }\n});\n//#endregion\nexport { defineAggregate, defineTable };\n", "//#region src/serverPlugin/errors.ts\nvar DatabaseConstraintError = class extends Error {\n\treason;\n\tmodel;\n\tname = \"DatabaseConstraintError\";\n\tconstructor(reason, model) {\n\t\tsuper(`${model}: ${reason}`);\n\t\tthis.reason = reason;\n\t\tthis.model = model;\n\t}\n};\n/** The retry budget ran out; ingestion answers 503 with Retry-After. */\nvar DatabaseConflictError = class extends Error {\n\tname = \"DatabaseConflictError\";\n};\n/** The write may or may not have committed; it is reported, never rerun. */\nvar DatabaseAmbiguousCommitError = class extends Error {\n\tname = \"DatabaseAmbiguousCommitError\";\n};\nvar DatabaseTransactionError = class extends Error {\n\tname = \"DatabaseTransactionError\";\n};\n/** A read that does not fit its model, such as an unknown index, a missing `where` field, or an out-of-range limit. */\nvar DatabaseQueryError = class extends Error {\n\tname = \"DatabaseQueryError\";\n};\n/** A malformed cursor, or one from a read with another model, index, filter, order, or range. */\nvar DatabaseCursorError = class extends Error {\n\tname = \"DatabaseCursorError\";\n};\n//#endregion\nexport { DatabaseAmbiguousCommitError, DatabaseConflictError, DatabaseConstraintError, DatabaseCursorError, DatabaseQueryError, DatabaseTransactionError };\n", "import { DatabaseConflictError } from \"./errors.mjs\";\n//#region src/serverPlugin/busy.ts\n/** Error names the AWS SDKs give a throttled request, as their retry strategy classifies them. */\nconst THROTTLING_NAMES = /* @__PURE__ */ new Set([\n\t\"ProvisionedThroughputExceededException\",\n\t\"RequestLimitExceeded\",\n\t\"RequestThrottled\",\n\t\"RequestThrottledException\",\n\t\"SlowDown\",\n\t\"ThrottledException\",\n\t\"Throttling\",\n\t\"ThrottlingException\",\n\t\"TooManyRequestsException\"\n]);\n/** gRPC's RESOURCE_EXHAUSTED, the status Firestore throttles a request with. */\nconst RESOURCE_EXHAUSTED = 8;\n/**\n* Whether the database is busy rather than broken, so the same request can\n* succeed later: a transaction ran out of retries, or the backend throttled\n* a request. Writes already retry transient failures, throttled ones\n* included, until the budget runs out. A throttled read throws the backend's\n* own error, so it is recognized by what the backends call it: a name the\n* AWS SDKs retry as throttling, HTTP 429, or gRPC's RESOURCE_EXHAUSTED.\n*/\nconst isDatabaseBusyError = (error) => {\n\tif (error instanceof DatabaseConflictError) return true;\n\tif (typeof error !== \"object\" || error === null) return false;\n\tconst { name, code, message, status, statusCode, $metadata } = error;\n\treturn typeof name === \"string\" && THROTTLING_NAMES.has(name) || [\n\t\tstatus,\n\t\tstatusCode,\n\t\t$metadata?.httpStatusCode\n\t].includes(429) || code === RESOURCE_EXHAUSTED && typeof message === \"string\" && message.includes(\"RESOURCE_EXHAUSTED\");\n};\n//#endregion\nexport { isDatabaseBusyError };\n", "//#region src/database/distinct.ts\n/**\n* HyperLogLog sketches, the storage engine's `distinct` aggregate metric: a\n* sketch is 1,024 registers stored as a 1,024-character string, so adding a\n* value, merging sketches, and counting one never need the values back.\n*/\nconst PRECISION = 10;\nconst REGISTER_COUNT = 1024;\nconst MAX_RANK = 55;\nconst hash = (value) => {\n\tlet result = 14695981039346656037n;\n\tfor (const byte of new TextEncoder().encode(value)) {\n\t\tresult ^= BigInt(byte);\n\t\tresult = BigInt.asUintN(64, result * 1099511628211n);\n\t}\n\treturn result;\n};\nconst OFFSET = 33;\nconst decode = (summary) => {\n\tif (!summary) return new Uint8Array(REGISTER_COUNT);\n\tif (summary.length !== REGISTER_COUNT) throw new Error(\"Invalid distinct sketch\");\n\tconst registers = new Uint8Array(REGISTER_COUNT);\n\tfor (let index = 0; index < REGISTER_COUNT; index += 1) {\n\t\tconst value = summary.charCodeAt(index) - OFFSET;\n\t\tif (!Number.isInteger(value) || value < 0 || value > MAX_RANK) throw new Error(\"Invalid distinct sketch\");\n\t\tregisters[index] = value;\n\t}\n\treturn registers;\n};\nconst encode = (registers) => Array.from(registers, (value) => String.fromCharCode(value + OFFSET)).join(\"\");\nconst distinctRegister = (identity) => {\n\tconst value = hash(identity);\n\tconst index = Number(value & BigInt(1023));\n\tlet remainder = value >> BigInt(PRECISION);\n\tlet rank = 1;\n\twhile ((remainder & 1n) === 0n && rank < MAX_RANK) {\n\t\trank += 1;\n\t\tremainder >>= 1n;\n\t}\n\treturn {\n\t\tindex,\n\t\trank,\n\t\tcharacter: String.fromCharCode(rank + OFFSET)\n\t};\n};\n/**\n* The sketch with `identity` added; a missing sketch is the empty one. A\n* plugin passes it as a `distinct` column's change to `tx.aggregate`.\n*/\nconst addDistinct = (summary, identity) => {\n\tconst registers = decode(summary);\n\tconst { index, rank } = distinctRegister(identity);\n\tregisters[index] = Math.max(registers[index], rank);\n\treturn encode(registers);\n};\n/**\n* The union of sketches, register by register: how a plugin combines a\n* `distinct` column across the aggregate rows it reads.\n*/\nconst mergeDistinct = (summaries) => {\n\tconst merged = new Uint8Array(REGISTER_COUNT);\n\tfor (const summary of summaries) {\n\t\tconst registers = decode(summary);\n\t\tfor (let index = 0; index < REGISTER_COUNT; index += 1) merged[index] = Math.max(merged[index], registers[index]);\n\t}\n\treturn encode(merged);\n};\n/**\n* The estimated number of distinct values a sketch holds: how a plugin\n* reads a `distinct` column.\n*/\nconst countDistinct = (summary) => {\n\tconst registers = decode(summary);\n\tlet inverseSum = 0;\n\tlet empty = 0;\n\tfor (const register of registers) {\n\t\tinverseSum += 2 ** -register;\n\t\tif (register === 0) empty += 1;\n\t}\n\tconst raw = .7213 / 1.0010537109375 * REGISTER_COUNT ** 2 / inverseSum;\n\tconst estimate = raw <= 2.5 * REGISTER_COUNT && empty > 0 ? REGISTER_COUNT * Math.log(REGISTER_COUNT / empty) : raw;\n\treturn Math.max(0, Math.round(estimate));\n};\n//#endregion\nexport { addDistinct, countDistinct, distinctRegister, mergeDistinct };\n", "//#region src/serverPlugin/configError.ts\n/** A misconfigured `createHotUpdater` call, reported at startup. */\nvar HotUpdaterConfigError = class extends Error {\n\tname = \"HotUpdaterConfigError\";\n};\n//#endregion\nexport { HotUpdaterConfigError };\n", "import { l as normalizeRange } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { createReleaseCatalogScopeKey, encodeChannelKey, parseReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/baseCandidateKey.ts\n/**\n* A new bundle's base-candidate key, which `findBaseBundleIds` on core's API\n* and on a plugin's `ctx.core` takes: the Release Catalog scope its devices\n* update from, and for an app version its normalized range; null for a\n* target without a valid range. The CLI's deploy produces it this way.\n*/\nconst targetBaseCandidateKey = (target) => {\n\tconst channelKey = encodeChannelKey(target.channel);\n\tif (target.fingerprintHash) return JSON.stringify([createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tfingerprintHash: target.fingerprintHash,\n\t\tplatform: target.platform,\n\t\tstrategy: \"FINGERPRINT\"\n\t})]);\n\tconst range = target.appVersion === null ? null : normalizeRange(target.appVersion);\n\treturn range === null ? null : JSON.stringify([createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tplatform: target.platform,\n\t\tstrategy: \"APP_VERSION\"\n\t}), range]);\n};\n/**\n* The scope and range a base-candidate key names, null for any other\n* string: what an implementation of `findBaseBundleIds` reads the key with.\n*/\nconst parseBaseCandidateKey = (key) => {\n\ttry {\n\t\tconst parsed = JSON.parse(key);\n\t\tif (!Array.isArray(parsed) || typeof parsed[0] !== \"string\") return null;\n\t\tconst [scopeKey, text] = parsed;\n\t\tconst { strategy } = parseReleaseCatalogScopeKey(scopeKey);\n\t\tif (strategy === \"FINGERPRINT\") return parsed.length === 1 ? {\n\t\t\tscopeKey,\n\t\t\trange: null\n\t\t} : null;\n\t\tconst range = parsed.length === 2 && typeof text === \"string\" ? normalizeRange(text) : null;\n\t\treturn range === null ? null : {\n\t\t\tscopeKey,\n\t\t\trange\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n};\n//#endregion\nexport { parseBaseCandidateKey, targetBaseCandidateKey };\n", "//#region src/database/adapter.ts\n/**\n* The version column every stored row carries, which a guarded write\n* compares and bumps. An adapter that is neither SQL nor key-value, such as\n* the MongoDB adapter, stores and checks it itself.\n*/\nconst DATABASE_VERSION_COLUMN = \"_v\";\nvar DatabaseSchemaError = class extends Error {\n\tname = \"DatabaseSchemaError\";\n};\n/**\n* The column `name` of `table`, or a `DatabaseSchemaError`: how an adapter\n* that is neither SQL nor key-value, such as the MongoDB adapter, reads a\n* column's type.\n*/\nconst findPhysicalColumn = (table, name) => {\n\tconst column = table.columns.find((candidate) => candidate.name === name);\n\tif (column === void 0) throw new DatabaseSchemaError(`${table.name} has no column ${name}.`);\n\treturn column;\n};\n/**\n* The index `name` of `table`, or a `DatabaseSchemaError`: how an adapter\n* that is neither SQL nor key-value, such as the MongoDB adapter, resolves a\n* query's `index`.\n*/\nconst findPhysicalIndex = (table, name) => {\n\tconst index = table.indexes.find((candidate) => candidate.name === name);\n\tif (index === void 0) throw new DatabaseSchemaError(`${table.name} has no index ${name}.`);\n\treturn index;\n};\n/**\n* The columns that order an index read and close its cursors: the sort\n* columns, then the key columns that neither `eq` nor `sort` fixes.\n*/\nconst indexOrderColumns = (table, index) => [...index.sort, ...table.key.filter((column) => !index.sort.includes(column) && !index.eq.includes(column))];\n/**\n* When a row of a table with retention expires, in epoch milliseconds, or\n* undefined when the table keeps its rows or the row's time is null.\n*/\nconst expiresAt = (table, row) => {\n\tconst time = table.retention && row[table.retention.column];\n\treturn typeof time === \"number\" ? time + table.retention.ms : void 0;\n};\n/**\n* The primary key of a row, in key-column order: what `get` takes for it.\n* An adapter that is neither SQL nor key-value, such as the MongoDB adapter,\n* addresses rows by it.\n*/\nconst rowKey = (table, row) => table.key.map((column) => {\n\tconst value = row[column];\n\tif (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") throw new DatabaseSchemaError(`${table.name}.${column} is a key column and must be a string, number, or boolean.`);\n\treturn value;\n});\n//#endregion\nexport { DATABASE_VERSION_COLUMN, DatabaseSchemaError, expiresAt, findPhysicalColumn, findPhysicalIndex, indexOrderColumns, rowKey };\n", "import { findPhysicalColumn, indexOrderColumns } from \"./adapter.mjs\";\n//#region src/database/values.ts\nvar DatabaseValueError = class extends Error {\n\tname = \"DatabaseValueError\";\n};\n/**\n* Compares strings in UTF-8 byte order, which is Unicode code point order:\n* the order the engine sorts string keys in. A plugin that merges rows from\n* several reads, as Insights does, keeps that order with it.\n*/\nconst compareUtf8 = (left, right) => {\n\tlet leftIndex = 0;\n\tlet rightIndex = 0;\n\twhile (leftIndex < left.length && rightIndex < right.length) {\n\t\tconst leftPoint = left.codePointAt(leftIndex);\n\t\tconst rightPoint = right.codePointAt(rightIndex);\n\t\tif (leftPoint !== rightPoint) return leftPoint < rightPoint ? -1 : 1;\n\t\tleftIndex += leftPoint > 65535 ? 2 : 1;\n\t\trightIndex += rightPoint > 65535 ? 2 : 1;\n\t}\n\tconst leftDone = leftIndex >= left.length;\n\treturn leftDone === rightIndex >= right.length ? 0 : leftDone ? -1 : 1;\n};\n/** Orders strings by UTF-8 bytes, numbers numerically, and false before true. */\nconst compareKeyValues = (left, right) => {\n\tif (typeof left === \"string\" && typeof right === \"string\") return compareUtf8(left, right);\n\tif (typeof left === \"number\" && typeof right === \"number\") return left < right ? -1 : left > right ? 1 : 0;\n\tif (typeof left === \"boolean\" && typeof right === \"boolean\") return Number(left) - Number(right);\n\tthrow new DatabaseValueError(`Cannot compare ${typeof left} with ${typeof right}.`);\n};\n/** Compares tuples element by element; a shorter equal prefix sorts first. */\nconst compareTuples = (left, right) => {\n\tfor (let index = 0; index < Math.min(left.length, right.length); index += 1) {\n\t\tconst result = compareKeyValues(left[index], right[index]);\n\t\tif (result !== 0) return result;\n\t}\n\treturn left.length - right.length;\n};\n/** JSON text with object keys sorted, so a value compares equal after a store reorders map keys. */\nconst canonicalJson = (value) => JSON.stringify(value ?? null, (_, inner) => inner !== null && typeof inner === \"object\" && !Array.isArray(inner) ? Object.fromEntries(Object.entries(inner).sort(([left], [right]) => compareUtf8(left, right))) : inner);\nconst isKeyValue = (value) => typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value);\n/** Every `eq` tuple a row is indexed under; none when an index field is null. */\nconst indexEntries = (table, index, row) => {\n\tif (index.sort.some((column) => !isKeyValue(row[column]))) return [];\n\tlet entries = [[]];\n\tfor (const column of index.eq) {\n\t\tconst value = row[column];\n\t\tconst values = findPhysicalColumn(table, column).multi ? Array.isArray(value) ? value.filter(isKeyValue) : [] : isKeyValue(value) ? [value] : [];\n\t\tif (values.length === 0) return [];\n\t\tentries = entries.flatMap((entry) => [...new Set(values)].map((item) => [...entry, item]));\n\t}\n\treturn entries;\n};\n/** The row's position in an index read, following `indexOrderColumns`. */\nconst indexOrderTuple = (table, index, row) => indexOrderColumns(table, index).map((column) => {\n\tconst value = row[column];\n\tif (!isKeyValue(value)) throw new DatabaseValueError(`${table.name}.${column} is not orderable for index ${index.name}.`);\n\treturn value;\n});\nconst satisfiesBound = (tuple, bound, side) => {\n\tif (bound === void 0) return true;\n\tconst result = compareTuples(tuple.slice(0, bound.values.length), bound.values);\n\tif (result === 0) return bound.inclusive;\n\treturn side === \"lower\" ? result > 0 : result < 0;\n};\n/** Whether a stored row belongs to the result range of a query. */\nconst matchesQuery = (table, index, request, row) => indexEntries(table, index, row).some((entry) => compareTuples(entry, request.eq) === 0) && satisfiesBound(indexOrderTuple(table, index, row), request.lower, \"lower\") && satisfiesBound(indexOrderTuple(table, index, row), request.upper, \"upper\");\nconst INTEGER_TEXT = /^-?\\d+$/u;\nconst NUMBER_TEXT = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/iu;\nconst toNumber = (raw, integer) => {\n\tconst text = typeof raw === \"bigint\" ? raw.toString() : typeof raw === \"string\" ? raw : typeof raw === \"object\" && raw !== null && \"toString\" in raw ? String(raw) : void 0;\n\tconst value = typeof raw === \"number\" ? raw : text !== void 0 && (integer ? INTEGER_TEXT : NUMBER_TEXT).test(text) ? Number(text) : NaN;\n\tif (integer ? !Number.isSafeInteger(value) : !Number.isFinite(value)) throw new DatabaseValueError(`Expected a ${integer ? \"safe integer\" : \"finite number\"}.`);\n\treturn value;\n};\nconst toBoolean = (raw) => {\n\tif (raw === true || raw === 1 || raw === 1n || raw === \"1\" || raw === \"t\") return true;\n\tif (raw === false || raw === 0 || raw === 0n || raw === \"0\" || raw === \"f\") return false;\n\tif (raw === \"true\" || raw === \"false\") return raw === \"true\";\n\tthrow new DatabaseValueError(\"Expected a boolean.\");\n};\nconst toScalar = (column, raw) => {\n\tswitch (column.type) {\n\t\tcase \"string\":\n\t\t\tif (typeof raw !== \"string\") throw new DatabaseValueError(`Expected a string in ${column.name}.`);\n\t\t\treturn raw;\n\t\tcase \"integer\":\n\t\tcase \"number\": return toNumber(raw, column.type === \"integer\");\n\t\tcase \"boolean\": return toBoolean(raw);\n\t\tcase \"json\": return raw;\n\t}\n};\n/** Converts a backend value (int8 text, BigInt, Decimal, 0/1, JSON text) to a stored value. */\nconst normalizeStoredValue = (column, raw, options) => {\n\tif (raw === null || raw === void 0) return null;\n\tconst parsed = options.jsonText && (column.multi || column.type === \"json\") && typeof raw === \"string\" ? JSON.parse(raw) : raw;\n\tif (!column.multi) return toScalar(column, parsed);\n\tif (!Array.isArray(parsed) || parsed.length > 16) throw new DatabaseValueError(`Expected at most 16 values in ${column.name}.`);\n\treturn parsed.map((item) => toScalar(column, item));\n};\n/** Converts every column of a backend row; unknown backend columns are dropped. */\nconst normalizeStoredRow = (table, raw, options) => Object.fromEntries(table.columns.map((column) => [column.name, normalizeStoredValue(column, raw[column.name], options)]));\n//#endregion\nexport { DatabaseValueError, canonicalJson, compareKeyValues, compareTuples, compareUtf8, indexEntries, indexOrderTuple, isKeyValue, matchesQuery, normalizeStoredRow, normalizeStoredValue };\n", "import { findPhysicalIndex, rowKey } from \"./adapter.mjs\";\nimport { compareTuples, indexOrderTuple, isKeyValue, matchesQuery } from \"./values.mjs\";\n//#region src/database/verifyAdapter.ts\n/** What `verifyAdapter` throws when an adapter call breaks the adapter contract. */\nvar DatabaseAdapterContractError = class extends Error {\n\tname = \"DatabaseAdapterContractError\";\n};\nconst EMPTY = {\n\tgets: 0,\n\tkeys: 0,\n\tqueries: 0,\n\trows: 0\n};\nconst createReadMeter = () => {\n\tconst tables = /* @__PURE__ */ new Map();\n\tconst add = (table, count) => {\n\t\tconst current = tables.get(table) ?? EMPTY;\n\t\ttables.set(table, {\n\t\t\tgets: current.gets + (count.gets ?? 0),\n\t\t\tkeys: current.keys + (count.keys ?? 0),\n\t\t\tqueries: current.queries + (count.queries ?? 0),\n\t\t\trows: current.rows + (count.rows ?? 0)\n\t\t});\n\t};\n\treturn {\n\t\tadd,\n\t\tmeter: {\n\t\t\ttotal: () => [...tables.values()].reduce((sum, count) => ({\n\t\t\t\tgets: sum.gets + count.gets,\n\t\t\t\tkeys: sum.keys + count.keys,\n\t\t\t\tqueries: sum.queries + count.queries,\n\t\t\t\trows: sum.rows + count.rows\n\t\t\t}), EMPTY),\n\t\t\tbyTable: (table) => tables.get(table) ?? EMPTY,\n\t\t\treset: () => tables.clear()\n\t\t}\n\t};\n};\nconst fail = (message) => {\n\tthrow new DatabaseAdapterContractError(message);\n};\nconst sameKey = (left, right) => left.length === right.length && compareTuples(left, right) === 0;\nconst verifyRequest = (table, request) => {\n\tconst index = findPhysicalIndex(table, request.index);\n\tif (!Number.isSafeInteger(request.limit) || request.limit < 1 || request.limit > 500) fail(`query limit must be 1\u2013500.`);\n\tif (request.eq.length !== index.eq.length || !request.eq.every(isKeyValue)) fail(`query on ${table.name}.${index.name} must bind every eq column.`);\n\treturn index;\n};\nconst verifyRows = (table, request, rows) => {\n\tconst index = findPhysicalIndex(table, request.index);\n\tif (rows.length > request.limit) fail(`${table.name}.${index.name} returned more than ${request.limit} rows.`);\n\tlet previous;\n\tfor (const row of rows) {\n\t\tif (!matchesQuery(table, index, request, row)) fail(`${table.name}.${index.name} returned a row outside the request.`);\n\t\tconst tuple = indexOrderTuple(table, index, row);\n\t\tif (previous !== void 0) {\n\t\t\tconst order = compareTuples(previous, tuple);\n\t\t\tif (request.order === \"asc\" ? order >= 0 : order <= 0) fail(`${table.name}.${index.name} returned rows out of order.`);\n\t\t}\n\t\tprevious = tuple;\n\t}\n\treturn previous;\n};\nconst verifyWrite = (adapter, ops) => {\n\tif (ops.length === 0) fail(\"write needs at least one op.\");\n\tconst seen = /* @__PURE__ */ new Set();\n\tfor (const op of ops) {\n\t\tconst key = op.type === \"insert\" ? rowKey(op.table, op.row) : op.key;\n\t\tconst id = JSON.stringify([op.table.name, key]);\n\t\tif (seen.has(id)) fail(`write touches ${op.table.name} ${id} twice.`);\n\t\tseen.add(id);\n\t\tif (op.type === \"insert\" && typeof op.row[\"_v\"] !== \"number\") fail(`insert into ${op.table.name} must set _v.`);\n\t\tif (op.type === \"patch\" && Object.keys(op.set).some((column) => column === \"_v\" || op.table.key.includes(column))) fail(`patch of ${op.table.name} may not set key columns or _v.`);\n\t}\n\tif (!adapter.fits(ops)) fail(\"write does not fit in one atomic write.\");\n};\n/** Wraps an adapter to check the contract at its boundary and count reads. */\nconst verifyAdapter = (adapter, options = {}) => {\n\tconst { add, meter } = createReadMeter();\n\treturn {\n\t\t...adapter,\n\t\tid: adapter.id,\n\t\treads: meter,\n\t\tfits: (ops) => adapter.fits(ops),\n\t\tasync get(table, keys) {\n\t\t\tconst rows = await adapter.get(table, keys);\n\t\t\tadd(table.name, {\n\t\t\t\tgets: 1,\n\t\t\t\tkeys: keys.length\n\t\t\t});\n\t\t\tif (rows.length !== keys.length) fail(`${table.name} get returned ${rows.length} rows for ${keys.length} keys.`);\n\t\t\trows.forEach((row, position) => {\n\t\t\t\tif (row !== null && !sameKey(rowKey(table, row), keys[position])) fail(`${table.name} get returned a row for another key.`);\n\t\t\t});\n\t\t\treturn rows;\n\t\t},\n\t\tasync query(table, request) {\n\t\t\tconst index = verifyRequest(table, request);\n\t\t\tconst rows = await adapter.query(table, request);\n\t\t\tadd(table.name, {\n\t\t\t\tqueries: 1,\n\t\t\t\trows: rows.length\n\t\t\t});\n\t\t\tconst last = verifyRows(table, request, rows);\n\t\t\tif (options.probeShortPages && last !== void 0 && rows.length < request.limit) {\n\t\t\t\tconst bound = {\n\t\t\t\t\tvalues: last,\n\t\t\t\t\tinclusive: false\n\t\t\t\t};\n\t\t\t\tif ((await adapter.query(table, {\n\t\t\t\t\t...request,\n\t\t\t\t\tlimit: 1,\n\t\t\t\t\t...request.order === \"asc\" ? { lower: bound } : { upper: bound }\n\t\t\t\t})).length > 0) fail(`${table.name}.${index.name} returned a short page before the range ended.`);\n\t\t\t}\n\t\t\treturn rows;\n\t\t},\n\t\t...adapter.prune && { async prune(table, before, limit) {\n\t\t\tif (table.retention === void 0) fail(`${table.name} has no retention to prune by.`);\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1) fail(\"prune limit must be a positive integer.\");\n\t\t\tconst deleted = await adapter.prune(table, before, limit);\n\t\t\tif (!Number.isSafeInteger(deleted) || deleted < 0 || deleted > limit) fail(`${table.name} prune reported ${deleted} rows for ${limit}.`);\n\t\t\treturn deleted;\n\t\t} },\n\t\tasync write(ops) {\n\t\t\tverifyWrite(adapter, ops);\n\t\t\tconst result = await adapter.write(ops);\n\t\t\tif (!result.ok && \"failedOp\" in result) {\n\t\t\t\tif (!Number.isSafeInteger(result.failedOp) || result.failedOp < 0 || result.failedOp >= ops.length) fail(`write reported failedOp ${result.failedOp} for ${ops.length} ops.`);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n};\n//#endregion\nexport { DatabaseAdapterContractError, verifyAdapter };\n", "//#region src/engine/database/fence.ts\n/**\n* The settings rows migrations write, last, and the fence reads; retention\n* passes keep their lease here too. Tooling that creates the tables creates\n* this one with them: an ORM's schema generator, a provider's setup, and an\n* access policy that names the tables a server reads.\n*/\nconst SETTINGS_TABLE = {\n\tname: \"private_hot_updater_settings\",\n\tcolumns: [\n\t\t{\n\t\t\tname: \"key\",\n\t\t\ttype: \"string\",\n\t\t\tnullable: false,\n\t\t\tmaxLength: 255\n\t\t},\n\t\t{\n\t\t\tname: \"value\",\n\t\t\ttype: \"string\",\n\t\t\tnullable: false,\n\t\t\tmaxLength: 255\n\t\t},\n\t\t{\n\t\t\tname: \"_v\",\n\t\t\ttype: \"integer\",\n\t\t\tnullable: false,\n\t\t\tdefault: 0\n\t\t}\n\t],\n\tkey: [\"key\"],\n\tindexes: []\n};\n/** The engine's storage-layout generation; it changes only with a migration. */\nconst ENGINE_SCHEMA_KEY = \"schema.engine\";\nconst CORE_SCHEMA_KEY = \"schema.core\";\nconst stored = ({ key, expected, found }) => `\"${key}\" is ${found === null ? \"missing\" : `\"${found}\"`}; expected \"${expected}\"`;\nconst settingMessage = (adapterName, { key, expected, found }) => `Hot Updater schema setting \"${key}\" for ${adapterName} is ${found === null ? \"missing\" : `\"${found}\"`}; expected \"${expected}\". Run \\`hot-updater db migrate\\`.`;\n/** The plugin a `schema.<id>` setting belongs to; undefined for core's and the engine's. */\nconst pluginOf = ({ key }) => key.startsWith(\"schema.\") && key !== \"schema.engine\" && key !== CORE_SCHEMA_KEY ? key.slice(7) : void 0;\nconst listed = (items) => items.length < 2 ? items.join(\"\") : `${items.slice(0, -1).join(\", \")} and ${items.at(-1)}`;\n/** How to create plugins' tables when the fence was given no fix. */\nconst PLUGIN_TABLES_FIX = \"Run `hot-updater db migrate`. A managed server runs only its provider's plugins, and rerunning `hot-updater init --provider <provider>` applies the provider's migrations. Run `hot-updater db` commands in the server's project: they load the server file named on the command line, or src/hotUpdater.* or src/db.*, and don't read hot-updater.config.ts.\";\nconst pluginsMessage = (adapterName, plugins, settings, fix) => `The tables of ${plugins.length === 1 ? \"plugin\" : \"plugins\"} ${listed(plugins.map((id) => `\"${id}\"`))} are not migrated on ${adapterName}: schema ${settings.length === 1 ? \"setting\" : \"settings\"} ${settings.map(stored).join(\", and \")}. ${fix}`;\n/** The database needs `hot-updater db migrate`, or a new database; the handler answers 503. */\nvar HotUpdaterSchemaMigrationRequiredError = class extends Error {\n\tadapterName;\n\tcurrentVersion;\n\tsetting;\n\t/** Every setting the fence found missing or different; `setting` is the first. */\n\tsettings;\n\t/**\n\t* The ids of the plugins whose `schema.<id>` setting is among them: the\n\t* plugins whose tables a migration has yet to create or change.\n\t*/\n\tplugins;\n\tconstructor(adapterName, currentVersion, setting, options) {\n\t\tconst settings = options?.settings ?? (setting === void 0 ? [] : [setting]);\n\t\tconst plugins = settings.flatMap((mismatch) => pluginOf(mismatch) ?? []);\n\t\tsuper(setting === void 0 ? currentVersion === void 0 ? `Hot Updater database schema is not initialized for ${adapterName}. Run \\`hot-updater db migrate\\` before using this adapter.` : `Hot Updater v1 cannot migrate schema ${currentVersion} in place. Create a new empty database and run \\`hot-updater db migrate\\`.` : plugins.length > 0 && plugins.length === settings.length ? pluginsMessage(adapterName, plugins, settings, options?.fix ?? PLUGIN_TABLES_FIX) : settingMessage(adapterName, setting), options?.cause === void 0 ? void 0 : { cause: options.cause });\n\t\tthis.adapterName = adapterName;\n\t\tthis.currentVersion = currentVersion;\n\t\tthis.setting = setting;\n\t\tthis.name = \"HotUpdaterSchemaMigrationRequiredError\";\n\t\tthis.settings = settings;\n\t\tthis.plugins = plugins;\n\t}\n};\n/** Driver codes for a table or column the database lacks. */\nconst MISSING_SCHEMA_CODES = /* @__PURE__ */ new Set([\n\t\"42P01\",\n\t\"42703\",\n\t\"ER_NO_SUCH_TABLE\",\n\t\"ER_BAD_FIELD_ERROR\"\n]);\nconst MISSING_SCHEMA_MESSAGE = /no such (?:table|column)|(?:relation|column) .+ does not exist|table .+ doesn't exist|unknown column/iu;\n/**\n* Whether a read failed because a table or column is missing, so the\n* database needs migrations. ORMs may wrap the driver's error in `cause`.\n*/\nconst isMissingSchemaError = (error) => {\n\tfor (let depth = 0; error instanceof Object && depth < 8; depth += 1) {\n\t\tconst { code, message, cause } = error;\n\t\tif (MISSING_SCHEMA_CODES.has(String(code)) || typeof message === \"string\" && MISSING_SCHEMA_MESSAGE.test(message)) return true;\n\t\terror = cause;\n\t}\n\treturn false;\n};\nconst readSettings = (adapter, keys) => adapter.get(SETTINGS_TABLE, keys.map((key) => [key]));\n/**\n* Throws unless every expected setting is stored with its value: one batch\n* read. The error lists every setting missing or different; `fix` says how\n* to create the plugins' tables on this database.\n*/\nconst checkSchemaFence = async (adapter, adapterName, expected, fix) => {\n\tconst keys = Object.keys(expected);\n\tlet rows;\n\ttry {\n\t\trows = await readSettings(adapter, keys);\n\t} catch (cause) {\n\t\tif (!isMissingSchemaError(cause)) throw cause;\n\t\tthrow new HotUpdaterSchemaMigrationRequiredError(adapterName, void 0, {\n\t\t\tkey: ENGINE_SCHEMA_KEY,\n\t\t\texpected: \"1\",\n\t\t\tfound: null\n\t\t}, { cause });\n\t}\n\tconst settings = keys.flatMap((key, position) => {\n\t\tconst found = rows[position]?.value;\n\t\treturn found === expected[key] ? [] : [{\n\t\t\tkey,\n\t\t\texpected: expected[key],\n\t\t\tfound: typeof found === \"string\" ? found : null\n\t\t}];\n\t});\n\tconst [first] = settings;\n\tif (first !== void 0) throw new HotUpdaterSchemaMigrationRequiredError(adapterName, void 0, first, {\n\t\tsettings,\n\t\t...fix === void 0 ? {} : { fix }\n\t});\n};\n/** The database name a fenced adapter carries, so a server can fence its plugins' rows too. */\nconst FENCED = Symbol.for(\"@hot-updater/server/schema-fence\");\n/** The database name an adapter behind the schema fence reports under. */\nconst fencedName = (adapter) => adapter[FENCED];\n/**\n* The adapter behind the schema fence: a process's first read or write\n* checks the settings first. Success is kept; a failure is checked again on\n* the next call.\n*/\nconst withSchemaFence = (adapter, adapterName, expected, fix) => {\n\tlet ready;\n\tconst fence = () => {\n\t\tready ??= checkSchemaFence(adapter, adapterName, expected, fix).catch((error) => {\n\t\t\tready = void 0;\n\t\t\tthrow error;\n\t\t});\n\t\treturn ready;\n\t};\n\treturn {\n\t\t...adapter,\n\t\t[FENCED]: adapterName,\n\t\tget: (table, keys) => fence().then(() => adapter.get(table, keys)),\n\t\tquery: (table, request) => fence().then(() => adapter.query(table, request)),\n\t\twrite: (ops) => fence().then(() => adapter.write(ops)),\n\t\t...adapter.prune && { prune: (table, before, limit) => fence().then(() => adapter.prune(table, before, limit)) }\n\t};\n};\n//#endregion\nexport { ENGINE_SCHEMA_KEY, HotUpdaterSchemaMigrationRequiredError, SETTINGS_TABLE, checkSchemaFence, fencedName, isMissingSchemaError, readSettings, withSchemaFence };\n", "//#region src/engine/database/readMeter.ts\nconst METER = Symbol.for(\"@hot-updater/plugin-core/read-meter\");\nconst NO_READS = {\n\tgets: 0,\n\tkeys: 0,\n\tqueries: 0,\n\trows: 0\n};\n/** The meter `meterReads` gave `database`, if it did. */\nconst readMeterOf = (database) => typeof database === \"object\" && database !== null ? database[METER] : void 0;\n/**\n* `database` with read metering, for adapter cost analysis: pass it to\n* `createHotUpdater` or `createEngine`, then `measureReads` reports what a\n* call read at the adapter and at the engine. It works on any database on\n* the storage engine, a provider's included, and every engine on it reports\n* to the same meter.\n*/\nconst meterReads = (database) => {\n\tlet adapterReads = NO_READS;\n\tconst engines = /* @__PURE__ */ new Set();\n\tconst add = (count) => {\n\t\tadapterReads = {\n\t\t\tgets: adapterReads.gets + (count.gets ?? 0),\n\t\t\tkeys: adapterReads.keys + (count.keys ?? 0),\n\t\t\tqueries: adapterReads.queries + (count.queries ?? 0),\n\t\t\trows: adapterReads.rows + (count.rows ?? 0)\n\t\t};\n\t};\n\tconst meter = {\n\t\twrap: (adapter) => Object.assign(Object.create(adapter), {\n\t\t\tasync get(...args) {\n\t\t\t\tconst rows = await adapter.get(...args);\n\t\t\t\tadd({\n\t\t\t\t\tgets: 1,\n\t\t\t\t\tkeys: args[1].length\n\t\t\t\t});\n\t\t\t\treturn rows;\n\t\t\t},\n\t\t\tasync query(...args) {\n\t\t\t\tconst rows = await adapter.query(...args);\n\t\t\t\tadd({\n\t\t\t\t\tqueries: 1,\n\t\t\t\t\trows: rows.length\n\t\t\t\t});\n\t\t\t\treturn rows;\n\t\t\t}\n\t\t}),\n\t\tattach: (counter) => {\n\t\t\tengines.add(counter);\n\t\t}\n\t};\n\treturn {\n\t\t...database,\n\t\t[METER]: meter,\n\t\tasync measureReads(read) {\n\t\t\tadapterReads = NO_READS;\n\t\t\tfor (const engine of engines) engine.reset();\n\t\t\tconst result = await read();\n\t\t\tlet engine = {\n\t\t\t\tcalls: 0,\n\t\t\t\trows: 0\n\t\t\t};\n\t\t\tfor (const counter of engines) {\n\t\t\t\tconst total = counter.total();\n\t\t\t\tengine = {\n\t\t\t\t\tcalls: engine.calls + total.calls,\n\t\t\t\t\trows: engine.rows + total.rows\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult,\n\t\t\t\tadapter: adapterReads,\n\t\t\t\tengine\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { meterReads, readMeterOf };\n", "import { SETTINGS_TABLE, readSettings } from \"../database/fence.mjs\";\n//#region src/engine/db/schemaSettings.ts\nconst storedSettings = async (adapter, keys) => {\n\tconst rows = await readSettings(adapter, keys);\n\treturn new Map(keys.map((key, position) => [key, rows[position] ?? null]));\n};\n/** Writes the settings rows after every table exists. */\nconst writeSchemaSettings = async (adapter, adapterName, settings) => {\n\tconst stored = await storedSettings(adapter, Object.keys(settings));\n\tconst ops = Object.entries(settings).flatMap(([key, value]) => {\n\t\tconst row = stored.get(key);\n\t\tif (row === null || row === void 0) return [{\n\t\t\ttype: \"insert\",\n\t\t\ttable: SETTINGS_TABLE,\n\t\t\trow: {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\t_v: 0\n\t\t\t}\n\t\t}];\n\t\tif (row.value === value) return [];\n\t\treturn [{\n\t\t\ttype: \"patch\",\n\t\t\ttable: SETTINGS_TABLE,\n\t\t\tkey: [key],\n\t\t\tset: { value },\n\t\t\tguard: { v: Number(row._v) },\n\t\t\tprevious: row\n\t\t}];\n\t});\n\tif (ops.length === 0) return;\n\tif (!(await adapter.write(ops)).ok) throw new Error(`${adapterName}: the schema settings changed during the migration; run it again.`);\n};\n/** Creates or updates every table, then writes the settings rows last. */\nconst migrateSchema = async (adapter, adapterName, tables, settings) => {\n\tif (adapter.migrations === void 0) throw new Error(`${adapterName} creates its tables with its own tooling; write only the settings rows.`);\n\tawait adapter.migrations.apply([...tables, SETTINGS_TABLE]);\n\tawait writeSchemaSettings(adapter, adapterName, settings);\n};\n//#endregion\nexport { migrateSchema, writeSchemaSettings };\n", "import { DatabaseSchemaError, findPhysicalColumn, indexOrderColumns } from \"../../../database/adapter.mjs\";\n//#region src/engine/database/sql/sqlSchema.ts\n/**\n* Quotes an identifier: backticks on MySQL, double quotes elsewhere. An ORM\n* schema generator, or an executor that issues statements of its own, quotes\n* names as the SQL core does with it, as the Prisma adapter's do.\n*/\nconst quoteSql = (dialect, name) => dialect === \"mysql\" ? `\\`${name.replaceAll(\"`\", \"``\")}\\`` : `\"${name.replaceAll(\"\\\"\", \"\\\"\\\"\")}\"`;\nconst isMultiIndex = (table, index) => index.eq.some((column) => findPhysicalColumn(table, column).multi);\n/** Keeps an identifier within PostgreSQL's 63 and MySQL's 64 characters. */\nconst shortSqlName = (name) => {\n\tif (name.length <= 60) return name;\n\tlet hash = 2166136261;\n\tfor (const char of name) hash = Math.imul(hash ^ char.charCodeAt(0), 16777619) >>> 0;\n\treturn `${name.slice(0, 51)}_${hash.toString(36)}`;\n};\n/** The column type; `entry` types one value of a multi-valued column in its index table. */\nconst columnType = (dialect, column, indexed, entry = false) => {\n\tif (column.multi && !entry || column.type === \"json\") return {\n\t\tpostgresql: \"jsonb\",\n\t\tmysql: \"json\",\n\t\tsqlite: \"TEXT\"\n\t}[dialect];\n\tif (column.type === \"string\") {\n\t\tconst length = column.maxLength ?? (indexed ? 255 : void 0);\n\t\tif (dialect === \"sqlite\") return \"TEXT\";\n\t\tif (dialect === \"postgresql\") return `${column.maxLength ? `varchar(${column.maxLength})` : \"text\"} COLLATE \"C\"`;\n\t\tconst charset = column.ascii ? \"ascii COLLATE ascii_bin\" : \"utf8mb4 COLLATE utf8mb4_0900_bin\";\n\t\treturn `${length ? `varchar(${length})` : \"longtext\"} CHARACTER SET ${charset}`;\n\t}\n\tif (column.type === \"integer\") return dialect === \"sqlite\" ? \"INTEGER\" : \"bigint\";\n\tif (column.type === \"number\") return {\n\t\tpostgresql: \"double precision\",\n\t\tmysql: \"double\",\n\t\tsqlite: \"REAL\"\n\t}[dialect];\n\treturn dialect === \"sqlite\" ? \"INTEGER\" : \"boolean\";\n};\n/** InnoDB's limit on the bytes of one key or index. */\nconst MYSQL_KEY_BYTES = 3072;\n/** Refuses a MySQL key or index over InnoDB's limit before any DDL runs. */\nconst checkMysqlKey = (table, name, columns) => {\n\tconst bytes = columns.reduce((sum, column) => {\n\t\tconst { type, maxLength, ascii } = findPhysicalColumn(table, column);\n\t\tif (type === \"string\") return sum + (maxLength ?? 255) * (ascii ? 1 : 4);\n\t\treturn sum + (type === \"boolean\" ? 1 : 8);\n\t}, 0);\n\tif (bytes > MYSQL_KEY_BYTES) throw new DatabaseSchemaError(`${table.name} ${name} needs ${bytes} bytes on MySQL, over its ${MYSQL_KEY_BYTES}; shorten its strings or mark ASCII ones ascii.`);\n};\n/**\n* Each table as the DDL creates it, for the DDL below and for ORM schema\n* generators, such as the Drizzle and Prisma adapters': binary collation, one index per declared index, and an index\n* table `<table>__<index>` for each index over a multi-valued field, keyed by\n* every column it holds.\n*/\nconst sqlTableShapes = (dialect, tables, tablePrefix = \"\") => tables.map((table) => {\n\tconst name = tablePrefix + table.name;\n\tconst indexed = /* @__PURE__ */ new Set([...table.key, ...table.indexes.flatMap(({ eq, sort }) => [...eq, ...sort])]);\n\tif (dialect === \"mysql\") checkMysqlKey(table, \"key\", table.key);\n\tconst indexes = table.indexes.flatMap((index) => {\n\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\tif (dialect === \"mysql\") checkMysqlKey(table, `index ${index.name}`, columns);\n\t\tif (isMultiIndex(table, index)) {\n\t\t\tconst entries = columns.map((column) => ({\n\t\t\t\tname: column,\n\t\t\t\ttype: columnType(dialect, findPhysicalColumn(table, column), true, true),\n\t\t\t\tnotNull: true\n\t\t\t}));\n\t\t\treturn [{\n\t\t\t\tkind: \"table\",\n\t\t\t\ttable: {\n\t\t\t\t\tname: `${name}__${index.name}`,\n\t\t\t\t\tcolumns: entries,\n\t\t\t\t\tkey: columns,\n\t\t\t\t\tindexes: []\n\t\t\t\t}\n\t\t\t}];\n\t\t}\n\t\tif (!index.unique && columns.join() === table.key.join()) return [];\n\t\treturn [{\n\t\t\tkind: \"index\",\n\t\t\tname: shortSqlName(`${name}_${index.name}`),\n\t\t\tunique: index.unique === true,\n\t\t\tcolumns: index.unique ? index.eq : columns\n\t\t}];\n\t});\n\tconst retention = table.retention && retentionOrder(table);\n\tif (retention && !retention.indexed) indexes.push({\n\t\tkind: \"index\",\n\t\tname: shortSqlName(`${name}__retention`),\n\t\tunique: false,\n\t\tcolumns: retention.columns\n\t});\n\treturn {\n\t\tname,\n\t\tcolumns: table.columns.map((column) => ({\n\t\t\tname: column.name,\n\t\t\ttype: columnType(dialect, column, indexed.has(column.name)),\n\t\t\tnotNull: !column.nullable,\n\t\t\t...column.default === void 0 ? {} : { default: column.default }\n\t\t})),\n\t\tkey: table.key,\n\t\tindexes\n\t};\n});\n/** DDL for the tables' shapes: each table, then its indexes and index tables. */\nconst createTableStatements = (dialect, tables, tablePrefix = \"\") => {\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst list = (columns) => columns.map(quote).join(\", \");\n\tconst render = (shape) => {\n\t\tconst definitions = shape.columns.map((column) => `${quote(column.name)} ${column.type}${column.notNull ? \" NOT NULL\" : \"\"}${column.default === void 0 ? \"\" : ` DEFAULT ${column.default}`}`);\n\t\tdefinitions.push(`PRIMARY KEY (${list(shape.key)})`);\n\t\tconst after = [];\n\t\tfor (const index of shape.indexes) if (index.kind === \"table\") after.push(...render(index.table));\n\t\telse if (dialect === \"mysql\") definitions.push(`${index.unique ? \"UNIQUE \" : \"\"}INDEX ${quote(index.name)} (${list(index.columns)})`);\n\t\telse after.push(`CREATE ${index.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${quote(index.name)} ON ${quote(shape.name)} (${list(index.columns)})`);\n\t\treturn [`CREATE TABLE IF NOT EXISTS ${quote(shape.name)} (${definitions.join(\", \")})`, ...after];\n\t};\n\treturn sqlTableShapes(dialect, tables, tablePrefix).flatMap(render);\n};\n/**\n* The order a prune walks a table's expired rows in, which ends with the\n* key so it is total: the columns of the first index that leads with the\n* retention column, or the key when it does, or else the column and the\n* key, which then need an index of their own (`indexed` false).\n*/\nconst retentionOrder = (table) => {\n\tconst { column } = table.retention;\n\tfor (const index of table.indexes) {\n\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\tif (!index.unique && !isMultiIndex(table, index) && columns[0] === column) return {\n\t\t\tcolumns,\n\t\t\tindexed: true\n\t\t};\n\t}\n\tif (table.key[0] === column) return {\n\t\tcolumns: table.key,\n\t\tindexed: true\n\t};\n\treturn {\n\t\tcolumns: [column, ...table.key.filter((field) => field !== column)],\n\t\tindexed: false\n\t};\n};\n/**\n* The statements that delete up to `limit` expired rows of a table with\n* retention, oldest first in {@link retentionOrder}: its multi-valued index\n* entries, then the rows, which a concurrent write that moved the retention\n* column past `before` keeps. `before` renders the bound each time it\n* appears. MySQL deletes with ORDER BY and LIMIT. Elsewhere the cutoff is\n* the last of the `limit` oldest expired rows in that order, a row value\n* the index ranges over, and the shapes pass Supabase's apply RPC: no IN, no\n* AS, aliases `i` and `b`.\n*/\nconst pruneStatements = (dialect, table, tablePrefix, limit) => {\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst name = quote(`${tablePrefix}${table.name}`);\n\tconst at = quote(table.retention.column);\n\tconst order = retentionOrder(table).columns.map(quote);\n\tconst list = (alias, direction = \"\") => order.map((column) => `${alias}.${column}${direction}`).join(\", \");\n\tconst oldest = (before) => `SELECT ${list(\"i\")} FROM ${name} i WHERE i.${at} <= ${before()} ORDER BY ${list(\"i\", \" ASC\")} LIMIT ${limit}`;\n\tconst doomed = (alias, before) => `${alias}.${at} <= ${before()} AND (${list(alias)}) <= (SELECT ${list(\"b\")} FROM (${oldest(before)}) b ORDER BY ${list(\"b\", \" DESC\")} LIMIT 1)`;\n\tconst entries = table.indexes.filter((index) => isMultiIndex(table, index)).map((index) => quote(`${tablePrefix}${table.name}__${index.name}`));\n\tconst keyOf = (left, right) => table.key.map((column) => `${left}.${quote(column)} = ${right}.${quote(column)}`).join(\" AND \");\n\tif (dialect === \"mysql\") return [...entries.map((index) => (before) => `DELETE e FROM ${index} e JOIN (${oldest(before)}) d ON ${keyOf(\"e\", \"d\")}`), (before) => `DELETE FROM ${name} WHERE ${at} <= ${before()} ORDER BY ${order.join(\", \")} LIMIT ${limit}`];\n\treturn [...entries.map((index) => (before) => `DELETE FROM ${index} WHERE EXISTS (SELECT * FROM ${name} b WHERE ${keyOf(\"b\", index)} AND ${doomed(\"b\", before)})`), (before) => `DELETE FROM ${name} WHERE ${doomed(name, before)}`];\n};\n//#endregion\nexport { createTableStatements, isMultiIndex, pruneStatements, quoteSql, retentionOrder, shortSqlName, sqlTableShapes };\n", "import { defineAggregate, defineTable } from \"../../serverPlugin/schema.mjs\";\n//#region src/engine/core/schema.ts\n/** A channel's id is `channel:` and its name's channel key, so ids share channel_key's bound. */\nconst CHANNEL_ID = {\n\ttype: \"string\",\n\tmaxLength: 1408,\n\tascii: true\n};\n/** Core's schema version: the `schema.core` settings row. */\nconst HOT_UPDATER_SCHEMA_VERSION = \"1.0.0\";\nconst coreSchema = {\n\tbundles: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tgit_commit_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tmetadata: { type: \"json\" },\n\t\tmanifest_storage_uri: { type: \"string\" },\n\t\tmanifest_file_hash: { type: \"string\" },\n\t\tasset_base_storage_uri: { type: \"string\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tbyPlatform: {\n\t\t\t\teq: [\"platform\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tall: {\n\t\t\t\teq: [],\n\t\t\t\tsort: [\"id\"]\n\t\t\t}\n\t\t}\n\t}),\n\tbundle_patches: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255\n\t\t},\n\t\tbundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"cascade\"\n\t\t\t}\n\t\t},\n\t\tbase_bundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"cascade\"\n\t\t\t}\n\t\t},\n\t\tbase_file_hash: { type: \"string\" },\n\t\tpatch_file_hash: { type: \"string\" },\n\t\tpatch_storage_uri: { type: \"string\" },\n\t\tbyte_size: { type: \"integer\" },\n\t\torder_index: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tpair: {\n\t\t\t\teq: [\"bundle_id\", \"base_bundle_id\"],\n\t\t\t\tsort: [],\n\t\t\t\tunique: true\n\t\t\t},\n\t\t\tbyBundle: {\n\t\t\t\teq: [\"bundle_id\"],\n\t\t\t\tsort: [\"order_index\"],\n\t\t\t\troot: { model: \"bundles\" }\n\t\t\t},\n\t\t\tbyBase: {\n\t\t\t\teq: [\"base_bundle_id\"],\n\t\t\t\tsort: [\"bundle_id\"]\n\t\t\t}\n\t\t}\n\t}),\n\treleases: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36\n\t\t},\n\t\trevision: { type: \"integer\" },\n\t\tscope_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 2048,\n\t\t\tascii: true\n\t\t},\n\t\tchannel_id: {\n\t\t\t...CHANNEL_ID,\n\t\t\treferences: {\n\t\t\t\tmodel: \"channels\",\n\t\t\t\tonDelete: \"restrict\"\n\t\t\t}\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tkind: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tbundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\trequired: false,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"restrict\"\n\t\t\t}\n\t\t},\n\t\tstrategy: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\ttarget_app_version: {\n\t\t\ttype: \"string\",\n\t\t\trequired: false\n\t\t},\n\t\tfingerprint_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tenabled: { type: \"boolean\" },\n\t\tshould_force_update: { type: \"boolean\" },\n\t\tmessage: {\n\t\t\ttype: \"string\",\n\t\t\trequired: false\n\t\t},\n\t\trollout_cohort_count: { type: \"integer\" },\n\t\ttarget_cohorts: { type: \"json\" },\n\t\toperation: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tsource_release_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\trequired: false,\n\t\t\treferences: {\n\t\t\t\tmodel: \"releases\",\n\t\t\t\tonDelete: \"none\"\n\t\t\t}\n\t\t},\n\t\tcreated_at_ms: { type: \"integer\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tbyScope: {\n\t\t\t\teq: [\"scope_key\"],\n\t\t\t\tsort: [\"id\"],\n\t\t\t\troot: { model: \"release_catalogs\" }\n\t\t\t},\n\t\t\tbyScopeEnabled: {\n\t\t\t\teq: [\"scope_key\", \"enabled\"],\n\t\t\t\tsort: [\"id\"],\n\t\t\t\troot: { model: \"release_catalogs\" }\n\t\t\t},\n\t\t\tbyChannelPlatform: {\n\t\t\t\teq: [\"channel_id\", \"platform\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tbyChannelPlatformEnabled: {\n\t\t\t\teq: [\n\t\t\t\t\t\"channel_id\",\n\t\t\t\t\t\"platform\",\n\t\t\t\t\t\"enabled\"\n\t\t\t\t],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tbyBundle: {\n\t\t\t\teq: [\"bundle_id\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tall: {\n\t\t\t\teq: [],\n\t\t\t\tsort: [\"id\"]\n\t\t\t}\n\t\t}\n\t}),\n\trelease_catalogs: defineTable({\n\t\tscope_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 2048,\n\t\t\tascii: true\n\t\t},\n\t\tcatalog_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255\n\t\t},\n\t\tstrategy: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tchannel_id: {\n\t\t\t...CHANNEL_ID,\n\t\t\treferences: {\n\t\t\t\tmodel: \"channels\",\n\t\t\t\tonDelete: \"none\"\n\t\t\t}\n\t\t},\n\t\tchannel_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 1400,\n\t\t\tascii: true\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tfingerprint_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tgeneration: { type: \"integer\" },\n\t\tpayload: { type: \"string\" },\n\t\tcatalog_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 71\n\t\t},\n\t\tbyte_size: { type: \"integer\" },\n\t\tis_tombstone: { type: \"boolean\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"scope_key\"],\n\t\tindexes: { all: {\n\t\t\teq: [],\n\t\t\tsort: [\"scope_key\"]\n\t\t} }\n\t}),\n\tchannels: defineTable({\n\t\tid: CHANNEL_ID,\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\tunique: true\n\t\t}\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: { all: {\n\t\t\teq: [],\n\t\t\tsort: [\"name\"]\n\t\t} }\n\t}),\n\tbundle_totals: defineAggregate({ platform_key: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t} }, {\n\t\tkey: [\"platform_key\"],\n\t\tcounters: [\"bundles\"],\n\t\tindexes: { byPlatform: {\n\t\t\teq: [\"platform_key\"],\n\t\t\tsort: []\n\t\t} }\n\t})\n};\n/** Core's module: always installed, never a plugin. */\nconst coreModule = {\n\tid: \"core\",\n\tschema: coreSchema\n};\n//#endregion\nexport { HOT_UPDATER_SCHEMA_VERSION, coreModule, coreSchema };\n", "//#region src/engine/db/fixedMigratorShared.ts\nconst getEmptyMigrationResult = () => ({\n\toperations: [],\n\texecute: async () => {},\n\tgetSQL: () => \"\"\n});\n//#endregion\nexport { getEmptyMigrationResult };\n", "import { HOT_UPDATER_SCHEMA_VERSION } from \"../core/schema.mjs\";\nimport { HotUpdaterSchemaMigrationRequiredError, SETTINGS_TABLE, isMissingSchemaError } from \"../database/fence.mjs\";\nimport { getEmptyMigrationResult } from \"./fixedMigratorShared.mjs\";\nimport { quoteSql } from \"../database/sql/sqlSchema.mjs\";\nimport { settingsStatements } from \"./engineSql.mjs\";\n//#region src/engine/db/settingsMigrator.ts\n/**\n* Every settings row by key and value alone, so a v0 layout reads too; null\n* when the settings table is missing.\n*/\nconst readStoredSettings = async (executor, tablePrefix = \"\") => {\n\tconst quote = (name) => quoteSql(executor.dialect, name);\n\ttry {\n\t\tconst { rows } = await executor.execute({\n\t\t\tsql: `SELECT ${quote(\"key\")}, ${quote(\"value\")} FROM ${quote(tablePrefix + SETTINGS_TABLE.name)}`,\n\t\t\tparams: []\n\t\t});\n\t\treturn new Map(rows.map((row) => [String(row.key), row.value]));\n\t} catch (error) {\n\t\tif (!isMissingSchemaError(error)) throw error;\n\t\treturn null;\n\t}\n};\n/** `schema.core`, or a v0 database's `version`. */\nconst storedSchemaVersion = (stored) => {\n\tconst version = stored?.get(\"schema.core\") ?? stored?.get(\"version\");\n\treturn typeof version === \"string\" ? version : void 0;\n};\n/**\n* A v0 database, whose settings hold `version` and no `schema.engine`, is\n* recreated, never converted.\n*/\nconst refuseV0Database = (adapterName, stored) => {\n\tconst version = stored.get(\"version\");\n\tif (typeof version !== \"string\" || stored.has(\"schema.engine\")) return;\n\tthrow new HotUpdaterSchemaMigrationRequiredError(adapterName, version);\n};\n/**\n* `hot-updater db migrate` for an ORM that applies the DDL itself (Drizzle,\n* Prisma): it sets what the ORM cannot declare, writes the settings rows, and\n* refuses a v0 database. The `createMigrator` of an adapter whose ORM\n* creates the tables returns it, as the Drizzle and Prisma adapters' do.\n*/\nconst createSettingsMigrator = (options) => {\n\tconst read = () => readStoredSettings(options.executor);\n\tconst getVersion = async () => storedSchemaVersion(await read());\n\tconst makeResult = async (migrate = {}) => {\n\t\tconst stored = await read();\n\t\tif (stored === null) throw new Error(`${options.adapterName}: the Hot Updater tables are missing. Run \\`hot-updater db generate\\`, apply the schema with ${options.applyTables}, then migrate again.`);\n\t\trefuseV0Database(options.adapterName, stored);\n\t\tif (migrate.updateSettings === false || Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();\n\t\tconst fixups = options.fixups?.statements ?? [];\n\t\tconst statements = [...fixups, ...settingsStatements(options.executor.dialect, options.settings)];\n\t\treturn {\n\t\t\toperations: [...fixups.length === 0 ? [] : [{\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: options.fixups.description\n\t\t\t}], {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: `Write the schema settings: ${Object.keys(options.settings).join(\", \")}`\n\t\t\t}],\n\t\t\tgetSQL: () => statements.map((statement) => `${statement};`).join(\"\\n\\n\"),\n\t\t\texecute: async () => {\n\t\t\t\tfor (const sql of statements) await options.executor.execute({\n\t\t\t\t\tsql,\n\t\t\t\t\tparams: []\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t};\n\treturn {\n\t\tgetVersion,\n\t\tgetNameVariants: async () => void 0,\n\t\tnext: async () => await getVersion() === \"1.0.0\" ? void 0 : { version: HOT_UPDATER_SCHEMA_VERSION },\n\t\tprevious: async () => void 0,\n\t\tup: makeResult,\n\t\tdown: async () => {\n\t\t\tthrow new Error(\"No previous schema to migrate to.\");\n\t\t},\n\t\tmigrateTo: async (version, migrate) => {\n\t\t\tif (version !== \"1.0.0\") throw new Error(`Invalid version ${version}`);\n\t\t\treturn makeResult(migrate);\n\t\t},\n\t\tmigrateToLatest: makeResult\n\t};\n};\n//#endregion\nexport { createSettingsMigrator, readStoredSettings, refuseV0Database, storedSchemaVersion };\n", "import { DatabaseCursorError } from \"../../serverPlugin/errors.mjs\";\nimport { isKeyValue } from \"../../database/values.mjs\";\n//#region src/engine/database/cursor.ts\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\nconst toBase64Url = (text) => {\n\tlet binary = \"\";\n\tfor (const byte of encoder.encode(text)) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst fromBase64Url = (value) => {\n\tconst binary = atob(value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\"));\n\treturn decoder.decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));\n};\n/** A stable 32-bit FNV-1a hash of the text's UTF-8 bytes. */\nconst fnv1a = (text) => {\n\tlet hash = 2166136261;\n\tfor (const byte of encoder.encode(text)) hash = Math.imul(hash ^ byte, 16777619) >>> 0;\n\treturn hash;\n};\n/** A hash of the request's identity; a cursor only resumes the same read. */\nconst cursorScope = (parts) => fnv1a(JSON.stringify(parts)).toString(36);\nconst encodeCursor = (scope, after) => toBase64Url(JSON.stringify([scope, after]));\n/** The order tuple a cursor resumes after; rejects a cursor from another read. */\nconst decodeCursor = (scope, cursor) => {\n\tlet decoded;\n\ttry {\n\t\tdecoded = JSON.parse(fromBase64Url(cursor));\n\t} catch {\n\t\tdecoded = void 0;\n\t}\n\tconst [from, after] = Array.isArray(decoded) ? decoded : [];\n\tif (typeof from !== \"string\" || !Array.isArray(after) || !after.every(isKeyValue)) throw new DatabaseCursorError(\"The cursor is malformed.\");\n\tif (from !== scope) throw new DatabaseCursorError(\"The cursor belongs to a read with another model, index, filter, order, or range.\");\n\treturn after;\n};\n//#endregion\nexport { DatabaseCursorError, cursorScope, decodeCursor, encodeCursor, fnv1a };\n", "import { DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport { mergeDistinct } from \"../../database/distinct.mjs\";\nimport \"../../database/adapter.mjs\";\nimport { isKeyValue } from \"../../database/values.mjs\";\nimport { fnv1a } from \"./cursor.mjs\";\n//#region src/engine/database/engineAggregates.ts\nconst definitionOf = (model) => model.definition;\n/** Every change keyed by one value lands on one shard. */\nconst shardOf = (value, shards) => fnv1a(value) % shards;\n/** Merges one `tx.aggregate` call into its shard row's pending changes. */\nconst recordAggregate = (changes, model, identity, values, shardBy) => {\n\tconst { key: fields, counters, gauges, distinct, shards } = definitionOf(model);\n\tconst fail = (message) => new DatabaseTransactionError(`${model.table.name}: ${message}`);\n\tif (Object.keys(identity).length !== fields.length || !fields.every((name) => isKeyValue(identity[name]))) throw fail(`aggregate takes exactly its identity fields: ${fields.join(\", \")}.`);\n\tif (shardBy === void 0 && shards > 1 && gauges.some((gauge) => gauge in values)) throw fail(\"gauges of a sharded aggregate need shardBy.\");\n\tconst shard = shardBy === void 0 ? Math.floor(Math.random() * shards) : shardOf(shardBy, shards);\n\tconst key = [...fields.map((name) => identity[name]), shard];\n\tconst id = JSON.stringify([model.table.name, key]);\n\tconst change = changes.get(id) ?? {\n\t\tmodel,\n\t\tkey,\n\t\tdeltas: {},\n\t\tsketches: {}\n\t};\n\tchanges.set(id, change);\n\tfor (const [metric, value] of Object.entries(values)) if (distinct.includes(metric) && typeof value === \"string\") change.sketches[metric] = mergeDistinct([change.sketches[metric], value]);\n\telse if ((counters.includes(metric) || gauges.includes(metric)) && Number.isSafeInteger(value)) change.deltas[metric] = (change.deltas[metric] ?? 0) + Number(value);\n\telse throw fail(`${metric} is not a counter, gauge, or sketch of this aggregate.`);\n};\n/** A shard row before its first change: every metric zero or empty. */\nconst blank = (model, key) => {\n\tconst { counters, gauges, distinct } = definitionOf(model);\n\treturn Object.fromEntries([\n\t\t...model.table.key.map((column, position) => [column, key[position]]),\n\t\t...[...counters, ...gauges].map((name) => [name, 0]),\n\t\t...distinct.map((name) => [name, null]),\n\t\t[\"_v\", 0]\n\t]);\n};\n/**\n* A gauge computed below zero. Deltas from a row another writer has since\n* moved do this, so the transaction reruns; it is thrown only when it lasts.\n*/\nvar NegativeGaugeError = class extends DatabaseTransactionError {};\n/** The guarded write that merges `change` into `current`: insert, patch, or delete at zero. */\nconst rewrite = ({ model, key, deltas, sketches }, current) => {\n\tconst { table } = model;\n\tconst { counters, gauges, distinct } = definitionOf(model);\n\tconst base = current ?? blank(model, key);\n\tconst set = {};\n\tfor (const [metric, delta] of Object.entries(deltas)) set[metric] = Number(base[metric] ?? 0) + delta;\n\tfor (const [metric, sketch] of Object.entries(sketches)) set[metric] = mergeDistinct([base[metric], sketch]);\n\tif (current && Object.entries(set).every(([metric, value]) => current[metric] === value)) return;\n\tconst row = {\n\t\t...base,\n\t\t...set\n\t};\n\tif (gauges.some((gauge) => Number(row[gauge]) < 0)) {\n\t\tif (current === null && table.retention) return void 0;\n\t\tthrow new NegativeGaugeError(`${table.name}: a gauge went below 0.`);\n\t}\n\tconst zero = distinct.length === 0 && [...counters, ...gauges].every((metric) => Number(row[metric]) === 0);\n\tif (current === null) return zero ? void 0 : {\n\t\ttype: \"insert\",\n\t\ttable,\n\t\trow\n\t};\n\tconst guard = { v: Number(current[\"_v\"]) };\n\treturn zero ? {\n\t\ttype: \"delete\",\n\t\ttable,\n\t\tkey,\n\t\tguard,\n\t\tprevious: current\n\t} : {\n\t\ttype: \"patch\",\n\t\ttable,\n\t\tkey,\n\t\tset,\n\t\tguard,\n\t\tprevious: current\n\t};\n};\n/**\n* Counter-only rows become blind increments that create the row when it is\n* missing. Rows with gauges or sketches are read in one parallel batch per\n* table, merged, and written back under a guard, so a conflict resends only\n* them.\n*/\nconst compileAggregates = async (adapter, changes) => {\n\tconst ops = [];\n\tconst merged = /* @__PURE__ */ new Map();\n\tfor (const change of changes) {\n\t\tconst { model, key, deltas, sketches } = change;\n\t\tif (Object.keys(sketches).length > 0 || definitionOf(model).gauges.some((gauge) => (deltas[gauge] ?? 0) !== 0)) merged.set(model, [...merged.get(model) ?? [], change]);\n\t\telse if (Object.values(deltas).some((delta) => delta !== 0)) {\n\t\t\tconst { table } = model;\n\t\t\tconst init = blank(model, key);\n\t\t\tops.push({\n\t\t\t\ttype: \"increment\",\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tby: deltas,\n\t\t\t\tinit\n\t\t\t});\n\t\t}\n\t}\n\tconst groups = [...merged.values()];\n\tconst current = await Promise.all(groups.map((group) => adapter.get(group[0].model.table, group.map(({ key }) => key))));\n\tgroups.forEach((group, index) => group.forEach((change, position) => {\n\t\tconst op = rewrite(change, current[index][position] ?? null);\n\t\tif (op !== void 0) ops.push(op);\n\t}));\n\treturn ops;\n};\n//#endregion\nexport { NegativeGaugeError, compileAggregates, recordAggregate, shardOf };\n", "import { defineTable } from \"../../serverPlugin/schema.mjs\";\nimport { DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport \"../../database/adapter.mjs\";\nimport { compareUtf8 } from \"../../database/values.mjs\";\nimport { recordAggregate } from \"./engineAggregates.mjs\";\n//#region src/engine/database/aggregateBatching.ts\n/** Log rows spread over 8 tables, each its own DynamoDB partition. */\nconst LOG_TABLES = [\n\t0,\n\t1,\n\t2,\n\t3,\n\t4,\n\t5,\n\t6,\n\t7\n].map((at) => `aggregate_log_${at}`);\nconst LEASE_TABLE = \"aggregate_lease\";\nconst LEASE = { id: \"compaction\" };\n/** How long a compaction holds the lease before another process may take it. */\nconst LEASE_MS = 3e4;\n/**\n* Default windows: log mode compacts every 60 seconds, since reads compact\n* first; memory mode flushes every 15, since its window is what a crash\n* loses.\n*/\nconst WINDOW_MS = {\n\tlog: 6e4,\n\tmemory: 15e3\n};\n/** Log rows a compaction reads from each log table for one group. */\nconst LOG_PAGE = 200;\n/**\n* Groups one compaction applies: after a commit, so the request that runs\n* it waits for one group; before a read; and on flush.\n*/\nconst GROUPS = {\n\tcommit: 1,\n\tread: 8,\n\tflush: 256\n};\n/** Tries per write after a conflict or a transient error. */\nconst ATTEMPTS = 5;\n/** Aggregate rows a memory buffer holds before a commit waits for a flush. */\nconst MAX_BUFFERED = 1e4;\nconst log = defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\t/** One committed transaction's changes, one entry per aggregate row. */\n\tchanges: { type: \"string\" }\n}, {\n\tkey: [\"id\"],\n\tindexes: { oldest: {\n\t\teq: [],\n\t\tsort: [\"id\"]\n\t} }\n});\n/**\n* Held by `holder` until `until`; the next compaction is due at `next`.\n* `applied` lists the log rows a compaction has applied and not yet deleted,\n* as `[log table's index, id]` pairs, so no compaction applies them again.\n*/\nconst lease = defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tholder: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tuntil: { type: \"integer\" },\n\tnext: { type: \"integer\" },\n\tapplied: { type: \"string\" }\n}, { key: [\"id\"] });\n/** The log and lease tables; an engine that batches has them in its schema. */\nconst aggregateBatchingModule = {\n\tid: \"aggregateBatching\",\n\tschema: {\n\t\t...Object.fromEntries(LOG_TABLES.map((table) => [table, log])),\n\t\t[LEASE_TABLE]: lease\n\t}\n};\nconst shapeOf = (model) => model.definition;\nconst isBatched = (model) => model?.definition.kind === \"aggregate\" && shapeOf(model).batched === true;\nconst valuesOf = ({ deltas, sketches }) => ({\n\t...deltas,\n\t...sketches\n});\n/**\n* Merges `values` into the change for `key`'s identity as `tx.aggregate`\n* does: deltas add up and sketches merge. One constant `shardBy` keys each\n* identity to one entry; the write picks the shard.\n*/\nconst merge = (into, model, key, values) => recordAggregate(into, model, Object.fromEntries(shapeOf(model).key.map((field, at) => [field, key[at]])), values, \"\");\nconst mergeAll = (into, changes) => {\n\tfor (const change of changes) merge(into, change.model, change.key, valuesOf(change));\n\treturn into;\n};\n/** A row's metrics as values to merge: counters, gauges, and the sketches it has. */\nconst metricsOf = (model, row) => {\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\treturn Object.fromEntries([...[...counters, ...gauges].map((name) => [name, Number(row[name] ?? 0)]), ...distinct.flatMap((name) => row[name] === null || row[name] === void 0 ? [] : [[name, row[name]]])]);\n};\n/** A shard row before its first change: every metric zero or empty. */\nconst blank = (model, key) => {\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\treturn Object.fromEntries([\n\t\t...model.table.key.map((column, at) => [column, key[at]]),\n\t\t...[...counters, ...gauges].map((name) => [name, 0]),\n\t\t...distinct.map((name) => [name, null]),\n\t\t[\"_v\", 0]\n\t]);\n};\n/** Whether a change needs its row: sketches merge, and a gauge may reach zero. */\nconst rewrites = ({ model, deltas, sketches }) => Object.keys(sketches).length > 0 || shapeOf(model).gauges.some((gauge) => (deltas[gauge] ?? 0) !== 0);\nconst increment = ({ model, deltas }, key) => Object.values(deltas).some((delta) => delta !== 0) ? {\n\ttype: \"increment\",\n\ttable: model.table,\n\tkey,\n\tby: deltas,\n\tinit: blank(model, key)\n} : void 0;\n/**\n* The guarded write that merges `change` into `current`: insert, patch, or\n* delete at zero. Unlike a transaction's, a gauge may go below zero here: a\n* shard row holds one writer's net changes, and reads sum every shard.\n*/\nconst rewrite = (change, key, current) => {\n\tconst { model } = change;\n\tconst { table } = model;\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\tconst base = current ?? blank(model, key);\n\tconst sum = mergeAll(/* @__PURE__ */ new Map(), [change]);\n\tmerge(sum, model, key, metricsOf(model, base));\n\tconst set = valuesOf([...sum.values()][0]);\n\tif (current && Object.keys(set).every((name) => current[name] === set[name])) return void 0;\n\tconst row = {\n\t\t...base,\n\t\t...set\n\t};\n\tconst zero = distinct.length === 0 && [...counters, ...gauges].every((name) => Number(row[name]) === 0);\n\tif (current === null) return zero ? void 0 : {\n\t\ttype: \"insert\",\n\t\ttable,\n\t\trow\n\t};\n\tconst guard = { v: Number(current[\"_v\"]) };\n\treturn zero ? {\n\t\ttype: \"delete\",\n\t\ttable,\n\t\tkey,\n\t\tguard,\n\t\tprevious: current\n\t} : {\n\t\ttype: \"patch\",\n\t\ttable,\n\t\tkey,\n\t\tset,\n\t\tguard,\n\t\tprevious: current\n\t};\n};\n/**\n* The write for each change on its shard: a blind increment that creates\n* the row for counters, and a guarded rewrite for gauges and sketches, whose\n* rows are read in one batch per table.\n*/\nconst compile = async (adapter, changes, shard) => {\n\tconst keys = changes.map(({ model, key }) => [...key.slice(0, -1), shard(model)]);\n\tconst reads = /* @__PURE__ */ new Map();\n\tchanges.forEach((change, at) => {\n\t\tif (rewrites(change)) reads.set(change.model, [...reads.get(change.model) ?? [], at]);\n\t});\n\tconst current = /* @__PURE__ */ new Map();\n\tawait Promise.all([...reads].map(async ([model, positions]) => {\n\t\tconst rows = await adapter.get(model.table, positions.map((at) => keys[at]));\n\t\tpositions.forEach((at, index) => current.set(at, rows[index] ?? null));\n\t}));\n\treturn changes.map((change, at) => current.has(at) ? rewrite(change, keys[at], current.get(at)) : increment(change, keys[at]));\n};\nconst isOp = (op) => op !== void 0;\nconst sleep = (attempt) => new Promise((resolve) => setTimeout(resolve, Math.min(250, 5 * 2 ** attempt) * Math.random()));\n/** Runs of one character, where shorter: a sparse sketch packs into a few. */\nconst pack = (text) => {\n\tconst runs = (text.match(/(.)\\1*/gsu) ?? []).flatMap((run) => [run[0], run.length]);\n\treturn JSON.stringify(runs).length < JSON.stringify(text).length ? runs : text;\n};\nconst unpack = (value) => Array.isArray(value) ? value.map((item, at) => at % 2 ? \"\" : item.repeat(value[at + 1])).join(\"\") : value;\n/** Raw deflate of `text` as base64, where the runtime has `CompressionStream`. */\nconst deflate = async (text) => {\n\tif (typeof CompressionStream === \"undefined\") return void 0;\n\tconst stream = new Blob([text]).stream().pipeThrough(new CompressionStream(\"deflate-raw\"));\n\tlet binary = \"\";\n\tfor (const byte of new Uint8Array(await new Response(stream).arrayBuffer())) binary += String.fromCharCode(byte);\n\treturn btoa(binary);\n};\nconst inflate = (base64) => new Response(new Blob([Uint8Array.from(atob(base64), (char) => char.charCodeAt(0))]).stream().pipeThrough(new DecompressionStream(\"deflate-raw\"))).text();\n/**\n* A log row's `changes`: entries of a table, an identity, and values, as\n* JSON, or `z` and its deflate where shorter, so a row stays under the 1 KB\n* that DynamoDB bills as one unit.\n*/\nconst encode = async (changes) => {\n\tconst json = JSON.stringify({\n\t\tv: 1,\n\t\tc: [...changes].map(({ model, key, deltas, sketches }) => {\n\t\t\tconst packed = Object.entries(sketches).map(([name, sketch]) => [name, pack(sketch)]);\n\t\t\tconst values = {\n\t\t\t\t...deltas,\n\t\t\t\t...Object.fromEntries(packed)\n\t\t\t};\n\t\t\treturn [\n\t\t\t\tmodel.table.name,\n\t\t\t\tkey.slice(0, -1),\n\t\t\t\tvalues\n\t\t\t];\n\t\t})\n\t});\n\tconst zipped = await deflate(json);\n\treturn zipped !== void 0 && zipped.length < json.length ? `z${zipped}` : json;\n};\n/**\n* Batches changes to aggregates declared `batched`. A transaction records\n* them without writing their rows; once it commits, \"memory\" mode keeps\n* them in this process until its timer flushes them, and \"log\" mode has\n* written them as one log row in the same atomic write, which a compaction\n* later merges into the aggregates and deletes, atomically again, so each\n* applies exactly once. One lease row keeps compactions one at a time.\n*/\nconst createAggregateBatches = ({ engine, adapter, schema, batching: { mode = \"log\", windowMs = WINDOW_MS[mode] }, now }) => {\n\tif (!schema.models.has(LEASE_TABLE)) throw new DatabaseTransactionError(\"An engine that batches aggregates needs aggregateBatchingModule in its schema.\");\n\tconst holder = crypto.randomUUID().replaceAll(\"-\", \"\");\n\tconst table = (name) => schema.models.get(name).table;\n\tconst warned = /* @__PURE__ */ new Set();\n\tconst warn = (what) => (error) => {\n\t\tif (warned.has(what)) return;\n\t\twarned.add(what);\n\t\tconsole.warn(`[hot-updater] Aggregate ${what} failed.`, error);\n\t};\n\t/** A log row's changes, or undefined when it names an aggregate or metric this schema lacks. */\n\tconst decode = async (text) => {\n\t\tconst changes = /* @__PURE__ */ new Map();\n\t\ttry {\n\t\t\tconst json = text.startsWith(\"z\") ? await inflate(text.slice(1)) : text;\n\t\t\tconst { c } = JSON.parse(json);\n\t\t\tfor (const [name, identity, values] of c) {\n\t\t\t\tconst model = schema.models.get(name);\n\t\t\t\tif (!isBatched(model)) return void 0;\n\t\t\t\tconst unpacked = Object.entries(values).map(([metric, value]) => [metric, unpack(value)]);\n\t\t\t\tmerge(changes, model, [...identity, 0], Object.fromEntries(unpacked));\n\t\t\t}\n\t\t} catch (error) {\n\t\t\twarn(\"log decoding\")(error);\n\t\t\treturn;\n\t\t}\n\t\treturn changes;\n\t};\n\t/**\n\t* Writes changes in atomic chunks within `fits`, and returns the ones it\n\t* could not apply. A write whose outcome is unknown is dropped, never\n\t* resent, so no change applies twice.\n\t*/\n\tconst apply = async (changes, shard) => {\n\t\tlet rest = changes;\n\t\tlet ops = [];\n\t\tlet read = true;\n\t\tfor (let failures = 0; rest.length > 0 && failures < ATTEMPTS;) try {\n\t\t\tif (read) ops = await compile(adapter, rest, shard);\n\t\t\tlet size = rest.length;\n\t\t\tconst chunk = () => ops.slice(0, size).filter(isOp);\n\t\t\twhile (size > 1 && !adapter.fits(chunk())) size = Math.ceil(size / 2);\n\t\t\tlet result = { ok: true };\n\t\t\tif (chunk().length > 0) result = await adapter.write(chunk()).catch((error) => {\n\t\t\t\twarn(\"flush\")(error);\n\t\t\t\treturn { ok: true };\n\t\t\t});\n\t\t\tread = !result.ok && !(\"retry\" in result);\n\t\t\tif (result.ok) {\n\t\t\t\trest = rest.slice(size);\n\t\t\t\tops = ops.slice(size);\n\t\t\t\tfailures = 0;\n\t\t\t} else {\n\t\t\t\tfailures += 1;\n\t\t\t\tif (!read) await sleep(failures);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\twarn(\"flush\")(error);\n\t\t\treturn rest;\n\t\t}\n\t\treturn rest;\n\t};\n\tlet buffer = /* @__PURE__ */ new Map();\n\tlet timer;\n\tlet flushing;\n\tconst shards = /* @__PURE__ */ new Map();\n\t/** Each process writes its own shard, so flushes of two processes rarely meet. */\n\tconst processShard = (model) => {\n\t\tif (!shards.has(model)) shards.set(model, Math.floor(Math.random() * shapeOf(model).shards));\n\t\treturn shards.get(model);\n\t};\n\tconst schedule = () => {\n\t\tif (timer !== void 0 || buffer.size === 0) return;\n\t\ttimer = setTimeout(() => {\n\t\t\ttimer = void 0;\n\t\t\tflushBuffer();\n\t\t}, windowMs);\n\t\ttimer.unref?.();\n\t};\n\t/** Never rejects: what it cannot apply goes back into the buffer. */\n\tconst flushBuffer = () => flushing ??= (async () => {\n\t\tclearTimeout(timer);\n\t\ttimer = void 0;\n\t\tconst pending = [...buffer.values()];\n\t\tbuffer = /* @__PURE__ */ new Map();\n\t\tmergeAll(buffer, await apply(pending, processShard));\n\t})().catch(warn(\"flush\")).finally(() => {\n\t\tflushing = void 0;\n\t\tschedule();\n\t});\n\tlet nextDue = 0;\n\tlet compacting;\n\t/** Log rows this process read, by `[log table's index, id]`, for the deletes after a group. */\n\tconst known = /* @__PURE__ */ new Map();\n\tconst idOf = (shard, id) => JSON.stringify([shard, id]);\n\t/** The lease row as stored once `set` is written over it. */\n\tconst leaseOp = (held, set) => {\n\t\tconst next = {\n\t\t\t...held,\n\t\t\t...set,\n\t\t\t_v: Number(held._v) + 1\n\t\t};\n\t\treturn {\n\t\t\top: {\n\t\t\t\ttype: \"patch\",\n\t\t\t\ttable: table(LEASE_TABLE),\n\t\t\t\tkey: [LEASE.id],\n\t\t\t\tset,\n\t\t\t\tguard: { v: Number(held._v) },\n\t\t\t\tprevious: held\n\t\t\t},\n\t\t\tnext\n\t\t};\n\t};\n\t/** The lease row as stored after this process takes it, or undefined when it is held or not due. */\n\tconst takeLease = (force) => engine.transaction(async (tx) => {\n\t\tconst at = now();\n\t\tconst held = await tx.findOne(LEASE_TABLE, LEASE);\n\t\tconst fields = {\n\t\t\tholder,\n\t\t\tuntil: at + LEASE_MS\n\t\t};\n\t\tif (held === null) {\n\t\t\tconst row = {\n\t\t\t\t...LEASE,\n\t\t\t\t...fields,\n\t\t\t\tnext: 0,\n\t\t\t\tapplied: \"[]\"\n\t\t\t};\n\t\t\ttx.create(LEASE_TABLE, row);\n\t\t\treturn {\n\t\t\t\t...row,\n\t\t\t\t_v: 0\n\t\t\t};\n\t\t}\n\t\tnextDue = Number(held.next);\n\t\tif (held.holder !== holder && Number(held.until) > at || !force && nextDue > at) return void 0;\n\t\ttx.update(LEASE_TABLE, held, fields);\n\t\treturn {\n\t\t\t...held,\n\t\t\t...fields,\n\t\t\t_v: Number(held._v) + 1\n\t\t};\n\t});\n\t/**\n\t* Writes `ops` once, retrying transient errors; true when it committed.\n\t* A conflict leaves its log rows for the next compaction; a write whose\n\t* outcome is unknown throws, and the next compaction reads what it did.\n\t*/\n\tconst commit = async (ops) => {\n\t\tfor (let failures = 0; failures < ATTEMPTS; failures += 1) {\n\t\t\tconst result = await adapter.write(ops);\n\t\t\tif (result.ok) return true;\n\t\t\tif (!(\"retry\" in result)) return false;\n\t\t\tawait sleep(failures);\n\t\t}\n\t\treturn false;\n\t};\n\t/** Deletes the log rows `held` lists as applied, in parallel writes; true once none is left. */\n\tconst deleteApplied = async (held) => {\n\t\tconst applied = JSON.parse(String(held.applied));\n\t\tawait Promise.all(LOG_TABLES.map(async (name, shard) => {\n\t\t\tconst ids = applied.flatMap(([at, id]) => at === shard && !known.has(idOf(at, id)) ? [id] : []);\n\t\t\tif (ids.length === 0) return;\n\t\t\tconst rows = await adapter.get(table(name), ids.map((id) => [id]));\n\t\t\tfor (const row of rows) if (row) known.set(idOf(shard, row.id), row);\n\t\t}));\n\t\tconst rows = applied.flatMap(([shard, id]) => {\n\t\t\tconst row = known.get(idOf(shard, id));\n\t\t\treturn row === void 0 ? [] : [{\n\t\t\t\tshard,\n\t\t\t\trow\n\t\t\t}];\n\t\t});\n\t\tif (adapter.deleteConsumed && await Promise.all(LOG_TABLES.map((name, at) => {\n\t\t\tconst own = rows.flatMap(({ shard, row }) => shard === at ? [row] : []);\n\t\t\treturn own.length > 0 && adapter.deleteConsumed(table(name), own);\n\t\t})).then(() => true, (error) => (warn(\"log cleanup\")(error), false))) {\n\t\t\tfor (const [shard, id] of applied) known.delete(idOf(shard, id));\n\t\t\treturn true;\n\t\t}\n\t\tconst deletes = rows.map(({ shard, row }) => {\n\t\t\tconst guard = { v: Number(row[\"_v\"]) };\n\t\t\treturn {\n\t\t\t\ttype: \"delete\",\n\t\t\t\ttable: table(LOG_TABLES[shard]),\n\t\t\t\tkey: [String(row.id)],\n\t\t\t\tguard,\n\t\t\t\tprevious: row\n\t\t\t};\n\t\t});\n\t\tlet size = deletes.length;\n\t\twhile (size > 1 && !adapter.fits(deletes.slice(0, size))) size = Math.ceil(size / 2);\n\t\tconst chunks = [];\n\t\tfor (let at = 0; at < deletes.length; at += size) chunks.push(deletes.slice(at, at + size));\n\t\tif ((await Promise.all(chunks.map(commit))).includes(false)) return false;\n\t\tfor (const [shard, id] of applied) known.delete(idOf(shard, id));\n\t\treturn true;\n\t};\n\t/**\n\t* The oldest pending log rows this schema can read, a page from each\n\t* table; `more` when a page was full, so more may wait.\n\t*/\n\tconst readLogs = async () => {\n\t\tlet more = false;\n\t\treturn {\n\t\t\tlogs: (await Promise.all(LOG_TABLES.map(async (name, shard) => {\n\t\t\t\tconst page = await engine.reads.findMany(name, {\n\t\t\t\t\tindex: \"oldest\",\n\t\t\t\t\tlimit: LOG_PAGE\n\t\t\t\t});\n\t\t\t\tmore ||= page.next !== void 0;\n\t\t\t\treturn (await Promise.all(page.rows.map(async (row) => ({\n\t\t\t\t\tshard,\n\t\t\t\t\trow,\n\t\t\t\t\tchanges: await decode(String(row.changes))\n\t\t\t\t})))).flatMap(({ changes, ...entry }) => changes === void 0 ? [] : [{\n\t\t\t\t\t...entry,\n\t\t\t\t\tchanges\n\t\t\t\t}]);\n\t\t\t}))).flat().sort((left, right) => compareUtf8(String(left.row.id), String(right.row.id))),\n\t\t\tmore\n\t\t};\n\t};\n\tconst rowsFor = async (changes) => (await compile(adapter, changes, () => 0)).filter(isOp);\n\t/**\n\t* Applies the oldest pending log rows whose merged changes fit in one\n\t* atomic write with the lease, which lists them as applied; the rows are\n\t* deleted after it. A log row too large for one write applies in parts,\n\t* keeping the rest in it. Returns the lease after the write and how many\n\t* log rows it applied whole, or undefined when a conflict stopped it.\n\t*/\n\tconst applyGroup = async (held, logs) => {\n\t\tfor (let count = logs.length; count > 0; count = Math.floor(count / 2)) {\n\t\t\tconst batch = logs.slice(0, count);\n\t\t\tconst changes = mergeAll(/* @__PURE__ */ new Map(), batch.flatMap((entry) => [...entry.changes.values()]));\n\t\t\tconst applied = batch.map(({ shard, row }) => [shard, row.id]);\n\t\t\tconst lease = leaseOp(held, { applied: JSON.stringify(applied) });\n\t\t\tconst ops = [...await rowsFor([...changes.values()]), lease.op];\n\t\t\tif (!adapter.fits(ops)) continue;\n\t\t\tfor (const { shard, row } of batch) known.set(idOf(shard, row.id), row);\n\t\t\treturn await commit(ops) ? {\n\t\t\t\theld: lease.next,\n\t\t\t\tcount\n\t\t\t} : void 0;\n\t\t}\n\t\tconst [{ shard, row, changes }] = logs;\n\t\tconst name = LOG_TABLES[shard];\n\t\tconst entries = [...changes.values()];\n\t\tfor (let take = entries.length - 1; take > 0; take = Math.floor(take / 2)) {\n\t\t\tconst kept = {\n\t\t\t\ttype: \"patch\",\n\t\t\t\ttable: table(name),\n\t\t\t\tkey: [String(row.id)],\n\t\t\t\tset: { changes: await encode(entries.slice(take)) },\n\t\t\t\tguard: { v: Number(row[\"_v\"]) },\n\t\t\t\tprevious: row\n\t\t\t};\n\t\t\tconst lease = leaseOp(held, {});\n\t\t\tconst ops = [\n\t\t\t\t...await rowsFor(entries.slice(0, take)),\n\t\t\t\tkept,\n\t\t\t\tlease.op\n\t\t\t];\n\t\t\tif (adapter.fits(ops)) return await commit(ops) ? {\n\t\t\t\theld: lease.next,\n\t\t\t\tcount: 0\n\t\t\t} : void 0;\n\t\t}\n\t\tthrow new DatabaseTransactionError(`${name}: one aggregate change does not fit in one write.`);\n\t};\n\t/**\n\t* Applies up to `groups` groups under the lease, deleting each group's log\n\t* rows before the next; the next compaction is due at once when some are\n\t* left. The lease release clears the applied list once its rows are gone.\n\t*/\n\tconst run = async (force, groups) => {\n\t\tlet held = await takeLease(force);\n\t\tif (held === void 0) return;\n\t\tlet pending = true;\n\t\tlet clear = false;\n\t\ttry {\n\t\t\tfor (let group = 0;; group += 1) {\n\t\t\t\tclear = await deleteApplied(held);\n\t\t\t\tif (!clear || !pending || group === groups) break;\n\t\t\t\tconst { logs, more } = await readLogs();\n\t\t\t\tif (logs.length === 0) {\n\t\t\t\t\tpending = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst applied = await applyGroup(held, logs);\n\t\t\t\tif (applied === void 0) break;\n\t\t\t\t[held, clear] = [applied.held, false];\n\t\t\t\tpending = more || applied.count < logs.length;\n\t\t\t}\n\t\t} finally {\n\t\t\tnextDue = now() + (pending ? 0 : windowMs);\n\t\t\tconst set = {\n\t\t\t\tuntil: 0,\n\t\t\t\tnext: nextDue,\n\t\t\t\t...clear ? { applied: \"[]\" } : {}\n\t\t\t};\n\t\t\tawait commit([leaseOp(held, set).op]);\n\t\t\tknown.clear();\n\t\t}\n\t};\n\t/** One compaction at a time in this process; never rejects. */\n\tconst compact = (force, groups) => compacting ??= run(force, groups).catch(warn(\"compaction\")).finally(() => {\n\t\tcompacting = void 0;\n\t});\n\tlet checking;\n\t/** Whether any log row waits; reads at once share one check. */\n\tconst hasPending = () => checking ??= Promise.all(LOG_TABLES.map((name) => engine.reads.findMany(name, {\n\t\tindex: \"oldest\",\n\t\tlimit: 1\n\t}))).then((pages) => pages.some((page) => page.rows.length > 0)).finally(() => {\n\t\tchecking = void 0;\n\t});\n\t/** Takes a committed transaction's changes; never rejects, since the transaction already committed. */\n\tconst committed = async (changes) => {\n\t\tif (mode === \"log\") {\n\t\t\tif (now() >= nextDue) await compact(false, GROUPS.commit);\n\t\t\treturn;\n\t\t}\n\t\tmergeAll(buffer, changes.values());\n\t\tschedule();\n\t\tif (buffer.size >= MAX_BUFFERED) await flushBuffer();\n\t};\n\tconst flush = async () => {\n\t\tawait flushBuffer();\n\t\tif (mode === \"log\" && await hasPending()) await compact(true, GROUPS.flush);\n\t};\n\treturn {\n\t\tasync transaction(fn) {\n\t\t\tlet changes = /* @__PURE__ */ new Map();\n\t\t\tconst result = await engine.transaction(async (tx) => {\n\t\t\t\tconst attempt = /* @__PURE__ */ new Map();\n\t\t\t\tchanges = attempt;\n\t\t\t\tlet open = true;\n\t\t\t\tlet failure;\n\t\t\t\tconst aggregate = (name, identity, values, options) => {\n\t\t\t\t\tconst model = schema.models.get(name);\n\t\t\t\t\tif (!isBatched(model)) return tx.aggregate(name, identity, values, options);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!open) throw new DatabaseTransactionError(\"The transaction has ended.\");\n\t\t\t\t\t\trecordAggregate(attempt, model, identity, values, options?.shardBy);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tfailure ??= { error };\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttry {\n\t\t\t\t\tconst value = await fn({\n\t\t\t\t\t\t...tx,\n\t\t\t\t\t\taggregate\n\t\t\t\t\t});\n\t\t\t\t\tif (failure) throw failure.error;\n\t\t\t\t\tif (mode === \"log\" && attempt.size > 0) {\n\t\t\t\t\t\tconst id = `${now().toString(36).padStart(9, \"0\")}${holder.slice(0, 8)}${crypto.randomUUID().slice(0, 8)}`;\n\t\t\t\t\t\tconst shard = Math.floor(Math.random() * LOG_TABLES.length);\n\t\t\t\t\t\tconst merged = mergeAll(/* @__PURE__ */ new Map(), attempt.values());\n\t\t\t\t\t\ttx.create(LOG_TABLES[shard], {\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tchanges: await encode(merged.values())\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t} finally {\n\t\t\t\t\topen = false;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (changes.size > 0) await committed(changes);\n\t\t\treturn result;\n\t\t},\n\t\tasync beforeRead(name) {\n\t\t\tif (!isBatched(schema.models.get(name))) return;\n\t\t\tif (buffer.size > 0 || flushing !== void 0) await flushBuffer();\n\t\t\tif (mode === \"log\") {\n\t\t\t\tif (await hasPending().catch((error) => {\n\t\t\t\t\twarn(\"read\")(error);\n\t\t\t\t\treturn false;\n\t\t\t\t})) await compact(true, GROUPS.read);\n\t\t\t}\n\t\t},\n\t\tflush,\n\t\tasync dispose() {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = void 0;\n\t\t\tawait flush();\n\t\t}\n\t};\n};\n//#endregion\nexport { aggregateBatchingModule, createAggregateBatches };\n", "//#region src/engine/database/retention.ts\nconst MINUTE_MS = 6e4;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\n/** A model's retention as its physical table carries it, which each adapter maps natively. */\nconst physicalRetention = ({ retention }) => retention === void 0 ? {} : { retention: {\n\tcolumn: retention.field,\n\tms: retention.days * DAY_MS\n} };\n/** Models in a reference or a rooted index, which an expired row's delete would break. */\nconst linkedModels = (schema) => Object.entries(schema).flatMap(([name, { fields, indexes }]) => [...Object.values(fields).map(({ references }) => references), ...Object.values(indexes).map(({ root }) => root)].flatMap((link) => link ? [name, link.model] : []));\n/**\n* What is wrong with a model's retention: it counts from an integer field,\n* over whole days, and expired rows are deleted without cascades, counter\n* moves, or root bumps, so the model is in no reference or rooted index.\n*/\nconst retentionProblems = (schema, model) => {\n\tconst definition = schema[model];\n\tif (definition.retention === void 0) return [];\n\tconst { field, days } = definition.retention;\n\tconst declared = definition.fields[field] ?? (definition.kind === \"table\" ? definition.derived[field] : void 0);\n\treturn [\n\t\t...declared?.type !== \"integer\" || \"multi\" in declared && declared.multi === true ? [`retention field \"${field}\" is not an integer field`] : [],\n\t\t...Number.isSafeInteger(days) && days >= 1 ? [] : [\"retention days must be a whole number of at least 1\"],\n\t\t...linkedModels(schema).includes(model) ? [\"a model with retention is in no reference or rooted index\"] : []\n\t];\n};\n/**\n* Rows a pass deletes from each table: one statement or two a table, so a\n* pass stays well inside D1's 50 queries an invocation.\n*/\nconst PASS_LIMIT = 500;\n/** The lease row: when the next pass is due, in epoch ms. */\nconst LEASE_KEY = \"retention.nextPassAt\";\n/**\n* The adapter, pruning during its writes with no scheduler: once the lease\n* row in `leaseTable` is due, the write that takes it first runs one bounded\n* pass over the tables with retention, and other writers skip. The next pass\n* is due in an hour, or in a minute while a pass still found a full batch of\n* expired rows in some table; a pass that fails is due again at once. A\n* backend that expires rows natively, or a schema without retention, gets its\n* adapter back.\n*/\nconst pruneDuringWrites = (adapter, tables, { leaseTable: table, now }) => {\n\tconst expiring = tables.filter(({ retention }) => retention !== void 0);\n\tif (adapter.prune === void 0 || expiring.length === 0) return adapter;\n\tconst key = [LEASE_KEY];\n\tlet checkAt = 0;\n\tconst lease = async (row, due) => {\n\t\tconst value = String(due);\n\t\tconst guard = { v: row === null ? -1 : Number(row._v) };\n\t\tconst next = {\n\t\t\tkey: LEASE_KEY,\n\t\t\tvalue,\n\t\t\t_v: guard.v + 1\n\t\t};\n\t\tconst op = row === null ? {\n\t\t\ttype: \"insert\",\n\t\t\ttable,\n\t\t\trow: next\n\t\t} : {\n\t\t\ttype: \"patch\",\n\t\t\ttable,\n\t\t\tkey,\n\t\t\tset: { value },\n\t\t\tguard,\n\t\t\tprevious: row\n\t\t};\n\t\treturn (await adapter.write([op])).ok ? next : null;\n\t};\n\tconst pass = async () => {\n\t\tconst at = now();\n\t\tif (at < checkAt) return;\n\t\tcheckAt = at + MINUTE_MS;\n\t\tconst [row = null] = await adapter.get(table, [key]);\n\t\tcheckAt = row === null ? at : Number(row.value);\n\t\tif (checkAt > at) return;\n\t\tconst held = await lease(row, at + HOUR_MS);\n\t\tif (held === null) return;\n\t\tcheckAt = at + HOUR_MS;\n\t\tconst deleted = [];\n\t\ttry {\n\t\t\tfor (const t of expiring) deleted.push(await adapter.prune(t, at - t.retention.ms, PASS_LIMIT));\n\t\t} catch (error) {\n\t\t\tcheckAt = at + MINUTE_MS;\n\t\t\tawait lease(held, at).catch(() => null);\n\t\t\tthrow error;\n\t\t}\n\t\tif (deleted.includes(PASS_LIMIT) && await lease(held, at + MINUTE_MS) !== null) checkAt = at + MINUTE_MS;\n\t};\n\tconst warn = (error) => console.warn(\"[hot-updater] Pruning expired rows failed.\", error);\n\treturn Object.assign(Object.create(adapter), { async write(ops) {\n\t\tawait pass().catch(warn);\n\t\treturn adapter.write(ops);\n\t} });\n};\n//#endregion\nexport { physicalRetention, pruneDuringWrites, retentionProblems };\n", "import { DatabaseSchemaError } from \"../../database/adapter.mjs\";\nimport { physicalRetention, retentionProblems } from \"./retention.mjs\";\n//#region src/engine/database/resolveSchema.ts\nconst SHARD_COLUMN = \"_shard\";\nconst NAME = /^[a-z][a-z0-9_]*$/u;\nconst INDEX_NAME = /^[A-Za-z][A-Za-z0-9_]*$/u;\nconst tableName = (module, model) => module.namespace ? `${module.namespace}_${model}` : model;\nconst integer = (name, defaulted = false) => ({\n\tname,\n\ttype: \"integer\",\n\tnullable: false,\n\t...defaulted ? { default: 0 } : {}\n});\n/** A declared or derived field's type, and whether it holds several values. */\nconst fieldType = (model, name) => {\n\tconst field = model.fields[name] ?? (model.kind === \"table\" ? model.derived[name] : void 0);\n\treturn field && {\n\t\ttype: field.type,\n\t\tmulti: \"multi\" in field && !!field.multi\n\t};\n};\nconst metricsOf = (model) => [\n\t...model.counters,\n\t...model.gauges,\n\t...model.distinct\n];\n/** Field names, the key, and each field's options. */\nconst fieldProblems = (definition, add) => {\n\tconst names = [...Object.keys(definition.fields), ...definition.kind === \"table\" ? Object.keys(definition.derived) : metricsOf(definition)];\n\tfor (const name of new Set(names)) {\n\t\tif (!NAME.test(name)) add(`field \"${name}\" must match ${NAME.source}`);\n\t\tif (names.indexOf(name) !== names.lastIndexOf(name)) add(`field \"${name}\" is declared twice`);\n\t}\n\tconst { key } = definition;\n\tif (key.length === 0) add(\"key is empty\");\n\tif (new Set(key).size !== key.length) add(\"key repeats a field\");\n\tfor (const name of key) {\n\t\tconst field = definition.fields[name];\n\t\tif (field === void 0) add(`key field \"${name}\" is not a declared field`);\n\t\telse if (field.required === false) add(`key field \"${name}\" is nullable`);\n\t\telse if (field.type === \"json\") add(`key field \"${name}\" is json`);\n\t}\n\tfor (const [name, { type, maxLength, ascii }] of Object.entries(definition.fields)) {\n\t\tif (maxLength !== void 0 && (type !== \"string\" || !Number.isSafeInteger(maxLength) || maxLength < 1)) add(`field \"${name}\" has an invalid maxLength`);\n\t\tif (ascii && type !== \"string\") add(`field \"${name}\" is ascii but not a string`);\n\t}\n};\n/** A table's derived fields and references. */\nconst tableProblems = (definition, add, table) => {\n\tfor (const [name, derived] of Object.entries(definition.derived)) {\n\t\tif (typeof derived.compute !== \"function\") add(`derived field \"${name}\" has no compute function`);\n\t\tif (derived.multi && derived.type === \"json\") add(`derived field \"${name}\" cannot be multi-valued json`);\n\t}\n\tfor (const [name, { type, references }] of Object.entries(definition.fields)) {\n\t\tif (references === void 0) continue;\n\t\tconst target = table(references.model);\n\t\tconst targetKey = target?.key.length === 1 ? target.fields[target.key[0]] : void 0;\n\t\tif (targetKey === void 0) add(`field \"${name}\" references \"${references.model}\", which is not a single-key table of this module`);\n\t\telse if (targetKey.type !== type) add(`field \"${name}\" and the key of \"${references.model}\" differ in type`);\n\t\tif (references.onDelete === \"cascade\" && !Object.values(definition.indexes).some(({ eq }) => eq.length === 1 && eq[0] === name)) add(`cascade on \"${name}\" needs an index whose eq is exactly [${name}]`);\n\t}\n};\n/** An aggregate's identity, metrics, and shards. */\nconst aggregateProblems = (definition, add) => {\n\tconst identity = Object.keys(definition.fields);\n\tif (definition.key.join(\"\\0\") !== identity.join(\"\\0\")) add(`key must list the identity fields in declaration order: ${identity.join(\", \")}`);\n\tif (metricsOf(definition).length === 0) add(\"aggregate has no metrics\");\n\tif (definition.distinct.length > 0 && definition.counters.length + definition.gauges.length > 0) add(\"distinct sketches need an aggregate of their own\");\n\tconst { shards } = definition;\n\tif (!Number.isSafeInteger(shards) || shards < 1 || shards > 64) add(`shards must be 1\u201364`);\n};\n/** Every problem in one model's declaration, its roots and references included. */\nconst problemsOf = (module, model, definition) => {\n\tconst problems = [];\n\tconst add = (message) => problems.push(`${module.id}.${model}: ${message}`);\n\tconst table = (name) => {\n\t\tconst target = module.schema[name];\n\t\treturn target?.kind === \"table\" ? target : void 0;\n\t};\n\tif (!NAME.test(model)) add(\"model names use lowercase letters, digits, and _\");\n\tfieldProblems(definition, add);\n\tfor (const [name, index] of Object.entries(definition.indexes)) {\n\t\tconst columns = [...index.eq, ...index.sort];\n\t\tif (!INDEX_NAME.test(name)) add(`index \"${name}\" must match ${INDEX_NAME.source}`);\n\t\tif (columns.length === 0) add(`index \"${name}\" has no fields`);\n\t\tif (index.unique && index.sort.length > 0) add(`unique index \"${name}\" cannot sort`);\n\t\tif (columns.filter((column) => {\n\t\t\tconst type = fieldType(definition, column);\n\t\t\tif (type === void 0) add(`index \"${name}\" names undeclared field \"${column}\"`);\n\t\t\telse if (type.type === \"json\") add(`index \"${name}\" names json field \"${column}\"`);\n\t\t\telse if (type.multi && index.sort.includes(column)) add(`index \"${name}\" sorts by multi-valued field \"${column}\"`);\n\t\t\treturn type?.type !== \"json\" && type?.multi;\n\t\t}).length > 1) add(`index \"${name}\" has more than one multi-valued field`);\n\t\tif (index.root === void 0) continue;\n\t\tconst root = table(index.root.model);\n\t\tif (root === void 0) add(`index \"${name}\" is rooted at unknown table \"${index.root.model}\"`);\n\t\telse if (root.key.length > index.eq.length || root.key.some((field, position) => fieldType(definition, index.eq[position])?.type !== root.fields[field].type)) add(`index \"${name}\" eq must start with the key of \"${index.root.model}\"`);\n\t}\n\tif (definition.kind === \"table\") tableProblems(definition, add, table);\n\telse aggregateProblems(definition, add);\n\tfor (const problem of retentionProblems(module.schema, model)) add(problem);\n\treturn problems;\n};\n/** Rejects invalid module schemas at startup, listing every problem. */\nconst validateSchema = (modules) => {\n\tconst problems = [];\n\tconst owners = /* @__PURE__ */ new Map();\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tconst name = tableName(module, model);\n\t\tconst owner = owners.get(name);\n\t\tif (owner !== void 0) problems.push(`${module.id}.${model}: table \"${name}\" is also declared by ${owner}`);\n\t\towners.set(name, `${module.id}.${model}`);\n\t\tproblems.push(...problemsOf(module, model, definition));\n\t}\n\tif (problems.length > 0) throw new DatabaseSchemaError(`Invalid database schema:\\n- ${problems.join(\"\\n- \")}`);\n};\nconst indexesOf = (definition) => [...Object.entries(definition.indexes).map(([name, index]) => ({\n\tname,\n\teq: [...index.eq],\n\tsort: [...index.sort],\n\t...index.unique ? { unique: true } : {}\n})), ...Object.entries(definition.fields).flatMap(([name, field]) => field.unique ? [{\n\tname,\n\teq: [name],\n\tsort: [],\n\tunique: true\n}] : [])];\n/** Validates the modules, then resolves them into physical tables with engine columns. */\nconst resolveSchema = (modules) => {\n\tvalidateSchema(modules);\n\tconst references = [];\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tif (definition.kind !== \"table\") continue;\n\t\tconst table = tableName(module, model);\n\t\tfor (const [field, { references: to }] of Object.entries(definition.fields)) {\n\t\t\tif (to === void 0) continue;\n\t\t\tconst { onDelete } = to;\n\t\t\tconst target = tableName(module, to.model);\n\t\t\tconst counter = onDelete === \"none\" ? {} : { counter: `_refs_${table}_${field}` };\n\t\t\treferences.push({\n\t\t\t\ttable,\n\t\t\t\tfield,\n\t\t\t\ttarget,\n\t\t\t\tonDelete,\n\t\t\t\t...counter\n\t\t\t});\n\t\t}\n\t}\n\tconst models = /* @__PURE__ */ new Map();\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tconst name = tableName(module, model);\n\t\tconst referencedBy = references.filter(({ target }) => target === name);\n\t\tconst columns = Object.entries(definition.fields).map(([field, { type, required, maxLength, ascii }]) => ({\n\t\t\tname: field,\n\t\t\ttype,\n\t\t\tnullable: required === false,\n\t\t\t...maxLength === void 0 ? {} : { maxLength },\n\t\t\t...ascii ? { ascii } : {}\n\t\t}));\n\t\tif (definition.kind === \"table\") for (const [field, { type, multi }] of Object.entries(definition.derived)) columns.push({\n\t\t\tname: field,\n\t\t\ttype,\n\t\t\tnullable: true,\n\t\t\t...multi ? { multi } : {}\n\t\t});\n\t\telse columns.push(integer(SHARD_COLUMN), ...[...definition.counters, ...definition.gauges].map((metric) => integer(metric)), ...definition.distinct.map((metric) => ({\n\t\t\tname: metric,\n\t\t\ttype: \"string\",\n\t\t\tnullable: true\n\t\t})));\n\t\tfor (const { counter } of referencedBy) if (counter !== void 0) columns.push(integer(counter, true));\n\t\tcolumns.push(integer(\"_v\", true));\n\t\tmodels.set(name, {\n\t\t\tmodule: module.id,\n\t\t\tmodel,\n\t\t\tdefinition,\n\t\t\ttable: {\n\t\t\t\tname,\n\t\t\t\tcolumns,\n\t\t\t\tkey: definition.kind === \"aggregate\" ? [...definition.key, SHARD_COLUMN] : [...definition.key],\n\t\t\t\tindexes: indexesOf(definition),\n\t\t\t\t...physicalRetention(definition)\n\t\t\t},\n\t\t\treferences: references.filter(({ table }) => table === name),\n\t\t\treferencedBy,\n\t\t\troots: new Map(Object.entries(definition.indexes).flatMap(([index, { root }]) => root === void 0 ? [] : [[index, tableName(module, root.model)]]))\n\t\t});\n\t}\n\treturn {\n\t\tmodels,\n\t\ttables: [...models.values()].map(({ table }) => table)\n\t};\n};\n//#endregion\nexport { SHARD_COLUMN, resolveSchema, validateSchema };\n", "import { HOT_UPDATER_SCHEMA_VERSION } from \"../core/schema.mjs\";\nimport { getEmptyMigrationResult } from \"./fixedMigratorShared.mjs\";\nimport { migrateSchema } from \"./schemaSettings.mjs\";\nimport { refuseV0Database, storedSchemaVersion } from \"./settingsMigrator.mjs\";\n//#region src/engine/db/engineMigrator.ts\n/**\n* `hot-updater db migrate` for a store whose adapter creates its own tables\n* (MongoDB and the key-value stores): the tables and indexes, then the\n* settings rows, applied when a setting is missing or different, and refused\n* on a v0 database.\n*/\nconst createEngineMigrator = (options) => {\n\tconst getVersion = async () => storedSchemaVersion(await options.readSettings());\n\tconst makeResult = async (migrate = {}) => {\n\t\tconst stored = await options.readSettings();\n\t\trefuseV0Database(options.adapterName, stored);\n\t\tif (Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();\n\t\treturn {\n\t\t\toperations: [...options.schema.tables.map((table) => ({\n\t\t\t\ttype: \"create-table\",\n\t\t\t\tvalue: {\n\t\t\t\t\tormName: table.name,\n\t\t\t\t\tcolumns: Object.fromEntries(table.columns.map((column) => [column.name, {\n\t\t\t\t\t\tormName: column.name,\n\t\t\t\t\t\ttype: column.type\n\t\t\t\t\t}]))\n\t\t\t\t}\n\t\t\t})), ...migrate.updateSettings === false ? [] : [{\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: `Write the schema settings: ${Object.keys(options.settings).join(\", \")}`\n\t\t\t}]],\n\t\t\texecute: () => migrateSchema(options.adapter, options.adapterName, options.schema.tables, options.settings)\n\t\t};\n\t};\n\treturn {\n\t\tgetVersion,\n\t\tgetNameVariants: async () => void 0,\n\t\tnext: async () => await getVersion() === \"1.0.0\" ? void 0 : { version: HOT_UPDATER_SCHEMA_VERSION },\n\t\tprevious: async () => void 0,\n\t\tup: makeResult,\n\t\tdown: async () => {\n\t\t\tthrow new Error(\"No previous schema to migrate to.\");\n\t\t},\n\t\tmigrateTo: async (version, migrate) => {\n\t\t\tif (version !== \"1.0.0\") throw new Error(`Invalid version ${version}`);\n\t\t\treturn makeResult(migrate);\n\t\t},\n\t\tmigrateToLatest: makeResult\n\t};\n};\n//#endregion\nexport { createEngineMigrator };\n", "import { HOT_UPDATER_SCHEMA_VERSION, coreModule } from \"../core/schema.mjs\";\nimport { aggregateBatchingModule } from \"../database/aggregateBatching.mjs\";\nimport { resolveSchema } from \"../database/resolveSchema.mjs\";\nimport { ENGINE_SCHEMA_KEY, isMissingSchemaError, readSettings, withSchemaFence } from \"../database/fence.mjs\";\nimport { migrateSchema } from \"./schemaSettings.mjs\";\nimport { createEngineMigrator } from \"./engineMigrator.mjs\";\n//#region src/engine/db/coreDatabase.ts\n/** Core's tables: the tables every provider's tooling creates. */\nconst coreSchema = resolveSchema([coreModule]);\n/** The settings rows a provider's database is fenced by. */\nconst coreSettings = {\n\t[ENGINE_SCHEMA_KEY]: \"1\",\n\t\"schema.core\": HOT_UPDATER_SCHEMA_VERSION\n};\n/** What `hot-updater db` creates for a server without plugins. */\nconst coreTarget = {\n\tschema: coreSchema,\n\tsettings: coreSettings\n};\n/**\n* The log and lease tables a database with `aggregateBatching` writes\n* beside core's and the plugins', which a provider's access policy names,\n* such as the managed AWS server's IAM role.\n*/\nconst aggregateBatchingTables = resolveSchema([aggregateBatchingModule]).tables;\n/** Each plugin's `schema.<id>` settings row. */\nconst pluginSettings = (plugins) => Object.fromEntries(plugins.map(({ id, schemaVersion }) => [`schema.${id}`, schemaVersion]));\n/** A plugin's schema as the engine resolves it: prefixed by its id unless it keeps its names. */\nconst pluginModule = ({ id, schema, namespace }) => ({\n\tid,\n\tschema,\n\t...namespace === false ? {} : { namespace: id }\n});\n/**\n* What `hot-updater db` creates for a server's plugins: core's tables, then\n* each plugin's tables with its `schema.<id>` settings row.\n*/\nconst toolingTargetOf = (plugins) => plugins.length === 0 ? coreTarget : {\n\tschema: resolveSchema([coreModule, ...plugins.map(pluginModule)]),\n\tsettings: {\n\t\t...coreSettings,\n\t\t...pluginSettings(plugins)\n\t}\n};\n/**\n* Creates core's tables and those of `plugins`, then writes their settings\n* rows: what a provider's setup runs for the plugins its server runs.\n*/\nconst migrateCoreSchema = (adapter, name, plugins = []) => {\n\tconst { schema, settings } = toolingTargetOf(plugins);\n\treturn migrateSchema(adapter, name, schema.tables, settings);\n};\n/**\n* A provider's database on the storage engine: its adapter behind the schema\n* fence, which checks core's settings rows before the first read or write\n* and names `hot-updater db migrate` when they are missing or stale. When the\n* adapter creates its own tables, `hot-updater db migrate` creates core's\n* tables and the server's plugin tables, then writes their settings rows.\n*/\nconst createEngineDatabase = ({ name, adapter, onCachedRoutesChange, aggregateBatching, retry, readSettings: readStored }) => {\n\tconst fenced = withSchemaFence(adapter, name, coreSettings);\n\tconst createMigrator = ({ schema, settings } = coreTarget) => createEngineMigrator({\n\t\tadapterName: name,\n\t\tadapter,\n\t\tschema,\n\t\tsettings,\n\t\treadSettings: readStored ?? (async () => {\n\t\t\tconst rows = await readSettings(adapter, Object.keys(settings)).catch((error) => {\n\t\t\t\tif (isMissingSchemaError(error)) return [];\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\treturn new Map(rows.flatMap((row) => row === null ? [] : [[String(row.key), row.value]]));\n\t\t})\n\t});\n\treturn {\n\t\tname,\n\t\tadapter: fenced,\n\t\t...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange },\n\t\t...aggregateBatching ? { aggregateBatching } : {},\n\t\t...retry === void 0 ? {} : { retry },\n\t\t...adapter.dispose === void 0 ? {} : { dispose: () => adapter.dispose() },\n\t\t...adapter.migrations === void 0 ? {} : { createMigrator }\n\t};\n};\n//#endregion\nexport { aggregateBatchingTables, coreSchema, coreSettings, coreTarget, createEngineDatabase, migrateCoreSchema, pluginModule, pluginSettings, toolingTargetOf };\n", "import { DatabaseAmbiguousCommitError, DatabaseConflictError, DatabaseConstraintError, DatabaseQueryError, DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport { rowKey } from \"../../database/adapter.mjs\";\nimport { canonicalJson, compareTuples, indexEntries } from \"../../database/values.mjs\";\nimport { NegativeGaugeError, compileAggregates, recordAggregate } from \"./engineAggregates.mjs\";\n//#region src/engine/database/engineTransaction.ts\n/** A row this attempt read changed while it ran; the attempt reruns. */\nvar StaleReadError = class extends Error {};\nconst idOf = (table, key) => JSON.stringify([table, key]);\nconst versionOf = (row) => Number(row[\"_v\"]);\nconst isKeyed = (value) => value !== null && value !== void 0;\nconst misuse = (table, message) => new DatabaseTransactionError(`${table}: ${message}`);\nconst once = (table) => misuse(table, \"a transaction writes one key once.\");\nconst hooks = globalThis.process?.getBuiltinModule?.(\"node:async_hooks\");\n/** Where the runtime tracks async context, `db.*` inside a transaction throws. */\nconst transactionScope = hooks && new hooks.AsyncLocalStorage();\nconst assertOutsideTransaction = () => {\n\tif (transactionScope?.getStore() !== void 0) throw new DatabaseTransactionError(\"Inside transaction(), read and write through its handle; db and core are not part of it.\");\n};\nconst createTransactions = ({ adapter, schema, reads, retry = {} }) => {\n\tconst { attempts = 8, baseDelayMs = 5, maxDelayMs = 250, onRetry } = retry;\n\tconst { modelOf } = reads;\n\t/**\n\t* A key-value index copy has no `_v`. A transaction guards what it reads,\n\t* so it reads such a row whole, and reruns if it changed since the copy.\n\t*/\n\tconst complete = async ({ table }, rows) => {\n\t\tconst copies = rows.filter((row) => !(\"_v\" in row));\n\t\tif (copies.length === 0) return [...rows];\n\t\tconst current = await adapter.get(table, copies.map((copy) => rowKey(table, copy)));\n\t\treturn rows.map((row) => {\n\t\t\tconst at = copies.indexOf(row);\n\t\t\tif (at < 0) return row;\n\t\t\tconst whole = current[at];\n\t\t\tif (!whole || Object.keys(row).some((column) => canonicalJson(row[column]) !== canonicalJson(whole[column]))) throw new StaleReadError();\n\t\t\treturn whole;\n\t\t});\n\t};\n\tconst attempt = async (fn) => {\n\t\tconst read = /* @__PURE__ */ new Map();\n\t\t/** Rows of rooted ranges: their root guards them, so they need no check of their own. */\n\t\tconst ranged = /* @__PURE__ */ new Map();\n\t\tconst writes = /* @__PURE__ */ new Map();\n\t\t/** Deleted keys, children before their parents. */\n\t\tconst deleted = [];\n\t\tconst aggregates = /* @__PURE__ */ new Map();\n\t\tlet open = true;\n\t\tlet failure;\n\t\t/** A failed call fails the attempt even when `fn` catches it. */\n\t\tconst step = (method) => (...args) => {\n\t\t\tif (!open) throw new DatabaseTransactionError(\"The transaction has ended.\");\n\t\t\tconst fail = (error) => {\n\t\t\t\tfailure ??= { error };\n\t\t\t\tthrow error;\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = method(...args);\n\t\t\t\treturn result instanceof Promise ? result.catch(fail) : result;\n\t\t\t} catch (error) {\n\t\t\t\treturn fail(error);\n\t\t\t}\n\t\t};\n\t\tconst remember = (model, key, row) => {\n\t\t\tconst id = idOf(model.table.name, key);\n\t\t\tconst known = read.get(id);\n\t\t\tif (known !== void 0 && (known && row ? versionOf(known) !== versionOf(row) : known !== row)) throw new StaleReadError();\n\t\t\tread.set(id, row);\n\t\t\treturn row;\n\t\t};\n\t\tconst readRow = ({ table }, row) => {\n\t\t\tconst id = idOf(table.name, rowKey(table, row));\n\t\t\tconst known = read.get(id) ?? ranged.get(id);\n\t\t\tif (known && versionOf(known) === versionOf(row)) return known;\n\t\t\tthrow misuse(table.name, \"update and delete take a row this transaction read.\");\n\t\t};\n\t\tconst checkFields = ({ table, definition: { fields } }, values, creating) => {\n\t\t\tfor (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\"}.`);\n\t\t\tfor (const [field, { required }] of Object.entries(fields)) if (required !== false && (creating || field in values) && !isKeyed(values[field])) throw misuse(table.name, `${field} is required.`);\n\t\t};\n\t\t/** Adds counter deltas to a key's pending op; an empty `by` still bumps `_v`. */\n\t\tconst bump = (model, key, by) => {\n\t\t\tconst id = idOf(model.table.name, key);\n\t\t\tconst pending = writes.get(id);\n\t\t\tif (pending === void 0) writes.set(id, {\n\t\t\t\tmodel,\n\t\t\t\tkey,\n\t\t\t\ttype: \"increment\",\n\t\t\t\trow: { ...by }\n\t\t\t});\n\t\t\telse if (pending.type !== \"delete\") for (const [column, delta] of Object.entries(by)) pending.row[column] = Number(pending.row[column] ?? pending.read?.[column] ?? 0) + delta;\n\t\t\telse if (Object.values(by).some((delta) => delta > 0)) throw new DatabaseConstraintError(\"not_found\", model.table.name);\n\t\t};\n\t\t/** Moves parent counters when a reference changes and bumps every rooted parent. */\n\t\tconst touchParents = (model, before, after) => {\n\t\t\tfor (const { field, counter, target } of model.references) {\n\t\t\t\tconst [from, to] = [before?.[field], after?.[field]];\n\t\t\t\tif (counter === void 0 || from === to) continue;\n\t\t\t\tif (isKeyed(from)) bump(modelOf(target), [from], { [counter]: -1 });\n\t\t\t\tif (isKeyed(to)) bump(modelOf(target), [to], { [counter]: 1 });\n\t\t\t}\n\t\t\tfor (const [index, root] of model.roots) {\n\t\t\t\tconst parent = modelOf(root);\n\t\t\t\tconst { eq } = model.table.indexes.find(({ name }) => name === index);\n\t\t\t\tfor (const row of [before, after]) {\n\t\t\t\t\tconst key = eq.slice(0, parent.table.key.length).map((field) => row?.[field]);\n\t\t\t\t\tif (row && key.every(isKeyed)) bump(parent, key, {});\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tconst derive = ({ definition }, row) => {\n\t\t\tif (definition.kind === \"table\") for (const [name, derived] of Object.entries(definition.derived)) row[name] = derived.compute(row);\n\t\t\treturn row;\n\t\t};\n\t\t/** Deletes a row after its cascaded children, or refuses a restricted delete. */\n\t\tconst remove = async (model, known) => {\n\t\t\tconst { table } = model;\n\t\t\tconst key = rowKey(table, known);\n\t\t\tconst id = idOf(table.name, key);\n\t\t\tconst pending = writes.get(id);\n\t\t\tif (pending?.type === \"delete\") return;\n\t\t\tif (pending && pending.type !== \"increment\") throw once(table.name);\n\t\t\twrites.set(id, {\n\t\t\t\tmodel,\n\t\t\t\tkey,\n\t\t\t\ttype: \"delete\",\n\t\t\t\trow: {},\n\t\t\t\tread: known\n\t\t\t});\n\t\t\ttouchParents(model, known, null);\n\t\t\tfor (const reference of model.referencedBy) {\n\t\t\t\tconst { counter, field, onDelete, table: name } = reference;\n\t\t\t\tif (counter === void 0) continue;\n\t\t\t\tconst stored = Number(known[counter] ?? 0);\n\t\t\t\tconst added = Number(pending?.row[counter] ?? 0);\n\t\t\t\tif (added > 0) throw new DatabaseConstraintError(\"referenced\", table.name);\n\t\t\t\tif (stored + added <= 0) continue;\n\t\t\t\tif (onDelete === \"restrict\") {\n\t\t\t\t\tconst [current] = await adapter.get(table, [key]);\n\t\t\t\t\tif (current && versionOf(current) === versionOf(known)) throw new DatabaseConstraintError(\"referenced\", table.name);\n\t\t\t\t\tthrow new StaleReadError();\n\t\t\t\t}\n\t\t\t\tconst child = modelOf(name);\n\t\t\t\tconst index = child.table.indexes.find(({ eq }) => eq.length === 1 && eq[0] === field);\n\t\t\t\tlet cursor;\n\t\t\t\tlet seen = 0;\n\t\t\t\tdo {\n\t\t\t\t\tconst page = await reads.findMany(name, {\n\t\t\t\t\t\tindex: index.name,\n\t\t\t\t\t\twhere: { [field]: key[0] },\n\t\t\t\t\t\tlimit: Math.min(stored - seen, reads.maxPageSize),\n\t\t\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t\t\t});\n\t\t\t\t\tfor (const row of await complete(child, page.rows)) {\n\t\t\t\t\t\tremember(child, rowKey(child.table, row), row);\n\t\t\t\t\t\tawait remove(child, row);\n\t\t\t\t\t}\n\t\t\t\t\tseen += page.rows.length;\n\t\t\t\t\tcursor = page.next;\n\t\t\t\t} while (cursor !== void 0 && seen < stored);\n\t\t\t}\n\t\t\tdeleted.push(id);\n\t\t};\n\t\tconst tx = {\n\t\t\tfindOne: step(async (name, lookup) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst { table } = model;\n\t\t\t\tconst found = await reads.findOne(name, lookup);\n\t\t\t\tif (found === null && !table.key.every((field) => field in lookup)) return null;\n\t\t\t\tconst [row = null] = found ? await complete(model, [found]) : [];\n\t\t\t\tconst key = row ? rowKey(table, row) : table.key.map((field) => lookup[field]);\n\t\t\t\treturn remember(model, key, row);\n\t\t\t}),\n\t\t\tfindMany: step(async (name, input) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst root = model.roots.get(input.index);\n\t\t\t\tif (root === void 0) throw new DatabaseQueryError(`${name}.${input.index} is not rooted; a transaction reads a range only under a guarded parent.`);\n\t\t\t\tconst parent = modelOf(root);\n\t\t\t\tconst { eq } = model.table.indexes.find(({ name: index }) => index === input.index);\n\t\t\t\tconst where = input.where ?? {};\n\t\t\t\tconst lookup = Object.fromEntries(parent.table.key.map((field, at) => [field, where[eq[at]]]));\n\t\t\t\tremember(parent, Object.values(lookup), await reads.findOne(root, lookup));\n\t\t\t\tconst found = await reads.findMany(name, input);\n\t\t\t\tconst rows = await complete(model, found.rows);\n\t\t\t\tfor (const row of rows) ranged.set(idOf(name, rowKey(model.table, row)), row);\n\t\t\t\treturn {\n\t\t\t\t\t...found,\n\t\t\t\t\trows\n\t\t\t\t};\n\t\t\t}),\n\t\t\tcreate: step((name, values) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tcheckFields(model, values, true);\n\t\t\t\tconst defaults = model.table.columns.flatMap((column) => column.nullable || column.default !== void 0 ? [[column.name, column.default ?? null]] : []);\n\t\t\t\tconst row = derive(model, {\n\t\t\t\t\t...Object.fromEntries(defaults),\n\t\t\t\t\t...values\n\t\t\t\t});\n\t\t\t\tconst key = rowKey(model.table, row);\n\t\t\t\tconst id = idOf(name, key);\n\t\t\t\tconst pending = writes.get(id);\n\t\t\t\tif (pending && pending.type !== \"increment\") throw once(name);\n\t\t\t\tfor (const [column, delta] of Object.entries(pending?.row ?? {})) row[column] = Number(row[column]) + Number(delta);\n\t\t\t\twrites.set(id, {\n\t\t\t\t\tmodel,\n\t\t\t\t\tkey,\n\t\t\t\t\ttype: \"insert\",\n\t\t\t\t\trow\n\t\t\t\t});\n\t\t\t\ttouchParents(model, null, row);\n\t\t\t}),\n\t\t\tupdate: step((name, row, set) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst known = readRow(model, row);\n\t\t\t\tcheckFields(model, set, false);\n\t\t\t\tconst key = rowKey(model.table, known);\n\t\t\t\tconst id = idOf(name, key);\n\t\t\t\tconst pending = writes.get(id);\n\t\t\t\tif (pending?.type === \"insert\" || pending?.type === \"delete\") throw once(name);\n\t\t\t\tconst before = pending?.type === \"patch\" ? {\n\t\t\t\t\t...known,\n\t\t\t\t\t...pending.row\n\t\t\t\t} : known;\n\t\t\t\tconst next = derive(model, {\n\t\t\t\t\t...before,\n\t\t\t\t\t...set\n\t\t\t\t});\n\t\t\t\tconst changed = Object.entries(next).filter(([column, value]) => column !== \"_v\" && JSON.stringify(value) !== JSON.stringify(known[column]));\n\t\t\t\tconst patch = Object.fromEntries(changed);\n\t\t\t\twrites.set(id, {\n\t\t\t\t\tmodel,\n\t\t\t\t\tkey,\n\t\t\t\t\ttype: \"patch\",\n\t\t\t\t\trow: patch,\n\t\t\t\t\tread: known\n\t\t\t\t});\n\t\t\t\tif (pending?.type === \"increment\") bump(model, key, pending.row);\n\t\t\t\ttouchParents(model, before, next);\n\t\t\t}),\n\t\t\tdelete: step(async (name, row) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tawait remove(model, readRow(model, row));\n\t\t\t}),\n\t\t\taggregate: step((name, identity, values, options) => {\n\t\t\t\tconst model = modelOf(name, \"aggregate\");\n\t\t\t\trecordAggregate(aggregates, model, identity, values, options?.shardBy);\n\t\t\t})\n\t\t};\n\t\ttry {\n\t\t\tconst result = await (transactionScope ? transactionScope.run(tx, () => fn(tx)) : fn(tx));\n\t\t\tif (failure) throw failure.error;\n\t\t\treturn {\n\t\t\t\tresult,\n\t\t\t\tread,\n\t\t\t\tops: compile(writes, read, deleted),\n\t\t\t\taggregates: [...aggregates.values()]\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow failure?.error instanceof StaleReadError ? failure.error : error;\n\t\t} finally {\n\t\t\topen = false;\n\t\t}\n\t};\n\t/** Inserts first, then patches and increments, then checks, then deletes, children before parents. */\n\tconst compile = (writes, read, deleted) => {\n\t\tconst toOp = (id) => {\n\t\t\tconst { model, key, type, row, read: previous } = writes.get(id);\n\t\t\tconst { table } = model;\n\t\t\tif (type === \"insert\") return {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\trow\n\t\t\t};\n\t\t\tif (type === \"increment\") {\n\t\t\t\tconst known = read.get(id);\n\t\t\t\tconst by = row;\n\t\t\t\treturn known ? {\n\t\t\t\t\ttype,\n\t\t\t\t\ttable,\n\t\t\t\t\tkey,\n\t\t\t\t\tby,\n\t\t\t\t\tguard: { v: versionOf(known) }\n\t\t\t\t} : {\n\t\t\t\t\ttype,\n\t\t\t\t\ttable,\n\t\t\t\t\tkey,\n\t\t\t\t\tby\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst guard = { v: versionOf(previous) };\n\t\t\treturn type === \"patch\" ? {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tset: row,\n\t\t\t\tguard,\n\t\t\t\tprevious\n\t\t\t} : {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tguard,\n\t\t\t\tprevious\n\t\t\t};\n\t\t};\n\t\tconst checks = [...read].flatMap(([id, row]) => {\n\t\t\tif (row === null || writes.has(id)) return [];\n\t\t\tconst { table } = schema.models.get(JSON.parse(id)[0]);\n\t\t\tconst guard = { v: versionOf(row) };\n\t\t\treturn [{\n\t\t\t\ttype: \"check\",\n\t\t\t\ttable,\n\t\t\t\tkey: rowKey(table, row),\n\t\t\t\tguard\n\t\t\t}];\n\t\t});\n\t\tconst ofType = (...types) => [...writes.keys()].filter((id) => types.includes(writes.get(id).type));\n\t\treturn [\n\t\t\t...[...ofType(\"insert\"), ...ofType(\"patch\", \"increment\")].map(toOp),\n\t\t\t...checks,\n\t\t\t...deleted.map(toOp)\n\t\t];\n\t};\n\t/** Only a constraint the current state confirms is reported; anything else reruns. */\n\tconst classify = async (op, read) => {\n\t\tif (op.type === \"check\" || op.type === \"delete\") return void 0;\n\t\tif (op.type === \"increment\" && op.guard) return void 0;\n\t\tconst { table } = op;\n\t\tconst key = op.type === \"insert\" ? rowKey(table, op.row) : op.key;\n\t\tconst [current] = await adapter.get(table, [key]);\n\t\tif (op.type === \"increment\") return current ? void 0 : \"not_found\";\n\t\tif (op.type === \"insert\" && current) {\n\t\t\tconst known = read.get(idOf(table.name, key));\n\t\t\treturn known === null || known !== void 0 && versionOf(known) !== versionOf(current) ? void 0 : \"exists\";\n\t\t}\n\t\tif (op.type === \"patch\" && current?.[\"_v\"] !== op.guard.v) return;\n\t\tconst row = op.type === \"insert\" ? op.row : {\n\t\t\t...current,\n\t\t\t...op.set\n\t\t};\n\t\tfor (const index of table.indexes) {\n\t\t\tif (!index.unique) continue;\n\t\t\tfor (const eq of indexEntries(table, index, row)) if ((await adapter.query(table, {\n\t\t\t\tindex: index.name,\n\t\t\t\teq,\n\t\t\t\torder: \"asc\",\n\t\t\t\tlimit: 2\n\t\t\t})).some((other) => compareTuples(rowKey(table, other), key))) return \"unique\";\n\t\t}\n\t};\n\treturn { async transaction(fn) {\n\t\tassertOutsideTransaction();\n\t\tlet run;\n\t\tlet negative;\n\t\tfor (let round = 0; round < attempts; round += 1) {\n\t\t\tconst delay = round && Math.min(maxDelayMs, baseDelayMs * 2 ** (round - 1));\n\t\t\tif (delay > 0) await new Promise((resolve) => setTimeout(resolve, delay / 2 + Math.random() * (delay / 2)));\n\t\t\trun ??= await attempt(fn).catch((error) => {\n\t\t\t\tif (error instanceof StaleReadError) return void 0;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\tif (run === void 0) {\n\t\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet aggregates;\n\t\t\ttry {\n\t\t\t\taggregates = await compileAggregates(adapter, run.aggregates);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof NegativeGaugeError)) throw error;\n\t\t\t\tnegative = error;\n\t\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\t\trun = void 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ops = [...run.ops, ...aggregates];\n\t\t\tif (ops.length <= 1 && ops.every(({ type }) => type === \"check\")) return run.result;\n\t\t\tif (!adapter.fits(ops)) throw new DatabaseConstraintError(\"too_large\", ops[0].table.name);\n\t\t\tlet outcome;\n\t\t\ttry {\n\t\t\t\toutcome = await adapter.write(ops);\n\t\t\t} catch (cause) {\n\t\t\t\tthrow new DatabaseAmbiguousCommitError(\"The commit outcome is unknown.\", { cause });\n\t\t\t}\n\t\t\tif (outcome.ok) return run.result;\n\t\t\tconst failed = \"failedOp\" in outcome ? outcome.failedOp : void 0;\n\t\t\tif (failed === void 0 || failed >= run.ops.length) {\n\t\t\t\tonRetry?.(\"resend\", round + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst reason = await classify(ops[failed], run.read);\n\t\t\tif (reason) throw new DatabaseConstraintError(reason, ops[failed].table.name);\n\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\trun = void 0;\n\t\t}\n\t\tthrow negative ?? new DatabaseConflictError(`The transaction conflicted ${attempts} times.`);\n\t} };\n};\n//#endregion\nexport { assertOutsideTransaction, createTransactions };\n", "import { DatabaseQueryError } from \"../../serverPlugin/errors.mjs\";\nimport { mergeDistinct } from \"../../database/distinct.mjs\";\nimport { indexOrderColumns } from \"../../database/adapter.mjs\";\nimport { indexOrderTuple, isKeyValue } from \"../../database/values.mjs\";\nimport { cursorScope, decodeCursor, encodeCursor } from \"./cursor.mjs\";\nimport { SHARD_COLUMN } from \"./resolveSchema.mjs\";\n//#region src/engine/database/engineReads.ts\nconst sameFields = (left, right) => left.length === right.length && left.every((field) => right.includes(field));\nconst keyValue = (value, field) => {\n\tif (isKeyValue(value)) return value;\n\tthrow new DatabaseQueryError(`${field} needs a string, number, or boolean.`);\n};\nconst bound = (exclusive, inclusive, columns) => {\n\tif (exclusive !== void 0 && inclusive !== void 0) throw new DatabaseQueryError(`range on ${columns[0]} sets both bounds of one side.`);\n\tconst value = exclusive ?? inclusive;\n\tif (value === void 0) return void 0;\n\tconst values = Array.isArray(value) ? value : [value];\n\tif (values.length === 0 || values.length > columns.length) throw new DatabaseQueryError(`range on ${columns[0]} takes 1\u2013${columns.length} values of ${columns.join(\", \")}.`);\n\treturn {\n\t\tvalues: values.map((item, position) => keyValue(item, columns[position])),\n\t\tinclusive: inclusive !== void 0\n\t};\n};\nconst createEngineReads = ({ adapter, schema, maxPageSize: requested = 500 }) => {\n\tconst maxPageSize = Math.min(requested, 500);\n\tlet count = {\n\t\tcalls: 0,\n\t\trows: 0\n\t};\n\tconst returned = (rows) => {\n\t\tconst size = Array.isArray(rows) ? rows.length : rows === null ? 0 : 1;\n\t\tcount = {\n\t\t\tcalls: count.calls + 1,\n\t\t\trows: count.rows + size\n\t\t};\n\t\treturn rows;\n\t};\n\t/** A model of `kind` by physical table name, for reads and transactions. */\n\tconst modelOf = (name, kind = \"table\") => {\n\t\tconst model = schema.models.get(name);\n\t\tif (model?.definition.kind === kind) return model;\n\t\tthrow 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.`);\n\t};\n\tconst plan = ({ table }, input) => {\n\t\tconst index = table.indexes.find(({ name }) => name === input.index);\n\t\tif (index === void 0) throw new DatabaseQueryError(`${table.name} has no index ${input.index}.`);\n\t\tconst where = input.where ?? {};\n\t\tif (!sameFields(Object.keys(where), index.eq)) throw new DatabaseQueryError(`${table.name}.${index.name} reads need where on exactly: ${index.eq.join(\", \") || \"(none)\"}.`);\n\t\tconst { limit, order = \"asc\", range } = input;\n\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxPageSize) throw new DatabaseQueryError(`limit must be 1\u2013${maxPageSize}.`);\n\t\tconst columns = indexOrderColumns(table, index);\n\t\tconst eq = index.eq.map((field) => keyValue(where[field], `${table.name}.${field}`));\n\t\tconst scope = cursorScope([\n\t\t\ttable.name,\n\t\t\tindex.name,\n\t\t\teq,\n\t\t\torder,\n\t\t\trange\n\t\t]);\n\t\tlet lower = bound(range?.gt, range?.gte, columns);\n\t\tlet upper = bound(range?.lt, range?.lte, columns);\n\t\tif (input.cursor !== void 0) {\n\t\t\tconst values = decodeCursor(scope, input.cursor);\n\t\t\tif (order === \"asc\") lower = {\n\t\t\t\tvalues,\n\t\t\t\tinclusive: false\n\t\t\t};\n\t\t\telse upper = {\n\t\t\t\tvalues,\n\t\t\t\tinclusive: false\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\trequest: {\n\t\t\t\tindex: index.name,\n\t\t\t\teq,\n\t\t\t\torder,\n\t\t\t\tlimit,\n\t\t\t\t...lower === void 0 ? {} : { lower },\n\t\t\t\t...upper === void 0 ? {} : { upper }\n\t\t\t},\n\t\t\tindex,\n\t\t\tscope\n\t\t};\n\t};\n\t/** Reads rows by key in one batch; the results follow the keys' order. */\n\tconst findByKeys = async (name, lookups) => {\n\t\tconst { table } = modelOf(name, \"table\");\n\t\tconst keys = lookups.map((lookup) => {\n\t\t\tif (!sameFields(Object.keys(lookup), table.key)) throw new DatabaseQueryError(`findByKeys on ${name} takes its key: ${table.key.join(\", \")}.`);\n\t\t\treturn table.key.map((field) => keyValue(lookup[field], `${name}.${field}`));\n\t\t});\n\t\tconst rows = keys.length === 0 ? [] : await adapter.get(table, keys);\n\t\treturned(rows.filter((row) => row !== null));\n\t\treturn rows.map((row) => row ?? null);\n\t};\n\treturn {\n\t\tmaxPageSize,\n\t\tmodelOf,\n\t\treads: {\n\t\t\ttotal: () => count,\n\t\t\treset: () => {\n\t\t\t\tcount = {\n\t\t\t\t\tcalls: 0,\n\t\t\t\t\trows: 0\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\tfindByKeys,\n\t\t/** Reads one row by its key or by the eq fields of a unique index. */\n\t\tasync findOne(name, lookup) {\n\t\t\tconst { table } = modelOf(name, \"table\");\n\t\t\tconst fields = Object.keys(lookup);\n\t\t\tif (sameFields(fields, table.key)) return (await findByKeys(name, [lookup]))[0];\n\t\t\tconst index = table.indexes.find(({ unique, eq }) => unique && sameFields(fields, eq));\n\t\t\tif (index === void 0) throw new DatabaseQueryError(`findOne on ${name} needs its key or a unique field, not ${fields.join(\", \")}.`);\n\t\t\tconst [row] = await adapter.query(table, {\n\t\t\t\tindex: index.name,\n\t\t\t\teq: index.eq.map((field) => keyValue(lookup[field], `${name}.${field}`)),\n\t\t\t\torder: \"asc\",\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn returned(row ?? null);\n\t\t},\n\t\t/** Reads one page of an index range; `next` resumes right after it. */\n\t\tasync findMany(name, input) {\n\t\t\tconst model = modelOf(name, \"table\");\n\t\t\tconst { request, index, scope } = plan(model, input);\n\t\t\tconst rows = returned(await adapter.query(model.table, request));\n\t\t\tconst last = rows.at(-1);\n\t\t\treturn rows.length === input.limit && last !== void 0 ? {\n\t\t\t\trows,\n\t\t\t\tnext: encodeCursor(scope, indexOrderTuple(model.table, index, last))\n\t\t\t} : { rows };\n\t\t},\n\t\t/**\n\t\t* Reads one page of logical aggregate rows, summing counters and gauges\n\t\t* and merging sketches across each row's shards. A row cut off by the\n\t\t* limit is completed by reading only its remaining shards.\n\t\t*/\n\t\tasync findAggregates(name, input) {\n\t\t\tconst model = modelOf(name, \"aggregate\");\n\t\t\tconst { table, definition } = model;\n\t\t\tif (definition.kind !== \"aggregate\") throw new DatabaseQueryError(name);\n\t\t\tconst { request, index, scope } = plan(model, input);\n\t\t\tconst rows = await adapter.query(table, request);\n\t\t\tconst logicalKey = (row) => definition.key.map((column) => keyValue(row[column], column));\n\t\t\tconst groups = /* @__PURE__ */ new Map();\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst key = JSON.stringify(logicalKey(row));\n\t\t\t\tgroups.set(key, [...groups.get(key) ?? [], row]);\n\t\t\t}\n\t\t\tconst full = rows.length === input.limit;\n\t\t\tconst last = [...groups.values()].at(-1);\n\t\t\tif (full && last !== void 0) {\n\t\t\t\tconst seen = new Set(last.map((row) => row[SHARD_COLUMN]));\n\t\t\t\tconst missing = Array.from({ length: definition.shards }, (_, shard) => shard).filter((shard) => !seen.has(shard));\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\tconst key = logicalKey(last[0]);\n\t\t\t\t\tconst rest = await adapter.get(table, missing.map((shard) => [...key, shard]));\n\t\t\t\t\tlast.push(...rest.filter((row) => row !== null));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst merged = [...groups.values()].map((shards) => {\n\t\t\t\tconst row = Object.fromEntries(definition.key.map((field) => [field, shards[0][field]]));\n\t\t\t\tfor (const metric of [...definition.counters, ...definition.gauges]) row[metric] = shards.reduce((sum, shard) => sum + Number(shard[metric] ?? 0), 0);\n\t\t\t\tfor (const metric of definition.distinct) row[metric] = mergeDistinct(shards.map((shard) => shard[metric]));\n\t\t\t\treturn row;\n\t\t\t});\n\t\t\treturned(merged);\n\t\t\tif (!full || last === void 0) return { rows: merged };\n\t\t\tconst tuple = indexOrderTuple(table, index, last[0]);\n\t\t\treturn {\n\t\t\t\trows: merged,\n\t\t\t\tnext: encodeCursor(scope, tuple.slice(0, -1))\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { DatabaseQueryError, createEngineReads };\n", "import { verifyAdapter } from \"../../database/verifyAdapter.mjs\";\nimport { createEngineReads } from \"./engineReads.mjs\";\nimport { createTransactions } from \"./engineTransaction.mjs\";\n//#region src/engine/database/engine.ts\n/** Storage semantics over one adapter, addressed by physical table name. */\nconst createStorageEngine = ({ adapter: given, schema, maxPageSize, verify, retry }) => {\n\tconst verified = verify ? verifyAdapter(given) : void 0;\n\tconst adapter = verified ?? given;\n\tconst reads = createEngineReads({\n\t\tadapter,\n\t\tschema,\n\t\tmaxPageSize\n\t});\n\tconst { transaction } = createTransactions({\n\t\tadapter,\n\t\tschema,\n\t\treads,\n\t\tretry\n\t});\n\treturn {\n\t\treads,\n\t\ttransaction,\n\t\t/** Runs `read` and reports what it read at both boundaries (verify mode only). */\n\t\tasync measureReads(read) {\n\t\t\tif (verified === void 0) throw new Error(\"measureReads needs an engine created with verify: true.\");\n\t\t\tverified.reads.reset();\n\t\t\treads.reads.reset();\n\t\t\treturn {\n\t\t\t\tresult: await read(),\n\t\t\t\tadapter: verified.reads.total(),\n\t\t\t\tengine: reads.reads.total()\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { createStorageEngine };\n", "import \"../../database/adapter.mjs\";\nimport { createAggregateBatches } from \"./aggregateBatching.mjs\";\nimport { assertOutsideTransaction } from \"./engineTransaction.mjs\";\nimport { createStorageEngine } from \"./engine.mjs\";\n//#region src/engine/database/database.ts\n/** The engine plus `database(module)`, which hands a module its typed handle. */\nconst createDatabaseEngine = ({ batching, now = Date.now, meter, ...options }) => {\n\tconst adapter = meter ? meter.wrap(options.adapter) : options.adapter;\n\tconst engine = createStorageEngine({\n\t\t...options,\n\t\tadapter\n\t});\n\tconst { reads } = engine;\n\tmeter?.attach(reads.reads);\n\tconst batches = batching && createAggregateBatches({\n\t\tengine,\n\t\tadapter,\n\t\tschema: options.schema,\n\t\tbatching,\n\t\tnow\n\t});\n\tconst transaction = batches?.transaction ?? engine.transaction;\n\tconst outside = (read) => (...args) => {\n\t\tassertOutsideTransaction();\n\t\treturn read(...args);\n\t};\n\t/** No read outside a transaction returns `_v`, which a key-value index copy lacks. */\n\tconst bare = (row) => row && Object.fromEntries(Object.entries(row).filter(([column]) => column !== \"_v\"));\n\tconst barePage = async (page) => {\n\t\tconst { rows, next } = await page;\n\t\treturn {\n\t\t\trows: rows.map(bare),\n\t\t\t...next === void 0 ? {} : { next }\n\t\t};\n\t};\n\treturn {\n\t\t...engine,\n\t\t/** Applies batched aggregate changes still pending: this process's buffer and the log. */\n\t\tflush: async () => {\n\t\t\tawait batches?.flush();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait batches?.dispose();\n\t\t},\n\t\tdatabase(module) {\n\t\t\tconst name = (model) => module.namespace ? `${module.namespace}_${model}` : model;\n\t\t\treturn {\n\t\t\t\tfindOne: outside(async (model, lookup) => bare(await reads.findOne(name(model), lookup))),\n\t\t\t\tfindByKeys: outside(async (model, keys) => (await reads.findByKeys(name(model), keys)).map(bare)),\n\t\t\t\tfindMany: outside((model, input) => barePage(reads.findMany(name(model), input))),\n\t\t\t\tfindAggregates: outside(async (model, input) => {\n\t\t\t\t\tawait batches?.beforeRead(name(model));\n\t\t\t\t\treturn await barePage(reads.findAggregates(name(model), input));\n\t\t\t\t}),\n\t\t\t\ttransaction: (fn) => transaction((tx) => fn({\n\t\t\t\t\tfindOne: (model, lookup) => tx.findOne(name(model), lookup),\n\t\t\t\t\tfindMany: (model, input) => tx.findMany(name(model), input),\n\t\t\t\t\tcreate: (model, row) => tx.create(name(model), row),\n\t\t\t\t\tupdate: (model, row, set) => tx.update(name(model), row, set),\n\t\t\t\t\tdelete: (model, row) => tx.delete(name(model), row),\n\t\t\t\t\taggregate: (model, identity, changes, options) => tx.aggregate(name(model), identity, changes, options)\n\t\t\t\t}))\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { createDatabaseEngine };\n", "import { HotUpdaterConfigError } from \"../serverPlugin/configError.mjs\";\nimport { coreModule } from \"./core/schema.mjs\";\nimport { aggregateBatchingModule } from \"./database/aggregateBatching.mjs\";\nimport { pruneDuringWrites } from \"./database/retention.mjs\";\nimport { resolveSchema, validateSchema } from \"./database/resolveSchema.mjs\";\nimport { createDatabaseEngine } from \"./database/database.mjs\";\nimport { SETTINGS_TABLE, fencedName, withSchemaFence } from \"./database/fence.mjs\";\nimport { readMeterOf } from \"./database/readMeter.mjs\";\nimport { pluginModule, pluginSettings } from \"./db/coreDatabase.mjs\";\n//#region src/engine/createEngine.ts\n/**\n* How to create plugins' tables on a database, by the tooling it offers:\n* what the plugins' schema fence names when their settings rows are missing.\n*/\nconst pluginTablesFix = (database) => {\n\tconst { createMigrator, generateSchema } = database;\n\tconst managed = \"A managed server runs only its provider's plugins, and rerunning `hot-updater init --provider <provider>` applies the provider's migrations.\";\n\tconst serverProject = \"Run `hot-updater db` commands in the server's project: they load the server file named on the command line, or src/hotUpdater.* or src/db.*, and don't read hot-updater.config.ts.\";\n\treturn createMigrator !== void 0 ? `Run \\`hot-updater db migrate\\`. ${managed} ${serverProject}` : generateSchema !== void 0 ? `Run \\`hot-updater db generate\\` and apply the file it writes. ${managed} ${serverProject}` : managed;\n};\n/**\n* The storage engine over a database, as a server runs it: core's tables\n* and the plugins', with the plugins' settings rows fenced on a fenced\n* database, expired rows pruned during writes, aggregates batched when the\n* database batches them, and reads metered when it came from `meterReads`.\n* `createHotUpdater` runs core and its plugins on one; tests and tools run\n* a plugin on one without a server. Wrap the adapter with `verifyAdapter`\n* to check every call against the adapter contract.\n*/\nconst createEngine = (database, { plugins = [], now = Date.now } = {}) => {\n\tconst modules = /* @__PURE__ */ new Map();\n\tfor (const plugin of plugins) {\n\t\tif (plugin.id === coreModule.id) throw new HotUpdaterConfigError(`Plugin id \"${plugin.id}\" is core's own.`);\n\t\tif (modules.has(plugin.id)) throw new HotUpdaterConfigError(`Plugin \"${plugin.id}\" is registered twice.`);\n\t\tmodules.set(plugin.id, pluginModule(plugin));\n\t}\n\tif (modules.size > 0) validateSchema([coreModule, ...modules.values()]);\n\tconst name = fencedName(database.adapter);\n\tconst fenced = name === void 0 || plugins.length === 0 ? database.adapter : withSchemaFence(database.adapter, name, pluginSettings(plugins), pluginTablesFix(database));\n\tconst batching = database.aggregateBatching;\n\tconst schema = resolveSchema([\n\t\tcoreModule,\n\t\t...modules.values(),\n\t\t...batching === void 0 ? [] : [aggregateBatchingModule]\n\t]);\n\tconst meter = readMeterOf(database);\n\tconst engine = createDatabaseEngine({\n\t\tadapter: pruneDuringWrites(fenced, schema.tables, {\n\t\t\tleaseTable: SETTINGS_TABLE,\n\t\t\tnow\n\t\t}),\n\t\tschema,\n\t\t...database.retry === void 0 ? {} : { retry: database.retry },\n\t\t...batching === void 0 ? {} : {\n\t\t\tbatching,\n\t\t\tnow\n\t\t},\n\t\t...meter === void 0 ? {} : { meter }\n\t});\n\treturn {\n\t\tcore: engine.database(coreModule),\n\t\tdatabase: (plugin) => {\n\t\t\tconst module = modules.get(plugin.id);\n\t\t\tif (module === void 0) throw new HotUpdaterConfigError(`Plugin \"${plugin.id}\" is not one of this engine's plugins.`);\n\t\t\treturn engine.database(module);\n\t\t},\n\t\tflush: () => engine.flush(),\n\t\tdispose: () => engine.dispose()\n\t};\n};\n//#endregion\nexport { createEngine };\n", "import { findPhysicalColumn, findPhysicalIndex, indexOrderColumns, rowKey } from \"../../../database/adapter.mjs\";\nimport { indexEntries, indexOrderTuple, normalizeStoredRow } from \"../../../database/values.mjs\";\nimport { createTableStatements, isMultiIndex, pruneStatements, quoteSql } from \"./sqlSchema.mjs\";\n//#region src/engine/database/sql/sqlAdapter.ts\n/** Where a batch write records its first failed op, before any change applies. */\nconst WRITE_GUARD_TABLE = {\n\tname: \"_hu_write\",\n\tcolumns: [{\n\t\tname: \"id\",\n\t\ttype: \"string\",\n\t\tnullable: false,\n\t\tmaxLength: 36\n\t}, {\n\t\tname: \"failed_op\",\n\t\ttype: \"integer\",\n\t\tnullable: true\n\t}],\n\tkey: [\"id\"],\n\tindexes: []\n};\nconst codes = (values) => new Set(values.split(\" \"));\nconst UNIQUE = codes(\"23505 1062 23503 1451 1452 SQLITE_CONSTRAINT_UNIQUE SQLITE_CONSTRAINT_PRIMARYKEY SQLITE_CONSTRAINT_FOREIGNKEY SQLITE:2067 SQLITE:1555 SQLITE:787\");\nconst RETRY = codes(\"40001 40P01 1213 1205 SQLITE_BUSY SQLITE_BUSY_SNAPSHOT SQLITE_LOCKED SQLITE:5 SQLITE:517 SQLITE:6\");\n/** Driver codes on an error and its causes: SQLSTATE, MySQL errno, SQLite codes. */\nconst codesOf = (error, depth = 0) => {\n\tif (typeof error !== \"object\" || error === null || depth > 3) return [];\n\tconst record = error;\n\tconst named = [\n\t\t\"code\",\n\t\t\"errno\",\n\t\t\"sqlState\",\n\t\t\"extendedCode\"\n\t].flatMap((field) => record[field] === void 0 ? [] : [String(record[field])]);\n\tconst sqlite = [\"errcode\", \"rawCode\"].flatMap((field) => typeof record[field] === \"number\" ? [`SQLITE:${record[field]}`] : []);\n\treturn [\n\t\t...named,\n\t\t...sqlite,\n\t\t...codesOf(record.cause, depth + 1)\n\t];\n};\n/** A constraint names the failed op; a transient error asks the engine to retry. */\nconst classifySqlError = (error) => {\n\tconst found = codesOf(error);\n\tif (found.some((code) => UNIQUE.has(code))) return \"constraint\";\n\treturn found.some((code) => RETRY.has(code)) ? \"retry\" : void 0;\n};\n/** An increment that creates its missing row: an upsert, which always applies. */\nconst upserts = (op) => op.type === \"increment\" && op.init !== void 0 && op.guard === void 0;\nvar FailedOp = class {\n\tindex;\n\tconstructor(index) {\n\t\tthis.index = index;\n\t}\n};\n/**\n* The shared SQL core over one executor: each write compiles to statements\n* run in one transaction, or in one atomic batch where the executor batches.\n*/\nconst createSqlAdapter = ({ executor, tablePrefix = \"\", maxOps = 1e3, maxParams = Number.POSITIVE_INFINITY }) => {\n\tconst { dialect } = executor;\n\tconst postgres = dialect === \"postgresql\";\n\tconst sqlite = dialect === \"sqlite\";\n\tconst lock = sqlite ? \"\" : \" FOR UPDATE\";\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst tableOf = (table, index) => quote(`${tablePrefix}${table.name}${index ? `__${index.name}` : \"\"}`);\n\tconst version = quote(\"_v\");\n\t/** A statement from `build`, whose `bind` collects parameters in order. */\n\tconst sql = (build) => {\n\t\tconst params = [];\n\t\tconst bind = (value, column) => {\n\t\t\tconst json = column?.multi || column?.type === \"json\";\n\t\t\tparams.push(value === null || value === void 0 ? null : json ? JSON.stringify(value) : typeof value === \"boolean\" && !postgres ? Number(value) : value);\n\t\t\treturn postgres ? `$${params.length}${json ? \"::jsonb\" : \"\"}` : \"?\";\n\t\t};\n\t\treturn {\n\t\t\tsql: build(bind),\n\t\t\tparams\n\t\t};\n\t};\n\t/** Each key column equal to its value in `key`. */\n\tconst keyMatch = (bind, table, key) => table.key.map((column, position) => `${quote(column)} = ${bind(key[position])}`).join(\" AND \");\n\t/** `columns op values` over a tuple prefix, expanded into ORs on MySQL. */\n\tconst compare = (bind, columns, bound, op) => {\n\t\tconst cols = columns.slice(0, bound.values.length).map((column) => `i.${quote(column)}`);\n\t\tconst last = `${op}${bound.inclusive ? \"=\" : \"\"}`;\n\t\tif (cols.length === 1) return `${cols[0]} ${last} ${bind(bound.values[0])}`;\n\t\tif (dialect !== \"mysql\") {\n\t\t\tconst values = bound.values.map((value) => bind(value));\n\t\t\treturn `(${cols.join(\", \")}) ${last} (${values.join(\", \")})`;\n\t\t}\n\t\treturn `(${cols.map((column, position) => [...cols.slice(0, position).map((prefix, at) => `${prefix} = ${bind(bound.values[at])}`), `${column} ${position === cols.length - 1 ? last : op} ${bind(bound.values[position])}`].join(\" AND \")).map((term) => `(${term})`).join(\" OR \")})`;\n\t};\n\t/**\n\t* An op's statements; the first one's result shows whether the op applied.\n\t* Guards via `UPDATE \u2026 WHERE _v = ?`, checks via locking reads, counters\n\t* via upserts. With `when`, every statement also carries that condition,\n\t* and a check has none: a batch write evaluated it first (`failure`).\n\t*/\n\tconst compile = (op, when) => {\n\t\tconst { table } = op;\n\t\tconst name = tableOf(table);\n\t\t/** The row with `key`, at version `v` when given, where `when` holds. */\n\t\tconst where = (bind, key, v) => `${keyMatch(bind, table, key)}${v === void 0 ? \"\" : ` AND ${version} = ${bind(v)}`}${when ? ` AND ${when(bind)}` : \"\"}`;\n\t\t/** Inserts bound values; with `when`, a SELECT yields them only while it holds. */\n\t\tconst insert = (bind, into, columns, values) => `INSERT INTO ${into} (${columns.map(quote).join(\", \")}) ${when ? `SELECT ${values.join(\", \")} WHERE ${when(bind)}` : `VALUES (${values.join(\", \")})`}`;\n\t\t/** Inserts `row` into the op's table, each value bound as its column's type. */\n\t\tconst insertRow = (bind, row) => insert(bind, name, table.columns.map((column) => column.name), table.columns.map((column) => bind(row[column.name], column)));\n\t\t/** Replaces the row's entries in the index table of every multi-valued index. */\n\t\tconst entries = (key, row, changed) => table.indexes.flatMap((index) => {\n\t\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\t\tif (!isMultiIndex(table, index) || changed && !columns.some((column) => changed.includes(column))) return [];\n\t\t\tconst into = tableOf(table, index);\n\t\t\tconst found = row ? indexEntries(table, index, row) : [];\n\t\t\tconst order = found.length > 0 ? indexOrderTuple(table, index, row) : [];\n\t\t\treturn [sql((bind) => `DELETE FROM ${into} WHERE ${where(bind, key)}`), ...found.map((eq) => sql((bind) => {\n\t\t\t\tconst values = [...eq, ...order].map((value) => bind(value));\n\t\t\t\treturn insert(bind, into, columns, values);\n\t\t\t}))];\n\t\t});\n\t\tswitch (op.type) {\n\t\t\tcase \"insert\": return [sql((bind) => insertRow(bind, op.row)), ...entries(rowKey(table, op.row), op.row)];\n\t\t\tcase \"patch\": return [sql((bind) => {\n\t\t\t\tconst set = Object.entries(op.set).map(([column, value]) => `${quote(column)} = ${bind(value, findPhysicalColumn(table, column))}`);\n\t\t\t\treturn `UPDATE ${name} SET ${[...set, `${version} = ${version} + 1`].join(\", \")} WHERE ${where(bind, op.key, op.guard.v)}`;\n\t\t\t}), ...entries(op.key, {\n\t\t\t\t...op.previous,\n\t\t\t\t...op.set\n\t\t\t}, Object.keys(op.set))];\n\t\t\tcase \"delete\": return [sql((bind) => `DELETE FROM ${name} WHERE ${where(bind, op.key, op.guard.v)}`), ...entries(op.key)];\n\t\t\tcase \"increment\": {\n\t\t\t\tconst deltas = [...Object.entries(op.by), [\"_v\", 1]];\n\t\t\t\tconst bump = (bind, qualify = \"\") => deltas.map(([column, delta]) => `${quote(column)} = ${qualify}${quote(column)} + ${bind(delta)}`).join(\", \");\n\t\t\t\tif (!upserts(op)) return [sql((bind) => `UPDATE ${name} SET ${bump(bind)} WHERE ${where(bind, op.key, op.guard?.v)}`)];\n\t\t\t\tconst row = { ...op.init };\n\t\t\t\tfor (const [column, delta] of deltas) row[column] = Number(row[column] ?? 0) + delta;\n\t\t\t\tconst conflict = dialect === \"mysql\" ? \"ON DUPLICATE KEY UPDATE\" : `ON CONFLICT (${table.key.map(quote).join(\", \")}) DO UPDATE SET`;\n\t\t\t\treturn [sql((bind) => `${insertRow(bind, row)} ${conflict} ${bump(bind, `${name}.`)}`)];\n\t\t\t}\n\t\t\tcase \"check\":\n\t\t\t\tif (when) return [];\n\t\t\t\treturn [sql((bind) => `SELECT ${version} FROM ${name} WHERE ${where(bind, op.key)}${lock}`)];\n\t\t}\n\t};\n\t/**\n\t* SQL that holds when `op` would fail against the rows before any change.\n\t* Rows the write deletes or patches (`released`) do not count as holding a\n\t* unique value.\n\t*/\n\tconst failure = (bind, op, released) => {\n\t\tconst { table } = op;\n\t\tconst from = `SELECT 1 FROM ${tableOf(table)} WHERE`;\n\t\tconst exists = (key, v) => `EXISTS (${from} ${keyMatch(bind, table, key)}${v === void 0 ? \"\" : ` AND ${version} = ${bind(v)}`}${lock})`;\n\t\t/** Another row already holding a unique value this op writes. */\n\t\tconst clashes = (row, own, changed) => table.indexes.filter((index) => index.unique && !isMultiIndex(table, index) && index.eq.every((column) => (row[column] ?? null) !== null) && (!changed || index.eq.some((column) => changed.includes(column)))).map((index) => {\n\t\t\tconst match = index.eq.map((column) => `${quote(column)} = ${bind(row[column], findPhysicalColumn(table, column))}`);\n\t\t\tconst others = [...own ? [own] : [], ...released].map((key) => ` AND NOT (${keyMatch(bind, table, key)})`);\n\t\t\treturn `EXISTS (${from} ${match.join(\" AND \")}${others.join(\"\")})`;\n\t\t});\n\t\tswitch (op.type) {\n\t\t\tcase \"insert\": return [exists(rowKey(table, op.row)), ...clashes(op.row)].join(\" OR \");\n\t\t\tcase \"patch\": return [`NOT ${exists(op.key, op.guard.v)}`, ...clashes({\n\t\t\t\t...op.previous,\n\t\t\t\t...op.set\n\t\t\t}, op.key, Object.keys(op.set))].join(\" OR \");\n\t\t\tdefault: return `NOT ${exists(op.key, op.guard?.v)}`;\n\t\t}\n\t};\n\t/**\n\t* A write as one atomic batch, for drivers without interactive transactions:\n\t* each op's guard, against the rows before any change, records the first\n\t* failing op in a guard row; every change applies only when none failed; the\n\t* last two statements read the failure and remove the row. Unique fields are\n\t* checked ahead, since a batch cannot name the statement a constraint stopped.\n\t*/\n\tconst batchWrite = (ops, id) => {\n\t\tconst guard = tableOf(WRITE_GUARD_TABLE);\n\t\tconst [idColumn, failed] = [\"id\", \"failed_op\"].map(quote);\n\t\tconst byId = (bind) => `${idColumn} = ${bind(id)}`;\n\t\tconst released = (table) => ops.flatMap((op) => (op.type === \"delete\" || op.type === \"patch\") && op.table.name === table ? [op.key] : []);\n\t\tconst when = (bind) => `(SELECT ${failed} FROM ${guard} WHERE ${byId(bind)}) IS NULL`;\n\t\treturn [\n\t\t\tsql((bind) => `INSERT INTO ${guard} (${idColumn}, ${failed}) VALUES (${bind(id)}, NULL)`),\n\t\t\t...ops.flatMap((op, position) => upserts(op) ? [] : [sql((bind) => `UPDATE ${guard} SET ${failed} = ${position} WHERE ${failed} IS NULL AND (${failure(bind, op, released(op.table.name))}) AND ${byId(bind)}`)]),\n\t\t\t...ops.flatMap((op) => compile(op, when)),\n\t\t\tsql((bind) => `SELECT ${failed} FROM ${guard} WHERE ${byId(bind)}`),\n\t\t\tsql((bind) => `DELETE FROM ${guard} WHERE ${byId(bind)}`)\n\t\t];\n\t};\n\t/** Runs a read and converts its rows to stored values. */\n\tconst read = async (table, statement) => {\n\t\tconst { rows } = await executor.execute(statement);\n\t\treturn rows.map((row) => normalizeStoredRow(table, row, { jsonText: sqlite }));\n\t};\n\treturn {\n\t\tid: `sql:${dialect}`,\n\t\tfits: (ops) => ops.length <= maxOps,\n\t\tasync get(table, keys) {\n\t\t\tconst size = Math.max(1, Math.floor(maxParams / table.key.length));\n\t\t\tconst found = /* @__PURE__ */ new Map();\n\t\t\tfor (let start = 0; start < keys.length; start += size) {\n\t\t\t\tconst chunk = keys.slice(start, start + size);\n\t\t\t\tconst statement = sql((bind) => {\n\t\t\t\t\tconst where = chunk.map((key) => `(${keyMatch(bind, table, key)})`);\n\t\t\t\t\treturn `SELECT * FROM ${tableOf(table)} WHERE ${where.join(\" OR \")}`;\n\t\t\t\t});\n\t\t\t\tfor (const row of await read(table, statement)) found.set(JSON.stringify(rowKey(table, row)), row);\n\t\t\t}\n\t\t\treturn keys.map((key) => found.get(JSON.stringify(key)) ?? null);\n\t\t},\n\t\tasync query(table, request) {\n\t\t\tconst index = findPhysicalIndex(table, request.index);\n\t\t\tif (!Number.isSafeInteger(request.limit) || request.limit < 1) throw new RangeError(\"query limit must be a positive integer.\");\n\t\t\tconst order = indexOrderColumns(table, index);\n\t\t\tconst multi = isMultiIndex(table, index);\n\t\t\tconst source = multi ? `${tableOf(table, index)} i JOIN ${tableOf(table)} b ON ${table.key.map((column) => `b.${quote(column)} = i.${quote(column)}`).join(\" AND \")}` : `${tableOf(table)} i`;\n\t\t\tconst direction = request.order === \"asc\" ? \"ASC\" : \"DESC\";\n\t\t\tconst statement = sql((bind) => {\n\t\t\t\tconst conditions = [\n\t\t\t\t\t...index.eq.map((column, position) => `i.${quote(column)} = ${bind(request.eq[position])}`),\n\t\t\t\t\t...request.lower ? [compare(bind, order, request.lower, \">\")] : [],\n\t\t\t\t\t...request.upper ? [compare(bind, order, request.upper, \"<\")] : []\n\t\t\t\t];\n\t\t\t\treturn `SELECT ${multi ? \"b\" : \"i\"}.* FROM ${source}${conditions.length > 0 ? ` WHERE ${conditions.join(\" AND \")}` : \"\"} ORDER BY ${order.map((column) => `i.${quote(column)} ${direction}`).join(\", \")} LIMIT ${request.limit}`;\n\t\t\t});\n\t\t\treturn read(table, statement);\n\t\t},\n\t\tasync write(ops) {\n\t\t\ttry {\n\t\t\t\tif (executor.batch) {\n\t\t\t\t\tconst statements = batchWrite(ops, crypto.randomUUID());\n\t\t\t\t\tconst failed = (await executor.batch(statements)).at(-2)?.rows[0]?.failed_op ?? null;\n\t\t\t\t\treturn failed === null ? { ok: true } : {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\tfailedOp: Number(failed)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tawait executor.transaction(async (connection) => {\n\t\t\t\t\tfor (const [position, op] of ops.entries()) {\n\t\t\t\t\t\tconst [first, ...rest] = compile(op);\n\t\t\t\t\t\tlet result;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresult = await connection.execute(first);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (classifySqlError(error) === \"constraint\") throw new FailedOp(position);\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!(op.type === \"check\" ? result.rows.length === 1 && Number(result.rows[0][\"_v\"]) === op.guard.v : op.type === \"insert\" || upserts(op) || result.changes === 1)) throw new FailedOp(position);\n\t\t\t\t\t\tfor (const statement of rest) await connection.execute(statement);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { ok: true };\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof FailedOp) return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailedOp: error.index\n\t\t\t\t};\n\t\t\t\tconst kind = classifySqlError(error);\n\t\t\t\tif (kind === \"retry\") return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tretry: true\n\t\t\t\t};\n\t\t\t\tif (kind === \"constraint\" && executor.batch) return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailedOp: 0\n\t\t\t\t};\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\tasync prune(table, before, limit) {\n\t\t\tconst statements = pruneStatements(dialect, table, tablePrefix, limit).map((render) => sql((bind) => render(() => bind(before))));\n\t\t\treturn (executor.batch ? await executor.batch(statements) : await executor.transaction(async (connection) => {\n\t\t\t\tconst done = [];\n\t\t\t\tfor (const statement of statements) done.push(await connection.execute(statement));\n\t\t\t\treturn done;\n\t\t\t})).at(-1)?.changes ?? 0;\n\t\t},\n\t\tmigrations: { async apply(tables) {\n\t\t\tconst created = executor.batch && !tables.includes(WRITE_GUARD_TABLE) ? [...tables, WRITE_GUARD_TABLE] : tables;\n\t\t\tconst statements = createTableStatements(dialect, created, tablePrefix);\n\t\t\tfor (const text of statements) await executor.execute({\n\t\t\t\tsql: text,\n\t\t\t\tparams: []\n\t\t\t});\n\t\t} }\n\t};\n};\n//#endregion\nexport { WRITE_GUARD_TABLE, classifySqlError, createSqlAdapter };\n", "//#region package.json\nvar version = \"1.0.2\";\n//#endregion\nexport { version };\n", "import { version } from \"./package.mjs\";\n//#region src/version.ts\nconst HOT_UPDATER_SERVER_VERSION = version;\n//#endregion\nexport { HOT_UPDATER_SERVER_VERSION };\n", "import { HOT_UPDATER_SERVER_VERSION } from \"./version.mjs\";\n//#region src/handlerVersionRoutes.ts\nconst HOT_UPDATER_INFRASTRUCTURE_GENERATION = 1;\n/**\n* `/version` on both mounts. The admin mount also lists the ids of the\n* plugins the server runs, sorted; apps never learn which plugins a server\n* runs.\n*/\nconst createVersionRouteHandlers = (plugins = []) => {\n\tconst version = {\n\t\tadminProtocol: 2,\n\t\tinfrastructureGeneration: 1,\n\t\tversion: HOT_UPDATER_SERVER_VERSION\n\t};\n\tconst adminVersion = {\n\t\t...version,\n\t\tplugins: [...plugins].sort()\n\t};\n\treturn {\n\t\tversion: async () => Response.json(version),\n\t\tadminVersion: async () => Response.json(adminVersion)\n\t};\n};\n//#endregion\nexport { HOT_UPDATER_INFRASTRUCTURE_GENERATION, createVersionRouteHandlers };\n", "import { HotUpdaterConfigError } from \"../assembly/configError.mjs\";\n//#region src/plugins/official.ts\n/**\n* The brand Hot Updater's own plugin factories set. It is a registered\n* symbol, not a module-private one, so a plugin made by one package's ESM\n* build still carries it when another's CommonJS build reads it, as a config\n* loaded through `require` may; no plugin sets it by accident. Each official\n* plugin package sets it with a copy of its own, so no package imports\n* another's internals for it. It guards Hot Updater's ids against a\n* clash, not against a determined impostor.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/**\n* The ids of Hot Updater's own plugins. The console and tooling tell\n* features apart by plugin id, so no other plugin may take one.\n*/\nconst OFFICIAL_IDS = /* @__PURE__ */ new Set([\n\t\"insights\",\n\t\"apiKeys\",\n\t\"remoteConfig\"\n]);\n/** Whether one of Hot Updater's own factories made `plugin`. */\nconst isOfficialPlugin = (plugin) => typeof plugin === \"object\" && plugin !== null && Reflect.get(plugin, OFFICIAL) === true;\n/**\n* Refuses a plugin that takes one of Hot Updater's own ids without being\n* that plugin: `at` names it in the error, such as `plugins[0]`.\n*/\nconst checkReservedId = (plugin, at) => {\n\tconst id = typeof plugin === \"object\" && plugin !== null ? Reflect.get(plugin, \"id\") : void 0;\n\tif (typeof id === \"string\" && OFFICIAL_IDS.has(id) && !isOfficialPlugin(plugin)) throw new HotUpdaterConfigError(`${at} takes the id \"${id}\", which is reserved for Hot Updater's ${id}() plugin; give this plugin another id.`);\n};\n//#endregion\nexport { checkReservedId, isOfficialPlugin };\n", "import { HotUpdaterConfigError } from \"./configError.mjs\";\nimport { checkReservedId } from \"../plugins/official.mjs\";\n//#region src/assembly/clientPlugins.ts\nconst EXPORT_NAME = /^[A-Za-z_$][\\w$]*$/u;\n/**\n* Names app code cannot import as they are: reserved words, and the names\n* the printed app code declares itself.\n*/\nconst UNAVAILABLE_NAMES = /* @__PURE__ */ new Set([\n\t\"App\",\n\t\"HotUpdater\",\n\t\"arguments\",\n\t\"await\",\n\t\"break\",\n\t\"case\",\n\t\"catch\",\n\t\"class\",\n\t\"const\",\n\t\"continue\",\n\t\"debugger\",\n\t\"default\",\n\t\"delete\",\n\t\"do\",\n\t\"else\",\n\t\"enum\",\n\t\"eval\",\n\t\"export\",\n\t\"extends\",\n\t\"false\",\n\t\"finally\",\n\t\"for\",\n\t\"function\",\n\t\"if\",\n\t\"implements\",\n\t\"import\",\n\t\"in\",\n\t\"instanceof\",\n\t\"interface\",\n\t\"let\",\n\t\"new\",\n\t\"null\",\n\t\"package\",\n\t\"private\",\n\t\"protected\",\n\t\"public\",\n\t\"return\",\n\t\"static\",\n\t\"super\",\n\t\"switch\",\n\t\"this\",\n\t\"throw\",\n\t\"true\",\n\t\"try\",\n\t\"typeof\",\n\t\"var\",\n\t\"void\",\n\t\"while\",\n\t\"with\",\n\t\"yield\"\n]);\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/**\n* The client plugins an app adds for the plugins, each once, in plugin\n* order: what init prints in `HotUpdater.init`'s `plugins`. A malformed one,\n* or one name from two modules, throws `HotUpdaterConfigError`.\n*/\nconst clientPluginsOf = (plugins) => {\n\tif (!Array.isArray(plugins)) throw new HotUpdaterConfigError(\"plugins must be an array of plugins.\");\n\tconst found = [];\n\tplugins.forEach((plugin, position) => checkReservedId(plugin, `plugins[${position}]`));\n\tfor (const plugin of plugins) {\n\t\tif (!isRecord(plugin) || !isRecord(plugin.cli)) continue;\n\t\tconst value = plugin.cli.clientPlugin;\n\t\tif (value === void 0) continue;\n\t\tconst id = String(plugin.id);\n\t\tif (!isRecord(value) || typeof value.module !== \"string\" || value.module === \"\" || typeof value.name !== \"string\" || !EXPORT_NAME.test(value.name) || UNAVAILABLE_NAMES.has(value.name)) throw new HotUpdaterConfigError(`Plugin \"${id}\" cli.clientPlugin needs a module and an export name the app can import: an identifier other than a reserved word, App, or HotUpdater.`);\n\t\tconst { module, name } = value;\n\t\tconst named = found.find((entry) => entry.name === name);\n\t\tif (named === void 0) found.push({\n\t\t\tmodule,\n\t\t\tname\n\t\t});\n\t\telse if (named.module !== module) throw new HotUpdaterConfigError(`Plugin \"${id}\" names the client plugin \"${name}\" from ${module}, but another plugin names it from ${named.module}.`);\n\t}\n\treturn found;\n};\n//#endregion\nexport { clientPluginsOf };\n", "import { projectCompiledCatalog, projectCompiledRollbackCatalog } from \"@hot-updater/plugin-core\";\nimport { RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, createReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/db/releaseCatalog.ts\n/** A stored catalog payload, checked against its strategy's shape. */\nconst parseCompiledCatalog = (payload, strategy) => {\n\tconst parsed = JSON.parse(payload);\n\tif (typeof parsed !== \"object\" || parsed === null || Reflect.get(parsed, \"schemaVersion\") !== RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, \"strategy\") !== strategy || Reflect.get(parsed, \"fallbackPolicy\") !== RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, \"releaseDescriptors\"))) throw new Error(\"Stored Release catalog payload is invalid\");\n\tif (strategy === \"APP_VERSION\" && !Array.isArray(Reflect.get(parsed, \"segments\"))) throw new Error(\"Stored app-version Release catalog is invalid\");\n\tif (strategy === \"FINGERPRINT\" && !Array.isArray(Reflect.get(parsed, \"releaseIndexes\"))) throw new Error(\"Stored fingerprint Release catalog is invalid\");\n\treturn parsed;\n};\n/** The scope key an update check reads. */\nconst releaseCatalogScopeKeyOf = (input) => input.strategy === \"APP_VERSION\" ? createReleaseCatalogScopeKey({\n\tchannelKey: input.channelKey,\n\tplatform: input.platform,\n\tstrategy: \"APP_VERSION\"\n}) : createReleaseCatalogScopeKey({\n\tchannelKey: input.channelKey,\n\tfingerprintHash: input.fingerprintHash,\n\tplatform: input.platform,\n\tstrategy: \"FINGERPRINT\"\n});\n/** Projects a stored catalog row for one update check; null when the row is not this scope's. */\nconst projectReleaseCatalogRow = (row, input, scopeKey = releaseCatalogScopeKeyOf(input)) => {\n\tif (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === \"FINGERPRINT\" ? input.fingerprintHash : null)) return null;\n\tconst compiled = parseCompiledCatalog(row.payload, input.strategy);\n\tconst appVersion = input.strategy === \"APP_VERSION\" ? input.appVersion : void 0;\n\treturn {\n\t\tcatalogId: row.catalog_id,\n\t\tcatalogHash: row.catalog_hash,\n\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\tgeneration: row.generation,\n\t\treleases: projectCompiledCatalog(compiled, appVersion),\n\t\trollbackReleases: projectCompiledRollbackCatalog(compiled, appVersion),\n\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\tscopeKey\n\t};\n};\n//#endregion\nexport { parseCompiledCatalog, projectReleaseCatalogRow, releaseCatalogScopeKeyOf };\n", "import { getBundleArchiveStorageUri, getManifestAssetDownloadPath, isContentAddressedAssetFileHash, resolveManifestAssetStorageUri } from \"@hot-updater/plugin-core\";\nimport { ARTIFACT_PROTOCOL_VERSION, getAssetBaseStorageUri, getBundlePatch, getManifestFileHash, getManifestStorageUri } from \"@hot-updater/protocol\";\n//#region src/db/updateArtifacts.ts\nconst HBC_ASSET_PATH_RE = /\\.bundle$/;\nconst asByteSize = (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : null;\nconst resolveUniqueHbcAssetPath = (manifest) => {\n\tconst candidates = Object.keys(manifest.assets).sort((left, right) => left.localeCompare(right)).filter((candidate) => HBC_ASSET_PATH_RE.test(candidate));\n\treturn candidates.length === 1 ? candidates[0] : null;\n};\nconst isBundleManifest = (value) => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst manifest = value;\n\tif (typeof manifest.bundleId !== \"string\") return false;\n\tif (!manifest.assets || typeof manifest.assets !== \"object\") return false;\n\treturn Object.values(manifest.assets).every((asset) => {\n\t\tif (!asset || typeof asset !== \"object\" || Array.isArray(asset)) return false;\n\t\tconst manifestAsset = asset;\n\t\treturn typeof manifestAsset.fileHash === \"string\" && (manifestAsset.signature === void 0 || typeof manifestAsset.signature === \"string\");\n\t});\n};\nasync function fetchBundleManifest(storageUri, readStorageText) {\n\tconst storageText = await readStorageText(storageUri);\n\tif (storageText === null) return null;\n\tlet payload;\n\ttry {\n\t\tpayload = JSON.parse(storageText);\n\t} catch {\n\t\treturn null;\n\t}\n\tif (!isBundleManifest(payload)) return null;\n\treturn payload;\n}\nfunction resolveHbcPatchPlan({ currentBundle, targetBundle, targetManifest }) {\n\tconst matchingPatch = currentBundle ? getBundlePatch(targetBundle, currentBundle.id) : null;\n\tconst patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);\n\tif (!currentBundle || !matchingPatch || !patchAssetPath || !matchingPatch.patchStorageUri || !matchingPatch.patchFileHash || !matchingPatch.baseFileHash) return null;\n\treturn {\n\t\tassetPath: patchAssetPath,\n\t\tpatch: {\n\t\t\tbaseBundleId: matchingPatch.baseBundleId,\n\t\t\tbaseFileHash: matchingPatch.baseFileHash,\n\t\t\tbyteSize: asByteSize(matchingPatch.byteSize),\n\t\t\tpatchFileHash: matchingPatch.patchFileHash,\n\t\t\tstorageUri: matchingPatch.patchStorageUri\n\t\t}\n\t};\n}\nfunction createManifestArtifactPlan({ assetBaseStorageUri, currentBundle, targetBundle, targetManifest }) {\n\tconst patchCandidate = resolveHbcPatchPlan({\n\t\tcurrentBundle,\n\t\ttargetBundle,\n\t\ttargetManifest\n\t});\n\treturn { assets: Object.entries(targetManifest.assets).map(([assetPath, asset]) => {\n\t\tconst downloadByteSize = asByteSize(asset.downloadByteSize);\n\t\tconst downloadPath = getManifestAssetDownloadPath(assetPath);\n\t\tconst isTransformedDownload = downloadPath !== assetPath;\n\t\tconst hasValidDownloadFileHash = isContentAddressedAssetFileHash(asset.downloadFileHash);\n\t\tconst file = {\n\t\t\tbyteSize: downloadByteSize !== null && (hasValidDownloadFileHash || !isTransformedDownload && asset.downloadFileHash === void 0) ? downloadByteSize : null,\n\t\t\tstorageUri: resolveManifestAssetStorageUri({\n\t\t\t\tassetBaseStorageUri,\n\t\t\t\tassetPath: downloadPath,\n\t\t\t\tdownloadFileHash: asset.downloadFileHash,\n\t\t\t\tfileHash: asset.fileHash\n\t\t\t})\n\t\t};\n\t\tif (isTransformedDownload) file.compression = \"br\";\n\t\tconst patch = patchCandidate?.assetPath === assetPath ? patchCandidate.patch : null;\n\t\treturn {\n\t\t\tassetPath,\n\t\t\tfile,\n\t\t\tfileHash: asset.fileHash,\n\t\t\tpatch\n\t\t};\n\t}) };\n}\nasync function resolveAssets(plan, resolveFileUrl) {\n\tconst patchAsset = plan.assets.find((asset) => asset.patch !== null);\n\tlet resolvedPatch = null;\n\tif (patchAsset?.patch) {\n\t\tconst patchUrl = await resolveFileUrl(patchAsset.patch.storageUri);\n\t\tif (patchUrl) resolvedPatch = {\n\t\t\tassetPath: patchAsset.assetPath,\n\t\t\tpatch: {\n\t\t\t\talgorithm: \"bsdiff\",\n\t\t\t\tbaseBundleId: patchAsset.patch.baseBundleId,\n\t\t\t\tbaseFileHash: patchAsset.patch.baseFileHash,\n\t\t\t\tpatchFileHash: patchAsset.patch.patchFileHash,\n\t\t\t\tpatchUrl,\n\t\t\t\t...patchAsset.patch.byteSize === null ? {} : { byteSize: patchAsset.patch.byteSize }\n\t\t\t}\n\t\t};\n\t}\n\tconst entries = await Promise.all(plan.assets.map(async (asset) => {\n\t\tlet patch = resolvedPatch?.assetPath === asset.assetPath ? resolvedPatch.patch : null;\n\t\tlet fileUrl = null;\n\t\ttry {\n\t\t\tfileUrl = await resolveFileUrl(asset.file.storageUri);\n\t\t} catch (error) {\n\t\t\tif (!patch) throw error;\n\t\t}\n\t\tif (fileUrl && patch && asset.file.byteSize !== null && asset.patch !== null && asset.patch.byteSize !== null && asset.patch.byteSize >= asset.file.byteSize) patch = null;\n\t\tif (!fileUrl) return null;\n\t\tconst changedAsset = {\n\t\t\tfile: { url: fileUrl },\n\t\t\tfileHash: asset.fileHash\n\t\t};\n\t\tif (asset.file.compression) changedAsset.file.compression = asset.file.compression;\n\t\tif (patch) changedAsset.patch = patch;\n\t\treturn { asset: [asset.assetPath, changedAsset] };\n\t}));\n\tif (entries.some((entry) => entry === null)) return null;\n\tconst resolvedEntries = entries.filter((entry) => entry !== null);\n\treturn { assets: Object.fromEntries(resolvedEntries.map((entry) => entry.asset)) };\n}\nasync function resolveManifestArtifacts({ currentBundle, resolveFileUrl, readStorageText, targetBundle }) {\n\tconst manifestStorageUri = targetBundle ? getManifestStorageUri(targetBundle) : null;\n\tconst manifestFileHash = targetBundle ? getManifestFileHash(targetBundle) : null;\n\tconst assetBaseStorageUri = targetBundle ? getAssetBaseStorageUri(targetBundle) : null;\n\tif (!targetBundle || !manifestStorageUri || !manifestFileHash || !assetBaseStorageUri) return null;\n\tconst targetManifest = await fetchBundleManifest(manifestStorageUri, readStorageText);\n\tif (!targetManifest) return null;\n\tconst plan = createManifestArtifactPlan({\n\t\tassetBaseStorageUri,\n\t\tcurrentBundle,\n\t\ttargetBundle,\n\t\ttargetManifest\n\t});\n\tconst manifestUrl = await resolveFileUrl(manifestStorageUri);\n\tif (!manifestUrl) return null;\n\tconst resolved = await resolveAssets(plan, resolveFileUrl);\n\tif (!resolved) return null;\n\tlet archiveUrl = null;\n\tconst archive = targetManifest.archive;\n\tif (archive && isContentAddressedAssetFileHash(archive.downloadFileHash) && (asByteSize(archive.downloadByteSize) ?? 0) > 0 && (asByteSize(archive.tarByteSize) ?? 0) > 0) try {\n\t\tarchiveUrl = await resolveFileUrl(getBundleArchiveStorageUri({\n\t\t\tmanifestStorageUri,\n\t\t\tbundleId: targetBundle.id\n\t\t}));\n\t} catch {}\n\treturn {\n\t\tartifactProtocolVersion: ARTIFACT_PROTOCOL_VERSION,\n\t\tassets: resolved.assets,\n\t\tmanifestFileHash,\n\t\tmanifestUrl,\n\t\t...archiveUrl ? { archiveUrl } : {}\n\t};\n}\n//#endregion\nexport { resolveManifestArtifacts };\n", "//#region src/version/constants.ts\nconst SEMVER_SPEC_VERSION = \"2.0.0\";\nconst INCREMENT_TYPES = [\n\t\"major\",\n\t\"premajor\",\n\t\"minor\",\n\t\"preminor\",\n\t\"patch\",\n\t\"prepatch\",\n\t\"prerelease\",\n\t\"release\"\n];\nconst TRUNCATION_TYPES = [\n\t\"major\",\n\t\"premajor\",\n\t\"minor\",\n\t\"preminor\",\n\t\"patch\",\n\t\"prepatch\",\n\t\"prerelease\"\n];\n//#endregion\n//#region src/version/patterns.ts\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst GREATER_LESS_THAN = \"((?:<|>)?=?)\";\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nconst XRANGE_PLAIN = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nconst XRANGE_PLAIN_LOOSE = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nconst LONE_TILDE = \"(?:~>?)\";\nconst LONE_CARET = String.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\n//#endregion\n//#region src/version/parse.ts\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction formatFullVersion(version) {\n\tconst comparable = formatComparableVersion(version);\n\treturn version.build?.length ? `${comparable}+${version.build.join(\".\")}` : comparable;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region src/version/identifiers.ts\nconst NUMERIC = /^\\d+$/;\nfunction compareIdentifiers(left, right) {\n\tif (typeof left === \"number\" && typeof right === \"number\") return left === right ? 0 : left < right ? -1 : 1;\n\tconst leftNumeric = NUMERIC.test(String(left));\n\tconst rightNumeric = NUMERIC.test(String(right));\n\tconst normalizedLeft = leftNumeric ? Number(left) : left;\n\tconst normalizedRight = rightNumeric ? Number(right) : right;\n\treturn normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;\n}\nfunction compareIdentifiersReversed(left, right) {\n\treturn compareIdentifiers(right, left);\n}\n//#endregion\n//#region src/version/comparison.ts\nfunction compareMainParsed(left, right) {\n\treturn left.major === right.major ? left.minor === right.minor ? left.patch === right.patch ? 0 : left.patch < right.patch ? -1 : 1 : left.minor < right.minor ? -1 : 1 : left.major < right.major ? -1 : 1;\n}\nfunction comparePrereleaseParsed(left, right) {\n\tconst leftPrerelease = left.prerelease;\n\tconst rightPrerelease = right.prerelease;\n\tif (leftPrerelease?.length && !rightPrerelease?.length) return -1;\n\tif (!leftPrerelease?.length && rightPrerelease?.length) return 1;\n\tif (!leftPrerelease?.length && !rightPrerelease?.length) return 0;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = leftPrerelease?.[index];\n\t\tconst rightIdentifier = rightPrerelease?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compareParsed(left, right) {\n\treturn compareMainParsed(left, right) || comparePrereleaseParsed(left, right);\n}\nfunction compareBuildParsed(left, right) {\n\tconst precedence = compareParsed(left, right);\n\tif (precedence !== 0) return precedence;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = left.build?.[index];\n\t\tconst rightIdentifier = right.build?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compare(left, right, options = {}) {\n\treturn compareParsed(parse(left, options), parse(right, options));\n}\nfunction compareReversed(left, right, options = {}) {\n\treturn compare(right, left, options);\n}\nfunction compareMain(left, right, options = {}) {\n\treturn compareMainParsed(parse(left, options), parse(right, options));\n}\nfunction comparePrerelease(left, right, options = {}) {\n\treturn comparePrereleaseParsed(parse(left, options), parse(right, options));\n}\nfunction compareBuild(left, right, options = {}) {\n\treturn compareBuildParsed(parse(left, options), parse(right, options));\n}\nfunction compareWithOperator(left, operator, right, options = {}) {\n\tif (operator === \"===\") return left === right;\n\tif (operator === \"!==\") return left !== right;\n\tconst comparison = compare(left, right, options);\n\tswitch (operator) {\n\t\tcase \"\":\n\t\tcase \"=\":\n\t\tcase \"==\": return comparison === 0;\n\t\tcase \"!=\": return comparison !== 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t\tdefault: throw new TypeError(`Invalid operator: ${operator}`);\n\t}\n}\nfunction isEqual(left, right, options = {}) {\n\treturn compare(left, right, options) === 0;\n}\nfunction isNotEqual(left, right, options = {}) {\n\treturn compare(left, right, options) !== 0;\n}\nfunction isGreater(left, right, options = {}) {\n\treturn compare(left, right, options) > 0;\n}\nfunction isGreaterOrEqual(left, right, options = {}) {\n\treturn compare(left, right, options) >= 0;\n}\nfunction isLess(left, right, options = {}) {\n\treturn compare(left, right, options) < 0;\n}\nfunction isLessOrEqual(left, right, options = {}) {\n\treturn compare(left, right, options) <= 0;\n}\nfunction sort(versions, options = {}) {\n\treturn [...versions].sort((left, right) => compareBuild(left, right, options));\n}\nfunction sortReversed(versions, options = {}) {\n\treturn [...versions].sort((left, right) => compareBuild(right, left, options));\n}\n//#endregion\nexport { LOOSE_PLAIN as A, BUILD as C, GREATER_LESS_THAN as D, FULL_PLAIN as E, safeRegex as F, INCREMENT_TYPES as I, SEMVER_SPEC_VERSION as L, PRERELEASE_LOOSE as M, XRANGE_PLAIN as N, LONE_CARET as O, XRANGE_PLAIN_LOOSE as P, TRUNCATION_TYPES as R, tryParse as S, COERCE_FULL as T, compareIdentifiers as _, compareParsed as a, formatFullVersion as b, compareWithOperator as c, isGreaterOrEqual as d, isLess as f, sortReversed as g, sort as h, compareMainParsed as i, PRERELEASE as j, LONE_TILDE as k, isEqual as l, isNotEqual as m, compareBuild as n, comparePrerelease as o, isLessOrEqual as p, compareMain as r, compareReversed as s, compare as t, isGreater as u, compareIdentifiersReversed as v, COERCE as w, parse as x, formatComparableVersion as y };\n", "import { A as LOOSE_PLAIN, D as GREATER_LESS_THAN, E as FULL_PLAIN, F as safeRegex, S as tryParse, a as compareParsed, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.js\";\n//#region src/comparator/parse.ts\nconst STRICT_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${FULL_PLAIN})$|^$`);\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction formatComparator(comparator) {\n\treturn comparator.version ? `${comparator.operator}${formatComparableVersion(comparator.version)}` : \"\";\n}\nfunction parseComparator(comparator, options = {}) {\n\tif (typeof comparator !== \"string\") return comparator;\n\tconst normalized = comparator.trim().replaceAll(/\\s+/g, \" \");\n\tconst match = normalized.match(options.loose ? LOOSE_COMPARATOR : STRICT_COMPARATOR);\n\tif (!match) throw new TypeError(`Invalid comparator: ${normalized}`);\n\tconst operator = match[1] === \"=\" ? \"\" : match[1] || \"\";\n\tconst version = match[2] ? parse(match[2], options) : null;\n\treturn {\n\t\toperator,\n\t\toptions,\n\t\tvalue: version ? `${operator}${formatComparableVersion(version)}` : \"\",\n\t\tversion\n\t};\n}\nfunction tryParseComparator(comparator, options = {}) {\n\ttry {\n\t\treturn typeof comparator === \"string\" ? parseComparator(comparator, options) : comparator;\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region src/comparator/set.ts\nfunction testParsedComparator(comparator, version) {\n\tif (!comparator.version) return true;\n\tconst comparison = compareParsed(version, comparator.version);\n\tswitch (comparator.operator) {\n\t\tcase \"\": return comparison === 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t}\n}\nfunction testComparatorVersion(comparator, version) {\n\tconst parsed = tryParse(version, comparator.options);\n\treturn parsed ? testParsedComparator(comparator, parsed) : false;\n}\nfunction comparatorAllowsPrerelease(comparator, version) {\n\tconst allowed = comparator.version;\n\treturn allowed !== null && !!allowed.prerelease?.length && allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch;\n}\nfunction testComparatorSet(set, version, options) {\n\tif (set.some((comparator) => !testParsedComparator(comparator, version))) return false;\n\treturn !version.prerelease?.length || !!options.includePrerelease || set.some((comparator) => comparatorAllowsPrerelease(comparator, version));\n}\nfunction parsedComparatorsIntersect(left, right, options = {}) {\n\tif (!left.version || !right.version) return true;\n\tif (left.operator === \"\") return testComparatorSet([right], left.version, options);\n\tif (right.operator === \"\") return testComparatorSet([left], right.version, options);\n\tconst leftValue = formatComparator(left);\n\tconst rightValue = formatComparator(right);\n\tif (options.includePrerelease && (leftValue === \"<0.0.0-0\" || rightValue === \"<0.0.0-0\")) return false;\n\tif (!options.includePrerelease && (leftValue.startsWith(\"<0.0.0\") || rightValue.startsWith(\"<0.0.0\"))) return false;\n\tif (left.operator.startsWith(\">\") && right.operator.startsWith(\">\")) return true;\n\tif (left.operator.startsWith(\"<\") && right.operator.startsWith(\"<\")) return true;\n\tconst comparison = compareParsed(left.version, right.version);\n\tif (comparison === 0 && left.operator.includes(\"=\") && right.operator.includes(\"=\")) return true;\n\tif (comparison < 0 && left.operator.startsWith(\">\") && right.operator.startsWith(\"<\")) return true;\n\treturn comparison > 0 && left.operator.startsWith(\"<\") && right.operator.startsWith(\">\");\n}\n//#endregion\nexport { testParsedComparator as a, tryParseComparator as c, testComparatorVersion as i, parsedComparatorsIntersect as n, formatComparator as o, testComparatorSet as r, parseComparator as s, comparatorAllowsPrerelease as t };\n", "import { A as LOOSE_PLAIN, C as BUILD, D as GREATER_LESS_THAN, F as safeRegex, N as XRANGE_PLAIN, O as LONE_CARET, P as XRANGE_PLAIN_LOOSE, S as tryParse, a as compareParsed, h as sort, k as LONE_TILDE, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.js\";\nimport { a as testParsedComparator, n as parsedComparatorsIntersect, o as formatComparator, r as testComparatorSet, s as parseComparator, t as comparatorAllowsPrerelease } from \"./set-CC5YeoYX.js\";\n//#region src/range/parse.ts\nfunction formatRange(range) {\n\treturn range.sets.map((set) => set.map(formatComparator).join(\" \")).join(\"||\");\n}\nconst BUILD_STRIP = new RegExp(BUILD, \"g\");\nconst BUILD_SAFE = safeRegex(BUILD);\nconst STRICT_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN})\\s+-\\s+(${XRANGE_PLAIN})\\s*$`);\nconst LOOSE_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN_LOOSE})\\s+-\\s+(${XRANGE_PLAIN_LOOSE})\\s*$`);\nconst COMPARATOR_TRIM = safeRegex(String.raw`(\\s*)${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN}|${XRANGE_PLAIN})`, \"g\");\nconst TILDE_TRIM = safeRegex(String.raw`(\\s*)${LONE_TILDE}\\s+`, \"g\");\nconst CARET_TRIM = safeRegex(String.raw`(\\s*)${LONE_CARET}\\s+`, \"g\");\nconst STRICT_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN}$`);\nconst LOOSE_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN}$`);\nconst LOOSE_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN}$`);\nconst LOOSE_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN_LOOSE}$`);\nconst STAR = safeRegex(String.raw`(<|>)?=?\\s*\\*`);\nconst GTE_ZERO = /^\\s*>=\\s*0\\.0\\.0\\s*$/;\nconst GTE_ZERO_PRERELEASE = /^\\s*>=\\s*0\\.0\\.0-0\\s*$/;\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction isWildcard(value) {\n\treturn !value || String(value).toLowerCase() === \"x\" || String(value) === \"*\";\n}\nfunction hasInvalidWildcardOrder(major, minor, patch) {\n\treturn isWildcard(major) && !isWildcard(minor) || isWildcard(minor) && Boolean(patch) && !isWildcard(patch);\n}\nfunction replaceTilde(comparator, options) {\n\tconst expression = options.loose ? LOOSE_TILDE : STRICT_TILDE;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn prerelease ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;\n\t});\n}\nfunction replaceTildes(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceTilde(part, options)).join(\" \");\n}\nfunction replaceCaret(comparator, options) {\n\tconst expression = options.loose ? LOOSE_CARET : STRICT_CARET;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return major === \"0\" ? `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (prerelease) return major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch}-${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\treturn major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;\n\t});\n}\nfunction replaceCarets(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceCaret(part, options)).join(\" \");\n}\nfunction replaceXRange(comparator, options) {\n\tconst expression = options.loose ? LOOSE_XRANGE : STRICT_XRANGE;\n\treturn comparator.trim().replace(expression, (match, rawOperator, rawMajor, rawMinor, rawPatch) => {\n\t\tlet operator = rawOperator;\n\t\tlet major = rawMajor;\n\t\tlet minor = rawMinor;\n\t\tlet patch = rawPatch;\n\t\tif (hasInvalidWildcardOrder(String(major), minor === void 0 ? void 0 : String(minor), patch === void 0 ? void 0 : String(patch))) return comparator;\n\t\tconst wildcardMajor = isWildcard(major);\n\t\tconst wildcardMinor = wildcardMajor || isWildcard(minor);\n\t\tconst wildcardPatch = wildcardMinor || isWildcard(patch);\n\t\tif (operator === \"=\" && wildcardPatch) operator = \"\";\n\t\tif (wildcardMajor) return operator === \">\" || operator === \"<\" ? \"<0.0.0-0\" : \"*\";\n\t\tlet prerelease = options.includePrerelease ? \"-0\" : \"\";\n\t\tif (operator && wildcardPatch) {\n\t\t\tif (wildcardMinor) minor = 0;\n\t\t\tpatch = 0;\n\t\t\tif (operator === \">\") {\n\t\t\t\toperator = \">=\";\n\t\t\t\tif (wildcardMinor) {\n\t\t\t\t\tmajor = Number(major) + 1;\n\t\t\t\t\tminor = 0;\n\t\t\t\t} else minor = Number(minor) + 1;\n\t\t\t} else if (operator === \"<=\") {\n\t\t\t\toperator = \"<\";\n\t\t\t\tif (wildcardMinor) major = Number(major) + 1;\n\t\t\t\telse minor = Number(minor) + 1;\n\t\t\t}\n\t\t\tif (operator === \"<\") prerelease = \"-0\";\n\t\t\treturn `${operator}${major}.${minor}.${patch}${prerelease}`;\n\t\t}\n\t\tif (wildcardMinor) return `>=${major}.0.0${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (wildcardPatch) return `>=${major}.${minor}.0${prerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn match;\n\t});\n}\nfunction replaceXRanges(comparator, options) {\n\treturn comparator.split(/\\s+/).map((part) => replaceXRange(part, options)).join(\" \");\n}\nfunction replaceHyphenRange(range, options) {\n\tconst expression = options.loose ? LOOSE_HYPHEN : STRICT_HYPHEN;\n\treturn range.replace(expression, (_match, rawFrom, fromMajor, fromMinor, fromPatch, fromPrerelease, _fromBuild, rawTo, toMajor, toMinor, toPatch, toPrerelease) => {\n\t\tlet from = rawFrom;\n\t\tlet to = rawTo;\n\t\tif (isWildcard(fromMajor)) from = \"\";\n\t\telse if (isWildcard(fromMinor)) from = `>=${fromMajor}.0.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (isWildcard(fromPatch)) from = `>=${fromMajor}.${fromMinor}.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (fromPrerelease) from = `>=${from}`;\n\t\telse from = `>=${from}${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\tif (isWildcard(toMajor)) to = \"\";\n\t\telse if (isWildcard(toMinor)) to = `<${Number(toMajor) + 1}.0.0-0`;\n\t\telse if (isWildcard(toPatch)) to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;\n\t\telse if (toPrerelease) to = `<=${toMajor}.${toMinor}.${toPatch}-${toPrerelease}`;\n\t\telse if (options.includePrerelease) to = `<${toMajor}.${toMinor}.${Number(toPatch) + 1}-0`;\n\t\telse to = `<=${to}`;\n\t\treturn `${from} ${to}`.trim();\n\t});\n}\nfunction expandComparator(comparator, options) {\n\treturn replaceXRanges(replaceTildes(replaceCarets(comparator.replace(BUILD_SAFE, \"\"), options), options), options).trim().replace(STAR, \"\");\n}\nfunction parseSimpleRange(input, options) {\n\tlet parts = replaceHyphenRange(input.replace(BUILD_STRIP, \"\"), options).replace(COMPARATOR_TRIM, \"$1$2$3\").replace(TILDE_TRIM, \"$1~\").replace(CARET_TRIM, \"$1^\").split(\" \").map((part) => expandComparator(part, options)).join(\" \").split(/\\s+/).map((part) => part.trim().replace(options.includePrerelease ? GTE_ZERO_PRERELEASE : GTE_ZERO, \"\"));\n\tif (options.loose) parts = parts.filter((part) => LOOSE_COMPARATOR.test(part));\n\tconst unique = /* @__PURE__ */ new Map();\n\tfor (const comparator of parts.map((part) => parseComparator(part, options))) {\n\t\tif (comparator.value === \"<0.0.0-0\") return [comparator];\n\t\tunique.set(comparator.value, comparator);\n\t}\n\tif (unique.size > 1) unique.delete(\"\");\n\treturn [...unique.values()];\n}\nfunction parseRange(range, options = {}) {\n\tif (typeof range !== \"string\") return range;\n\tconst parsedOptions = { ...options };\n\tconst normalizedRange = range.trim().replaceAll(/\\s+/g, \" \");\n\tlet sets = normalizedRange.split(\"||\").map((part) => parseSimpleRange(part.trim(), parsedOptions)).filter((set) => set.length);\n\tif (!sets.length) throw new TypeError(`Range contains no valid comparator sets: ${normalizedRange}`);\n\tif (sets.length > 1) {\n\t\tconst first = sets[0];\n\t\tsets = sets.filter((set) => set[0]?.value !== \"<0.0.0-0\");\n\t\tif (!sets.length) sets = [first];\n\t\telse if (sets.length > 1) {\n\t\t\tconst any = sets.find((set) => set.length === 1 && set[0]?.value === \"\");\n\t\t\tif (any) sets = [any];\n\t\t}\n\t}\n\treturn {\n\t\toptions: parsedOptions,\n\t\tsets\n\t};\n}\nfunction tryParseRange(range, options = {}) {\n\ttry {\n\t\treturn parseRange(range, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nfunction testParsedRange(range, version) {\n\treturn range.sets.some((set) => testComparatorSet(set, version, range.options));\n}\nfunction testRangeVersion(range, version) {\n\tconst parsed = tryParse(version, range.options);\n\treturn parsed ? testParsedRange(range, parsed) : false;\n}\nfunction exactVersion(set) {\n\tfor (const comparator of set) if (comparator.operator === \"\" && comparator.version) return comparator.version;\n\treturn null;\n}\nfunction isSatisfiable(comparators, options) {\n\tconst exact = exactVersion(comparators);\n\tif (exact) return testComparatorSet(comparators, exact, options);\n\tconst remaining = [...comparators];\n\tlet current = remaining.pop();\n\twhile (current && remaining.length) {\n\t\tif (remaining.some((other) => !parsedComparatorsIntersect(current, other, options))) return false;\n\t\tcurrent = remaining.pop();\n\t}\n\treturn true;\n}\nfunction setsIntersect(left, right, options) {\n\tconst leftExact = exactVersion(left);\n\tif (leftExact) return testComparatorSet(right, leftExact, options);\n\tconst rightExact = exactVersion(right);\n\tif (rightExact) return testComparatorSet(left, rightExact, options);\n\treturn left.every((leftComparator) => right.every((rightComparator) => parsedComparatorsIntersect(leftComparator, rightComparator, options)));\n}\nfunction parsedRangesIntersect(left, right, options = {}) {\n\treturn left.sets.some((leftSet) => isSatisfiable(leftSet, options) && right.sets.some((rightSet) => isSatisfiable(rightSet, options) && setsIntersect(leftSet, rightSet, options)));\n}\n//#endregion\n//#region src/range/operations.ts\nfunction isValidRange(range, options = {}) {\n\treturn tryParseRange(range, options) !== null;\n}\nfunction normalizeRange(range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? formatRange(parsed) || \"*\" : null;\n}\nfunction satisfies(version, range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? testRangeVersion(parsed, version) : false;\n}\nfunction rangeToComparators(range, options = {}) {\n\treturn parseRange(range, options).sets.map((set) => set.map(formatComparator).join(\" \").trim().split(\" \"));\n}\nfunction findMaxSatisfying(versions, range, options = {}) {\n\tconst parsedRange = tryParseRange(range, options);\n\tif (!parsedRange) return null;\n\tlet maximum = null;\n\tlet maximumParsed = null;\n\tfor (const version of versions) {\n\t\tconst parsedVersion = tryParse(version, parsedRange.options);\n\t\tif (!parsedVersion || !testParsedRange(parsedRange, parsedVersion)) continue;\n\t\tif (!maximumParsed || compareParsed(maximumParsed, parsedVersion) < 0) {\n\t\t\tmaximum = version;\n\t\t\tmaximumParsed = parsedVersion;\n\t\t}\n\t}\n\treturn maximum;\n}\nfunction findMinSatisfying(versions, range, options = {}) {\n\tconst parsedRange = tryParseRange(range, options);\n\tif (!parsedRange) return null;\n\tlet minimum = null;\n\tlet minimumParsed = null;\n\tfor (const version of versions) {\n\t\tconst parsedVersion = tryParse(version, parsedRange.options);\n\t\tif (!parsedVersion || !testParsedRange(parsedRange, parsedVersion)) continue;\n\t\tif (!minimumParsed || compareParsed(minimumParsed, parsedVersion) > 0) {\n\t\t\tminimum = version;\n\t\t\tminimumParsed = parsedVersion;\n\t\t}\n\t}\n\treturn minimum;\n}\nfunction nextVersionAfter(version) {\n\tconst { prerelease } = version;\n\treturn prerelease?.length ? {\n\t\tmajor: version.major,\n\t\tminor: version.minor,\n\t\tpatch: version.patch,\n\t\tprerelease: [...prerelease, 0]\n\t} : {\n\t\tmajor: version.major,\n\t\tminor: version.minor,\n\t\tpatch: version.patch + 1\n\t};\n}\nfunction findMinimumForRange(range, options = {}) {\n\tconst parsedRange = parseRange(range, options);\n\tconst zero = {\n\t\tmajor: 0,\n\t\tminor: 0,\n\t\tpatch: 0\n\t};\n\tif (testParsedRange(parsedRange, zero)) return zero;\n\tconst zeroPrerelease = {\n\t\t...zero,\n\t\tprerelease: [0]\n\t};\n\tif (testParsedRange(parsedRange, zeroPrerelease)) return zeroPrerelease;\n\tlet minimum = null;\n\tfor (const set of parsedRange.sets) {\n\t\tlet setMinimum = null;\n\t\tfor (const comparator of set) {\n\t\t\tif (!comparator.version) continue;\n\t\t\tconst candidate = comparator.operator === \">\" ? nextVersionAfter(comparator.version) : comparator.operator === \"\" || comparator.operator === \">=\" ? structuredClone(comparator.version) : null;\n\t\t\tif (candidate && (!setMinimum || compareParsed(candidate, setMinimum) > 0)) setMinimum = candidate;\n\t\t}\n\t\tif (setMinimum && (!minimum || compareParsed(minimum, setMinimum) > 0)) minimum = setMinimum;\n\t}\n\treturn minimum && testParsedRange(parsedRange, minimum) ? minimum : null;\n}\nfunction compareInDirection(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison > 0 : comparison < 0;\n}\nfunction compareOppositeOrEqual(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison <= 0 : comparison >= 0;\n}\nfunction compareOpposite(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison < 0 : comparison > 0;\n}\nfunction isOutsideRange(version, range, direction, options = {}) {\n\tif (direction !== \">\" && direction !== \"<\") throw new TypeError(\"Must provide a direction of \\\"<\\\" or \\\">\\\"\");\n\tconst parsedRange = parseRange(range, options);\n\tconst parsedVersion = parse(version, parsedRange.options);\n\tif (testParsedRange(parsedRange, parsedVersion)) return false;\n\tconst inclusiveDirection = direction === \">\" ? \">=\" : \"<=\";\n\tfor (const set of parsedRange.sets) {\n\t\tconst concrete = set.map((comparator) => comparator.version ? comparator : parseComparator(\">=0.0.0\"));\n\t\tlet high = concrete[0];\n\t\tlet low = concrete[0];\n\t\tfor (const comparator of concrete) if (compareInDirection(comparator.version, high.version, direction)) high = comparator;\n\t\telse if (compareOpposite(comparator.version, low.version, direction)) low = comparator;\n\t\tif (high.operator === direction || high.operator === inclusiveDirection) return false;\n\t\tif ((!low.operator || low.operator === direction) && compareOppositeOrEqual(parsedVersion, low.version, direction)) return false;\n\t\tif (low.operator === inclusiveDirection && compareOpposite(parsedVersion, low.version, direction)) return false;\n\t}\n\treturn true;\n}\nfunction isGreaterThanRange(version, range, options = {}) {\n\treturn isOutsideRange(version, range, \">\", options);\n}\nfunction isLessThanRange(version, range, options = {}) {\n\treturn isOutsideRange(version, range, \"<\", options);\n}\nfunction rangesIntersect(left, right, options = {}) {\n\tconst parsedLeft = parseRange(left, options);\n\tconst parsedRight = parseRange(right, options);\n\treturn parsedRangesIntersect(parsedLeft, parsedRight, {\n\t\t...parsedLeft.options,\n\t\t...parsedRight.options,\n\t\t...options\n\t});\n}\nfunction simplifyRange(versions, range, options = {}) {\n\tconst parsedRange = parseRange(range, options);\n\tconst sorted = sort(versions, parsedRange.options);\n\tconst sets = [];\n\tlet first = null;\n\tlet previous = null;\n\tfor (const version of sorted) if (testRangeVersion(parsedRange, version)) {\n\t\tprevious = version;\n\t\tfirst ??= version;\n\t} else if (previous) {\n\t\tsets.push([first, previous]);\n\t\tfirst = null;\n\t\tprevious = null;\n\t}\n\tif (first) sets.push([first, null]);\n\tconst simplified = sets.map(([minimum, maximum]) => {\n\t\tconst minimumValue = formatComparableVersion(parse(minimum, parsedRange.options));\n\t\tconst maximumValue = maximum ? formatComparableVersion(parse(maximum, parsedRange.options)) : null;\n\t\tif (minimumValue === maximumValue) return minimumValue;\n\t\tif (!maximum && minimum === sorted[0]) return \"*\";\n\t\tif (!maximumValue) return `>=${minimumValue}`;\n\t\tif (minimum === sorted[0]) return `<=${maximumValue}`;\n\t\treturn `${minimumValue} - ${maximumValue}`;\n\t}).join(\" || \");\n\tconst original = typeof range === \"string\" ? range : formatRange(parsedRange) || \"*\";\n\treturn simplified.length < original.length ? simplified : original;\n}\n//#endregion\n//#region src/range/subset.ts\nfunction higherLowerBound(left, right) {\n\tif (!left) return right;\n\tconst comparison = compareParsed(left.version, right.version);\n\treturn comparison > 0 ? left : comparison < 0 || right.operator === \">\" && left.operator === \">=\" ? right : left;\n}\nfunction lowerUpperBound(left, right) {\n\tif (!left) return right;\n\tconst comparison = compareParsed(left.version, right.version);\n\treturn comparison < 0 ? left : comparison > 0 || right.operator === \"<\" && left.operator === \"<=\" ? right : left;\n}\nfunction simpleRangeSubset(rawSubset, rawSuperset, options) {\n\tlet subset = rawSubset;\n\tlet superset = rawSuperset;\n\tconst subsetAny = subset.length === 1 && !subset[0].version;\n\tconst supersetAny = superset.length === 1 && !superset[0].version;\n\tif (subsetAny) {\n\t\tif (supersetAny) return true;\n\t\tsubset = [parseComparator(options.includePrerelease ? \">=0.0.0-0\" : \">=0.0.0\")];\n\t}\n\tif (supersetAny) {\n\t\tif (options.includePrerelease) return true;\n\t\tsuperset = [parseComparator(\">=0.0.0\")];\n\t}\n\tconst equal = /* @__PURE__ */ new Map();\n\tlet lower;\n\tlet upper;\n\tfor (const comparator of subset) if (comparator.operator === \">\" || comparator.operator === \">=\") lower = higherLowerBound(lower, comparator);\n\telse if (comparator.operator === \"<\" || comparator.operator === \"<=\") upper = lowerUpperBound(upper, comparator);\n\telse if (comparator.version) equal.set(formatComparableVersion(comparator.version), comparator.version);\n\tif (equal.size > 1) return null;\n\tlet boundsComparison;\n\tif (lower && upper) {\n\t\tboundsComparison = compareParsed(lower.version, upper.version);\n\t\tif (boundsComparison > 0) return null;\n\t\tif (boundsComparison === 0 && (lower.operator !== \">=\" || upper.operator !== \"<=\")) return null;\n\t}\n\tfor (const version of equal.values()) {\n\t\tif (lower && !testParsedComparator(lower, version)) return null;\n\t\tif (upper && !testParsedComparator(upper, version)) return null;\n\t\treturn testComparatorSet(superset, version, options);\n\t}\n\tlet needsLowerPrerelease = lower && !options.includePrerelease && lower.version.prerelease?.length ? lower.version : null;\n\tlet needsUpperPrerelease = upper && !options.includePrerelease && upper.version.prerelease?.length ? upper.version : null;\n\tconst upperPrerelease = needsUpperPrerelease?.prerelease;\n\tif (upperPrerelease?.length === 1 && upper?.operator === \"<\" && upperPrerelease[0] === 0) needsUpperPrerelease = null;\n\tlet hasSupersetLower = false;\n\tlet hasSupersetUpper = false;\n\tfor (const comparator of superset) {\n\t\thasSupersetLower ||= comparator.operator === \">\" || comparator.operator === \">=\";\n\t\thasSupersetUpper ||= comparator.operator === \"<\" || comparator.operator === \"<=\";\n\t\tif (lower) {\n\t\t\tif (needsLowerPrerelease && comparatorAllowsPrerelease(comparator, needsLowerPrerelease)) needsLowerPrerelease = null;\n\t\t\tif (comparator.operator === \">\" || comparator.operator === \">=\") {\n\t\t\t\tconst higher = higherLowerBound(lower, comparator);\n\t\t\t\tif (higher === comparator && higher !== lower) return false;\n\t\t\t} else if (lower.operator === \">=\" && !testParsedComparator(comparator, lower.version)) return false;\n\t\t}\n\t\tif (upper) {\n\t\t\tif (needsUpperPrerelease && comparatorAllowsPrerelease(comparator, needsUpperPrerelease)) needsUpperPrerelease = null;\n\t\t\tif (comparator.operator === \"<\" || comparator.operator === \"<=\") {\n\t\t\t\tconst lowerBound = lowerUpperBound(upper, comparator);\n\t\t\t\tif (lowerBound === comparator && lowerBound !== upper) return false;\n\t\t\t} else if (upper.operator === \"<=\" && !testParsedComparator(comparator, upper.version)) return false;\n\t\t}\n\t\tif (comparator.operator === \"\" && (lower || upper) && boundsComparison !== 0) return false;\n\t}\n\tif (lower && hasSupersetUpper && !upper && boundsComparison !== 0) return false;\n\tif (upper && hasSupersetLower && !lower && boundsComparison !== 0) return false;\n\treturn !needsLowerPrerelease && !needsUpperPrerelease;\n}\nfunction isRangeSubset(subset, superset, options = {}) {\n\tif (subset === superset) return true;\n\tconst parsedSubset = parseRange(subset, options);\n\tconst parsedSuperset = parseRange(superset, options);\n\tconst effectiveOptions = {\n\t\t...parsedSubset.options,\n\t\t...parsedSuperset.options,\n\t\t...options\n\t};\n\tlet sawNonNull = false;\n\tfor (const subsetSet of parsedSubset.sets) {\n\t\tlet matched = false;\n\t\tfor (const supersetSet of parsedSuperset.sets) {\n\t\t\tconst result = simpleRangeSubset(subsetSet, supersetSet, effectiveOptions);\n\t\t\tsawNonNull ||= result !== null;\n\t\t\tif (result) {\n\t\t\t\tmatched = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!matched && sawNonNull) return false;\n\t}\n\treturn true;\n}\n//#endregion\nexport { isGreaterThanRange as a, isValidRange as c, rangesIntersect as d, satisfies as f, tryParseRange as h, findMinimumForRange as i, normalizeRange as l, parseRange as m, findMaxSatisfying as n, isLessThanRange as o, simplifyRange as p, findMinSatisfying as r, isOutsideRange as s, isRangeSubset as t, rangeToComparators as u };\n", "import { parseCompiledCatalog } from \"../db/releaseCatalog.mjs\";\nimport { rangesIntersect } from \"verkit\";\n//#region src/core/baseCandidates.ts\n/** A compiled segment as a range: its version when it holds exactly one. */\nconst segmentRange = ({ lower, upper }) => lower?.inclusive && upper?.inclusive && lower.version === upper.version ? lower.version : [lower === null ? \"\" : `${lower.inclusive ? \">=\" : \">\"}${lower.version}`, upper === null ? \"\" : `${upper.inclusive ? \"<=\" : \"<\"}${upper.version}`].join(\" \").trim() || \"*\";\n/**\n* Auto-patch bases from a scope's compiled Release Catalog, which holds\n* every enabled bundle release of the scope: those whose range intersects\n* `range` (all of them in a fingerprint scope), newest release first, each\n* bundle once and older than `bundleId`, at most `limit`.\n*/\nconst baseBundleIdsOf = (row, range, bundleId, limit) => {\n\tconst catalog = parseCompiledCatalog(row.payload, row.strategy);\n\tconst serving = new Set(catalog.strategy === \"FINGERPRINT\" ? catalog.rollbackReleaseIndexes : catalog.segments.flatMap((segment) => range !== null && rangesIntersect(range, segmentRange(segment)) ? segment.rollbackReleaseIndexes : []));\n\tconst newestFirst = catalog.releaseDescriptors.map((descriptor, index) => ({\n\t\tdescriptor,\n\t\tindex\n\t})).sort((left, right) => left.descriptor.releaseId < right.descriptor.releaseId ? 1 : -1);\n\tconst ids = [];\n\tfor (const { descriptor, index } of newestFirst) {\n\t\tif (ids.length >= limit) break;\n\t\tconst id = descriptor.bundleId;\n\t\tif (serving.has(index) && id !== null && id < bundleId && !ids.includes(id)) ids.push(id);\n\t}\n\treturn ids;\n};\n//#endregion\nexport { baseBundleIdsOf };\n", "import { projectReleaseCatalogRow, releaseCatalogScopeKeyOf } from \"../db/releaseCatalog.mjs\";\nimport { resolveManifestArtifacts } from \"../db/updateArtifacts.mjs\";\nimport { baseBundleIdsOf } from \"./baseCandidates.mjs\";\nimport { parseBaseCandidateKey, rowToBundle } from \"@hot-updater/plugin-core\";\nimport { ARTIFACT_PROTOCOL_VERSION, NIL_UUID } from \"@hot-updater/protocol\";\n//#region src/core/reads.ts\nconst PAGE = 500;\nconst pick = (fields) => (row) => Object.fromEntries(fields.map((field) => [field, row[field]]));\nconst toBundleRow = pick([\n\t\"id\",\n\t\"platform\",\n\t\"git_commit_hash\",\n\t\"metadata\",\n\t\"manifest_storage_uri\",\n\t\"manifest_file_hash\",\n\t\"asset_base_storage_uri\"\n]);\nconst toPatchRow = pick([\n\t\"id\",\n\t\"bundle_id\",\n\t\"base_bundle_id\",\n\t\"base_file_hash\",\n\t\"patch_file_hash\",\n\t\"patch_storage_uri\",\n\t\"byte_size\",\n\t\"order_index\"\n]);\nconst toReleaseRow = pick([\n\t\"id\",\n\t\"revision\",\n\t\"scope_key\",\n\t\"channel_id\",\n\t\"platform\",\n\t\"kind\",\n\t\"bundle_id\",\n\t\"strategy\",\n\t\"target_app_version\",\n\t\"fingerprint_hash\",\n\t\"enabled\",\n\t\"should_force_update\",\n\t\"message\",\n\t\"rollout_cohort_count\",\n\t\"target_cohorts\",\n\t\"operation\",\n\t\"source_release_id\",\n\t\"created_at_ms\",\n\t\"updated_at_ms\"\n]);\nconst toCatalogRow = pick([\n\t\"scope_key\",\n\t\"catalog_id\",\n\t\"strategy\",\n\t\"channel_id\",\n\t\"channel_key\",\n\t\"platform\",\n\t\"fingerprint_hash\",\n\t\"generation\",\n\t\"payload\",\n\t\"catalog_hash\",\n\t\"byte_size\",\n\t\"is_tombstone\",\n\t\"updated_at_ms\"\n]);\nconst toChannelRow = pick([\"id\", \"name\"]);\n/** Every page of one read, in order. */\nconst drain = async (read) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await read(cursor === void 0 ? {} : { cursor });\n\t\trows.push(...page.rows);\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\n/** Core's reads, each through one declared index or key. */\nconst createCoreReads = (db, storage) => {\n\t/** A bundle row's patches, exactly as many as its reference counter holds. */\n\tconst detail = async (row) => {\n\t\tconst count = row._refs_bundle_patches_bundle_id ?? 0;\n\t\tconst patches = [];\n\t\tlet cursor;\n\t\twhile (patches.length < count) {\n\t\t\tconst page = await db.findMany(\"bundle_patches\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: { bundle_id: row.id },\n\t\t\t\tlimit: Math.min(count - patches.length, PAGE),\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\tpatches.push(...page.rows.map(toPatchRow));\n\t\t\tif (page.next === void 0) break;\n\t\t\tcursor = page.next;\n\t\t}\n\t\treturn {\n\t\t\tbundle: toBundleRow(row),\n\t\t\tpatches,\n\t\t\tchildCount: row._refs_bundle_patches_base_bundle_id ?? 0\n\t\t};\n\t};\n\tconst after = (input) => input.after === void 0 ? {} : { range: (input.order ?? \"asc\") === \"asc\" ? { gt: input.after } : { lt: input.after } };\n\treturn {\n\t\t/** The update check: one point read of its scope's catalog. */\n\t\tasync getReleaseCatalog(input) {\n\t\t\tconst scopeKey = releaseCatalogScopeKeyOf(input);\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\t\t\treturn projectReleaseCatalogRow(row === null ? null : toCatalogRow(row), input, scopeKey);\n\t\t},\n\t\t/** Artifact resolution: one batch read of both bundles and one unique read of their patch. */\n\t\tasync getArtifactInfo(targetBundleId, currentBundleId, artifactProtocolVersion) {\n\t\t\tconst { readStorageText } = storage;\n\t\t\tif (artifactProtocolVersion !== ARTIFACT_PROTOCOL_VERSION || readStorageText === void 0) return null;\n\t\t\tconst withCurrent = currentBundleId !== NIL_UUID;\n\t\t\tconst [[target, current], patch] = await Promise.all([db.findByKeys(\"bundles\", withCurrent ? [{ id: targetBundleId }, { id: currentBundleId }] : [{ id: targetBundleId }]), withCurrent ? db.findOne(\"bundle_patches\", {\n\t\t\t\tbundle_id: targetBundleId,\n\t\t\t\tbase_bundle_id: currentBundleId\n\t\t\t}) : null]);\n\t\t\tif (target === null || target === void 0) return null;\n\t\t\treturn resolveManifestArtifacts({\n\t\t\t\tcurrentBundle: current ? rowToBundle(toBundleRow(current)) : null,\n\t\t\t\treadStorageText,\n\t\t\t\tresolveFileUrl: storage.resolveFileUrl,\n\t\t\t\ttargetBundle: rowToBundle(toBundleRow(target), patch === null ? [] : [toPatchRow(patch)])\n\t\t\t});\n\t\t},\n\t\t/** A bundle, its patches, and how many patches start from it. */\n\t\tasync getBundle(id) {\n\t\t\tconst row = await db.findOne(\"bundles\", { id });\n\t\t\treturn row === null ? null : detail(row);\n\t\t},\n\t\t/** One page of the patches that start from a bundle, by target bundle id. */\n\t\t/** Each base bundle's reference counter: one batch read of the bundle rows, and no patches. */\n\t\tasync countBundleChildren(baseBundleIds) {\n\t\t\tconst ids = [...new Set(baseBundleIds)];\n\t\t\tif (ids.length === 0) return {};\n\t\t\tconst rows = await db.findByKeys(\"bundles\", ids.map((id) => ({ id })));\n\t\t\treturn Object.fromEntries(ids.map((id, position) => [id, rows[position]?._refs_bundle_patches_base_bundle_id ?? 0]));\n\t\t},\n\t\tasync listPatchesFromBase(baseBundleId, input) {\n\t\t\treturn (await db.findMany(\"bundle_patches\", {\n\t\t\t\tindex: \"byBase\",\n\t\t\t\twhere: { base_bundle_id: baseBundleId },\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t})).rows.map(toPatchRow);\n\t\t},\n\t\t/** One page of bundles with their patches, oldest or newest first, optionally for one platform. */\n\t\tasync listBundles(input) {\n\t\t\tconst page = input.platform === void 0 ? await db.findMany(\"bundles\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t}) : await db.findMany(\"bundles\", {\n\t\t\t\tindex: \"byPlatform\",\n\t\t\t\twhere: { platform: input.platform },\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t});\n\t\t\treturn Promise.all(page.rows.map(detail));\n\t\t},\n\t\t/** Bundles in total or for one platform: one counter row. */\n\t\tasync countBundles(platform) {\n\t\t\tconst { rows } = await db.findAggregates(\"bundle_totals\", {\n\t\t\t\tindex: \"byPlatform\",\n\t\t\t\twhere: { platform_key: platform ?? \"*\" },\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn rows[0]?.bundles ?? 0;\n\t\t},\n\t\t/** Auto-patch bases for a new bundle: one point read of its scope's catalog. */\n\t\tasync findBaseBundleIds(candidateKey, bundleId, limit) {\n\t\t\tconst query = parseBaseCandidateKey(candidateKey);\n\t\t\tif (query === null) return [];\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: query.scopeKey });\n\t\t\treturn row === null ? [] : baseBundleIdsOf(toCatalogRow(row), query.range, bundleId, limit);\n\t\t},\n\t\tasync getRelease(id) {\n\t\t\tconst row = await db.findOne(\"releases\", { id });\n\t\t\treturn row === null ? null : toReleaseRow(row);\n\t\t},\n\t\t/** One page of releases through the index its filter names. */\n\t\tasync listReleases(input) {\n\t\t\tconst { filter } = input;\n\t\t\tconst options = {\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t};\n\t\t\treturn (filter.kind === \"all\" ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\t...options\n\t\t\t}) : filter.kind === \"bundle\" ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: { bundle_id: filter.bundleId },\n\t\t\t\t...options\n\t\t\t}) : filter.kind === \"scope\" ? filter.enabled === void 0 ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScope\",\n\t\t\t\twhere: { scope_key: filter.scopeKey },\n\t\t\t\t...options\n\t\t\t}) : await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScopeEnabled\",\n\t\t\t\twhere: {\n\t\t\t\t\tscope_key: filter.scopeKey,\n\t\t\t\t\tenabled: filter.enabled\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t}) : filter.enabled === void 0 ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byChannelPlatform\",\n\t\t\t\twhere: {\n\t\t\t\t\tchannel_id: filter.channelId,\n\t\t\t\t\tplatform: filter.platform\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t}) : await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byChannelPlatformEnabled\",\n\t\t\t\twhere: {\n\t\t\t\t\tchannel_id: filter.channelId,\n\t\t\t\t\tplatform: filter.platform,\n\t\t\t\t\tenabled: filter.enabled\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t})).rows.map(toReleaseRow);\n\t\t},\n\t\t/** A scope's newest release id: `byScope` descending, limit 1. */\n\t\tasync latestReleaseId(scopeKey) {\n\t\t\tconst { rows } = await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScope\",\n\t\t\t\twhere: { scope_key: scopeKey },\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn rows[0]?.id ?? null;\n\t\t},\n\t\tasync getReleaseCatalogRow(scopeKey) {\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\t\t\treturn row === null ? null : toCatalogRow(row);\n\t\t},\n\t\tasync listReleaseCatalogs(input) {\n\t\t\treturn (await db.findMany(\"release_catalogs\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t})).rows.map(toCatalogRow);\n\t\t},\n\t\t/** Every channel, by name. */\n\t\tasync listChannels() {\n\t\t\treturn (await drain((page) => db.findMany(\"channels\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\tlimit: PAGE,\n\t\t\t\t...page\n\t\t\t}))).map(toChannelRow);\n\t\t},\n\t\tasync findChannelByName(name) {\n\t\t\tconst row = await db.findOne(\"channels\", { name });\n\t\t\treturn row === null ? null : toChannelRow(row);\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreReads, drain, toBundleRow, toCatalogRow, toChannelRow, toPatchRow, toReleaseRow };\n", "import { toChannelRow } from \"./reads.mjs\";\nimport { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/core/writes.ts\nconst PAGE = 500;\n/** Moves one bundle into or out of its platform's total and the overall total. */\nconst countBundle = (tx, platform, delta) => {\n\tfor (const key of [platform, \"*\"]) tx.aggregate(\"bundle_totals\", { platform_key: key }, { bundles: delta });\n};\nconst insertBundle = (tx, row) => {\n\ttx.create(\"bundles\", row);\n\tcountBundle(tx, row.platform, 1);\n};\nconst updateBundle = (tx, current, set) => {\n\ttx.update(\"bundles\", current, set);\n\tif (set.platform !== void 0 && set.platform !== current.platform) {\n\t\tcountBundle(tx, current.platform, -1);\n\t\tcountBundle(tx, set.platform, 1);\n\t}\n};\n/** Deletes a bundle and, by cascade, every patch to or from it; a release on it refuses. */\nconst deleteBundle = async (tx, current) => {\n\tawait tx.delete(\"bundles\", current);\n\tcountBundle(tx, current.platform, -1);\n};\n/**\n* Replaces a bundle's patches with `rows`: kept patches are updated where\n* they changed, others deleted or created, so no key is written twice.\n*/\nconst replaceBundlePatches = async (tx, bundle, rows) => {\n\tconst wanted = new Map(rows.map((row) => [row.id, row]));\n\tconst count = bundle._refs_bundle_patches_bundle_id ?? 0;\n\tlet cursor;\n\tfor (let seen = 0; seen < count;) {\n\t\tconst page = await tx.findMany(\"bundle_patches\", {\n\t\t\tindex: \"byBundle\",\n\t\t\twhere: { bundle_id: bundle.id },\n\t\t\tlimit: Math.min(count - seen, PAGE),\n\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t});\n\t\tfor (const stored of page.rows) {\n\t\t\tconst next = wanted.get(stored.id);\n\t\t\twanted.delete(stored.id);\n\t\t\tif (next === void 0) {\n\t\t\t\tawait tx.delete(\"bundle_patches\", stored);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst set = Object.fromEntries(Object.entries(next).filter(([field, value]) => field !== \"id\" && stored[field] !== value));\n\t\t\tif (Object.keys(set).length > 0) tx.update(\"bundle_patches\", stored, set);\n\t\t}\n\t\tseen += page.rows.length;\n\t\tif (page.next === void 0) break;\n\t\tcursor = page.next;\n\t}\n\tfor (const row of wanted.values()) tx.create(\"bundle_patches\", row);\n};\n/** A channel by name, created when missing; a concurrent creator's row is returned instead. */\nconst insertChannel = async (db, row) => {\n\tfor (let attempt = 1;; attempt += 1) try {\n\t\treturn await db.transaction(async (tx) => {\n\t\t\tconst existing = await tx.findOne(\"channels\", { name: row.name });\n\t\t\tif (existing !== null) return {\n\t\t\t\trow: toChannelRow(existing),\n\t\t\t\tinserted: false\n\t\t\t};\n\t\t\ttx.create(\"channels\", row);\n\t\t\treturn {\n\t\t\t\trow,\n\t\t\t\tinserted: true\n\t\t\t};\n\t\t});\n\t} catch (error) {\n\t\tif (attempt < 3 && error instanceof DatabaseConstraintError && (error.reason === \"unique\" || error.reason === \"exists\")) continue;\n\t\tthrow error;\n\t}\n};\n/** Deletes a channel no release uses: 1 read + 1 write. */\nconst deleteChannel = (db, id) => db.transaction(async (tx) => {\n\tconst row = await tx.findOne(\"channels\", { id });\n\tif (row === null) return {\n\t\tdeleted: false,\n\t\treason: \"not_found\"\n\t};\n\tif ((row._refs_releases_channel_id ?? 0) > 0) return {\n\t\tdeleted: false,\n\t\treason: \"not_empty\"\n\t};\n\tawait tx.delete(\"channels\", row);\n\treturn { deleted: true };\n});\n//#endregion\nexport { deleteBundle, deleteChannel, insertBundle, insertChannel, replaceBundlePatches, updateBundle };\n", "import { toCatalogRow, toReleaseRow } from \"./reads.mjs\";\nimport { insertBundle } from \"./writes.mjs\";\nimport { ReleaseCatalogMutationError, compileReleaseCatalog, createUUIDv7, createUUIDv7After, isUUIDv7, releaseRowToRelease } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey, encodeChannelKey } from \"@hot-updater/protocol\";\n//#region src/core/releases.ts\nconst PAGE = 500;\nconst fail = (code, message) => {\n\tthrow new ReleaseCatalogMutationError(code, message);\n};\nconst checkScope = (scope) => {\n\tconst channelKey = encodeChannelKey(scope.channelName);\n\tconst expected = scope.strategy === \"APP_VERSION\" ? createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tplatform: scope.platform,\n\t\tstrategy: \"APP_VERSION\"\n\t}) : createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tfingerprintHash: scope.fingerprintHash ?? \"\",\n\t\tplatform: scope.platform,\n\t\tstrategy: \"FINGERPRINT\"\n\t});\n\tif (scope.strategy === \"FINGERPRINT\" !== (scope.fingerprintHash !== null) || scope.scopeKey !== expected) fail(\"INVALID_SCOPE\", \"Release catalog scope metadata is inconsistent\");\n};\n/** A scope's enabled releases, all of them, under the catalog's guard. */\nconst enabledReleases = async (tx, scopeKey) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await tx.findMany(\"releases\", {\n\t\t\tindex: \"byScopeEnabled\",\n\t\t\twhere: {\n\t\t\t\tscope_key: scopeKey,\n\t\t\t\tenabled: true\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t});\n\t\trows.push(...page.rows.map(toReleaseRow));\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\n/** The scope's newest release id: `byScope` descending, limit 1. */\nconst latestReleaseId = async (tx, scopeKey) => {\n\tconst { rows } = await tx.findMany(\"releases\", {\n\t\tindex: \"byScope\",\n\t\twhere: { scope_key: scopeKey },\n\t\torder: \"desc\",\n\t\tlimit: 1\n\t});\n\treturn rows[0]?.id ?? null;\n};\n/** Compiles `enabled` and writes it as the scope's next catalog generation. */\nconst writeCatalog = async (tx, scope, stored, enabled, updatedAtMs) => {\n\tconst compilation = await compileReleaseCatalog({\n\t\tstrategy: scope.strategy,\n\t\treleases: enabled.map(releaseRowToRelease)\n\t});\n\tconst generation = (stored.generation ?? 0) + 1;\n\tif (!Number.isSafeInteger(generation)) fail(\"CATALOG_GENERATION_EXHAUSTED\", `Catalog \"${scope.scopeKey}\" exhausted its generation counter`);\n\tconst catalog = {\n\t\tscope_key: scope.scopeKey,\n\t\tcatalog_id: stored.catalog?.catalog_id ?? createUUIDv7(),\n\t\tstrategy: scope.strategy,\n\t\tchannel_id: scope.channelId,\n\t\tchannel_key: encodeChannelKey(scope.channelName),\n\t\tplatform: scope.platform,\n\t\tfingerprint_hash: scope.fingerprintHash,\n\t\tgeneration,\n\t\tpayload: compilation.canonicalPayload,\n\t\tcatalog_hash: compilation.catalogHash,\n\t\tbyte_size: compilation.byteSize,\n\t\tis_tombstone: compilation.payload.releaseDescriptors.length === 0,\n\t\tupdated_at_ms: updatedAtMs\n\t};\n\tconst { scope_key: _scopeKey, ...set } = catalog;\n\tif (stored.row === null) tx.create(\"release_catalogs\", catalog);\n\telse tx.update(\"release_catalogs\", stored.row, set);\n\treturn {\n\t\tcatalog,\n\t\tcompilation\n\t};\n};\n/** The scope's catalog row, and its compiled catalog and generation if it has one. */\nconst readCatalog = async (tx, scopeKey) => {\n\tconst row = await tx.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\treturn {\n\t\trow,\n\t\tgeneration: row?.generation ?? null,\n\t\tcatalog: row === null ? null : toCatalogRow(row)\n\t};\n};\n/** A scope with releases and no compiled catalog lost its history. */\nconst assertHistory = (stored, hasReleases) => {\n\tif (stored.catalog === null && hasReleases) fail(\"CATALOG_IDENTITY_MISSING\", \"Catalog history is missing. Restore its catalog row from backup before rebuilding or deploying.\");\n};\n/** One release change and its scope's next catalog, inside `tx`. */\nconst changeRelease = async (tx, { scope, change, bundle, updatedAtMs }) => {\n\tcheckScope(scope);\n\tconst stored = await readCatalog(tx, scope.scopeKey);\n\tconst enabled = await enabledReleases(tx, scope.scopeKey);\n\tif (bundle !== void 0) {\n\t\tinsertBundle(tx, bundle.row);\n\t\tfor (const patch of bundle.patches) tx.create(\"bundle_patches\", patch);\n\t}\n\tlet before = null;\n\tlet release;\n\tif (change.operation === \"insert\") {\n\t\tconst latest = await latestReleaseId(tx, scope.scopeKey);\n\t\tassertHistory(stored, latest !== null);\n\t\tconst floor = [latest, bundle && isUUIDv7(bundle.row.id) ? bundle.row.id : null].filter((id) => id !== null).sort().at(-1);\n\t\tconst id = change.row.id ?? createUUIDv7After(floor ?? null);\n\t\tif (latest !== null && id <= latest) fail(\"NON_MONOTONIC_RELEASE_ID\", `Release \"${id}\" must sort after \"${latest}\"`);\n\t\trelease = {\n\t\t\t...change.row,\n\t\t\tid\n\t\t};\n\t\tif (release.scope_key !== scope.scopeKey || release.channel_id !== scope.channelId || release.platform !== scope.platform || release.strategy !== scope.strategy || release.fingerprint_hash !== scope.fingerprintHash || release.revision !== 1) fail(\"INVALID_SCOPE\", \"Inserted Release does not match its catalog scope\");\n\t\ttx.create(\"releases\", release);\n\t} else {\n\t\tconst row = await tx.findOne(\"releases\", { id: change.id });\n\t\tif (row === null || row.scope_key !== scope.scopeKey) return fail(\"RELEASE_NOT_FOUND\", `Release \"${change.id}\" was not found in scope \"${scope.scopeKey}\"`);\n\t\tassertHistory(stored, true);\n\t\tbefore = toReleaseRow(row);\n\t\tif (change.operation === \"delete\") {\n\t\t\tawait tx.delete(\"releases\", row);\n\t\t\trelease = null;\n\t\t} else {\n\t\t\tconst set = {\n\t\t\t\t...change.update,\n\t\t\t\trevision: before.revision + 1\n\t\t\t};\n\t\t\ttx.update(\"releases\", row, set);\n\t\t\trelease = {\n\t\t\t\t...before,\n\t\t\t\t...set\n\t\t\t};\n\t\t}\n\t}\n\tconst changedId = before?.id ?? release?.id;\n\tconst next = [...enabled.filter(({ id }) => id !== changedId), ...release?.enabled ? [release] : []].sort((left, right) => left.id < right.id ? -1 : 1);\n\tconst { catalog, compilation } = await writeCatalog(tx, scope, stored, next, updatedAtMs);\n\treturn {\n\t\tcatalog,\n\t\trelease,\n\t\tdiagnostics: compilation.diagnostics\n\t};\n};\n/**\n* Release changes rooted at their catalogs: each reads its scope's catalog\n* and enabled releases, applies the change, and writes the next catalog\n* generation, all in one transaction. A concurrent change in a scope bumps\n* its catalog row, so this transaction reruns instead of publishing a stale\n* catalog.\n*/\nconst changeReleases = (db, inputs) => {\n\tif (new Set(inputs.map(({ scope }) => scope.scopeKey)).size !== inputs.length) fail(\"INVALID_SCOPE\", \"A batch cannot change one catalog scope twice\");\n\treturn db.transaction(async (tx) => {\n\t\tconst results = [];\n\t\tfor (const input of inputs) results.push(await changeRelease(tx, input));\n\t\treturn results;\n\t});\n};\n/** Recompiles a scope's catalog from its enabled releases inside `tx`; an unchanged catalog is not rewritten. */\nconst rebuildScope = async (tx, scope, updatedAtMs) => {\n\tcheckScope(scope);\n\tconst stored = await readCatalog(tx, scope.scopeKey);\n\tassertHistory(stored, await latestReleaseId(tx, scope.scopeKey) !== null);\n\tconst enabled = await enabledReleases(tx, scope.scopeKey);\n\tconst compilation = await compileReleaseCatalog({\n\t\tstrategy: scope.strategy,\n\t\treleases: enabled.map(releaseRowToRelease)\n\t});\n\tconst current = stored.catalog;\n\tif (current !== null && current.strategy === scope.strategy && current.channel_id === scope.channelId && current.channel_key === encodeChannelKey(scope.channelName) && current.platform === scope.platform && current.fingerprint_hash === scope.fingerprintHash && current.catalog_hash === compilation.catalogHash) return {\n\t\tcatalog: current,\n\t\tcurrent,\n\t\tchanged: false,\n\t\tdiagnostics: compilation.diagnostics\n\t};\n\tconst written = await writeCatalog(tx, scope, stored, enabled, updatedAtMs);\n\treturn {\n\t\tcatalog: written.catalog,\n\t\tcurrent,\n\t\tchanged: true,\n\t\tdiagnostics: written.compilation.diagnostics\n\t};\n};\n//#endregion\nexport { changeRelease, changeReleases, readCatalog, rebuildScope };\n", "import { toBundleRow, toReleaseRow } from \"./reads.mjs\";\nimport { deleteBundle, deleteChannel, insertChannel, replaceBundlePatches, updateBundle } from \"./writes.mjs\";\nimport { changeRelease, changeReleases, readCatalog, rebuildScope } from \"./releases.mjs\";\nimport { DatabaseBundleNotFoundError, DatabaseConstraintError, DatabaseRowReferencedError, ReleaseCatalogMutationError, ReleaseManagementError, bundleToPatchRows, bundleToRow, createUUIDv7After, isUUIDv7, rowToBundle } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey, decodeChannelKey, encodeChannelKey } from \"@hot-updater/protocol\";\n//#region src/core/operations.ts\n/** Carries a preflight's result out of the transaction it stops, so nothing is written. */\nvar Preflight = class extends Error {\n\tresult;\n\tconstructor(result) {\n\t\tsuper(\"preflight\");\n\t\tthis.result = result;\n\t}\n};\nconst dryRun = async (db, read) => {\n\ttry {\n\t\tawait db.transaction(async (tx) => {\n\t\t\tthrow new Preflight(await read(tx));\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof Preflight) return error.result;\n\t\tthrow error;\n\t}\n\tthrow new Error(\"A preflight transaction returned without its result.\");\n};\n/** A channel's catalog scope for a platform, and a fingerprint when it has one. */\nconst scopeOf = (channel, platform, fingerprintHash) => {\n\tconst channelKey = encodeChannelKey(channel.name);\n\treturn fingerprintHash === null ? {\n\t\tchannelId: channel.id,\n\t\tchannelName: channel.name,\n\t\tfingerprintHash,\n\t\tplatform,\n\t\tscopeKey: createReleaseCatalogScopeKey({\n\t\t\tchannelKey,\n\t\t\tplatform,\n\t\t\tstrategy: \"APP_VERSION\"\n\t\t}),\n\t\tstrategy: \"APP_VERSION\"\n\t} : {\n\t\tchannelId: channel.id,\n\t\tchannelName: channel.name,\n\t\tfingerprintHash,\n\t\tplatform,\n\t\tscopeKey: createReleaseCatalogScopeKey({\n\t\t\tchannelKey,\n\t\t\tfingerprintHash,\n\t\t\tplatform,\n\t\t\tstrategy: \"FINGERPRINT\"\n\t\t}),\n\t\tstrategy: \"FINGERPRINT\"\n\t};\n};\n/** A release and its scope, checked against the revision the caller saw. */\nconst loadTarget = async (tx, { releaseId, expectedRevision }) => {\n\tconst row = await tx.findOne(\"releases\", { id: releaseId });\n\tif (row === null) throw new ReleaseManagementError(\"RELEASE_NOT_FOUND\", `Release \"${releaseId}\" was not found.`);\n\tconst release = toReleaseRow(row);\n\tif (expectedRevision !== void 0 && expectedRevision !== release.revision) throw new ReleaseManagementError(\"VERSION_CONFLICT\", `Release \"${release.id}\" is revision ${release.revision}; expected ${expectedRevision}.`);\n\tconst catalog = await tx.findOne(\"release_catalogs\", { scope_key: release.scope_key });\n\tif (catalog === null) throw new ReleaseCatalogMutationError(\"INVALID_SCOPE\", `Release \"${release.id}\" has no catalog projection.`);\n\treturn {\n\t\trelease,\n\t\tscope: {\n\t\t\tchannelId: release.channel_id,\n\t\t\tchannelName: decodeChannelKey(catalog.channel_key),\n\t\t\tfingerprintHash: release.fingerprint_hash,\n\t\t\tplatform: release.platform,\n\t\t\tscopeKey: release.scope_key,\n\t\t\tstrategy: release.strategy\n\t\t}\n\t};\n};\nconst policyUpdate = (release, patch, updatedAtMs) => {\n\tif (patch.fingerprintHash !== void 0 && patch.fingerprintHash !== release.fingerprint_hash) throw new ReleaseManagementError(\"SCOPE_MOVE_UNSUPPORTED\", \"Changing a fingerprint target requires an atomic Release scope move.\");\n\treturn {\n\t\t...patch.enabled === void 0 ? {} : { enabled: patch.enabled },\n\t\t...patch.message === void 0 ? {} : { message: patch.message },\n\t\t...patch.rolloutCohortCount === void 0 ? {} : { rollout_cohort_count: patch.rolloutCohortCount },\n\t\t...patch.shouldForceUpdate === void 0 ? {} : { should_force_update: patch.shouldForceUpdate },\n\t\t...patch.targetAppVersion === void 0 ? {} : { target_app_version: patch.targetAppVersion },\n\t\t...patch.targetCohorts === void 0 ? {} : { target_cohorts: [...patch.targetCohorts] },\n\t\tupdated_at_ms: updatedAtMs\n\t};\n};\nconst mutationResult = ({ catalog, release }) => ({\n\tattempts: 1,\n\tcatalog,\n\trelease\n});\n/** The scope a catalog row names, for a rebuild. */\nconst catalogScope = async (tx, scopeKey) => {\n\tconst row = await tx.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\tif (row === null) throw new Error(`Release catalog \"${scopeKey}\" was not found.`);\n\treturn {\n\t\tchannelId: row.channel_id,\n\t\tchannelName: decodeChannelKey(row.channel_key),\n\t\tfingerprintHash: row.fingerprint_hash,\n\t\tplatform: row.platform,\n\t\tscopeKey: row.scope_key,\n\t\tstrategy: row.strategy\n\t};\n};\n/**\n* Core's typed writes: each runs in one engine transaction rooted at the\n* catalogs it changes, so a concurrent change reruns it instead of\n* publishing a stale catalog.\n*/\nconst createCoreOperations = (db, { now = Date.now } = {}) => {\n\tconst ensureChannel = async (name) => (await insertChannel(db, {\n\t\tid: `channel:${encodeChannelKey(name)}`,\n\t\tname\n\t})).row;\n\t/**\n\t* Runs a write that ensured its channels first. A channel deleted between\n\t* that and the write refuses the write, so it runs again and ensures it anew.\n\t*/\n\tconst withChannels = async (write) => {\n\t\tfor (let attempt = 1;; attempt += 1) try {\n\t\t\treturn await write();\n\t\t} catch (error) {\n\t\t\tif (attempt < 3 && error instanceof DatabaseConstraintError && error.reason === \"not_found\" && error.model === \"channels\") continue;\n\t\t\tthrow error;\n\t\t}\n\t};\n\tconst deployOnce = async (deployments) => {\n\t\tconst channels = /* @__PURE__ */ new Map();\n\t\tfor (const { release } of deployments) if (!channels.has(release.channel)) channels.set(release.channel, await ensureChannel(release.channel));\n\t\tconst platforms = /* @__PURE__ */ new Map();\n\t\tfor (const deployment of deployments) {\n\t\t\tif (!(\"bundleId\" in deployment) || platforms.has(deployment.bundleId)) continue;\n\t\t\tconst row = await db.findOne(\"bundles\", { id: deployment.bundleId });\n\t\t\tif (row === null) throw new DatabaseBundleNotFoundError(deployment.bundleId);\n\t\t\tplatforms.set(deployment.bundleId, toBundleRow(row).platform);\n\t\t}\n\t\tconst updatedAtMs = now();\n\t\treturn (await changeReleases(db, deployments.map((deployment) => {\n\t\t\tconst { release: policy } = deployment;\n\t\t\tconst stored = \"bundleId\" in deployment;\n\t\t\tconst bundleId = stored ? deployment.bundleId : deployment.bundle.id;\n\t\t\tconst platform = stored ? platforms.get(deployment.bundleId) : deployment.bundle.platform;\n\t\t\tconst scope = scopeOf(channels.get(policy.channel), platform, policy.fingerprintHash);\n\t\t\treturn {\n\t\t\t\tscope,\n\t\t\t\t...stored ? {} : { bundle: {\n\t\t\t\t\trow: bundleToRow(deployment.bundle),\n\t\t\t\t\tpatches: bundleToPatchRows(deployment.bundle)\n\t\t\t\t} },\n\t\t\t\tchange: {\n\t\t\t\t\toperation: \"insert\",\n\t\t\t\t\trow: {\n\t\t\t\t\t\tbundle_id: bundleId,\n\t\t\t\t\t\tchannel_id: scope.channelId,\n\t\t\t\t\t\tcreated_at_ms: updatedAtMs,\n\t\t\t\t\t\tenabled: policy.enabled,\n\t\t\t\t\t\tfingerprint_hash: policy.fingerprintHash,\n\t\t\t\t\t\tkind: \"BUNDLE\",\n\t\t\t\t\t\tmessage: policy.message,\n\t\t\t\t\t\toperation: \"DEPLOY\",\n\t\t\t\t\t\tplatform,\n\t\t\t\t\t\trevision: 1,\n\t\t\t\t\t\trollout_cohort_count: policy.rolloutCohortCount ?? 1e3,\n\t\t\t\t\t\tscope_key: scope.scopeKey,\n\t\t\t\t\t\tshould_force_update: policy.shouldForceUpdate,\n\t\t\t\t\t\tsource_release_id: null,\n\t\t\t\t\t\tstrategy: scope.strategy,\n\t\t\t\t\t\ttarget_app_version: policy.targetAppVersion,\n\t\t\t\t\t\ttarget_cohorts: policy.targetCohorts ?? [],\n\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdatedAtMs\n\t\t\t};\n\t\t}))).map(mutationResult);\n\t};\n\treturn {\n\t\tdeploy: (deployments) => withChannels(() => deployOnce(deployments)),\n\t\tupdateReleasePolicy: (input) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\t\treturn mutationResult(await changeRelease(tx, {\n\t\t\t\t\tscope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: release.id,\n\t\t\t\t\t\tupdate: policyUpdate(release, input.patch, updatedAtMs)\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t}));\n\t\t\t});\n\t\t},\n\t\tpreflightReleasePolicy: (input) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn dryRun(db, async (tx) => {\n\t\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\t\tconst stored = await readCatalog(tx, scope.scopeKey);\n\t\t\t\tconst changed = await changeRelease(tx, {\n\t\t\t\t\tscope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: release.id,\n\t\t\t\t\t\tupdate: policyUpdate(release, input.patch, updatedAtMs)\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tcatalog: changed.catalog,\n\t\t\t\t\tcurrentCatalog: stored.catalog,\n\t\t\t\t\tdiagnostics: changed.diagnostics,\n\t\t\t\t\texpectedReleaseRevision: release.revision,\n\t\t\t\t\trelease: changed.release\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tdeleteRelease: (input) => db.transaction(async (tx) => {\n\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\tif (release.enabled) throw new ReleaseManagementError(\"ENABLED_RELEASE\", `Disable Release \"${release.id}\" before hard deletion.`);\n\t\t\tconst bundle = release.bundle_id === null ? null : await tx.findOne(\"bundles\", { id: release.bundle_id });\n\t\t\tconst result = mutationResult(await changeRelease(tx, {\n\t\t\t\tscope,\n\t\t\t\tchange: {\n\t\t\t\t\toperation: \"delete\",\n\t\t\t\t\tid: release.id\n\t\t\t\t},\n\t\t\t\tupdatedAtMs: now()\n\t\t\t}));\n\t\t\tif (bundle !== null && (bundle._refs_releases_bundle_id ?? 0) <= 1) await deleteBundle(tx, bundle);\n\t\t\treturn result;\n\t\t}),\n\t\tpromoteRelease: (input) => withChannels(async () => {\n\t\t\tconst checkSource = (source) => {\n\t\t\t\tif (source.bundle_id === null) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Only a Bundle Release can be promoted.\");\n\t\t\t};\n\t\t\tcheckSource((await db.transaction((tx) => loadTarget(tx, input))).release);\n\t\t\tconst targetChannel = input.targetChannel.trim();\n\t\t\tif (targetChannel.length === 0) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Promotion requires a target channel.\");\n\t\t\tconst channel = await ensureChannel(targetChannel);\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { release: source, scope: sourceScope } = await loadTarget(tx, input);\n\t\t\t\tcheckSource(source);\n\t\t\t\tconst targetScope = scopeOf(channel, source.platform, source.fingerprint_hash);\n\t\t\t\tif (targetScope.scopeKey === sourceScope.scopeKey) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Source and target Release scopes are the same.\");\n\t\t\t\tconst { rows } = await tx.findMany(\"releases\", {\n\t\t\t\t\tindex: \"byScope\",\n\t\t\t\t\twhere: { scope_key: targetScope.scopeKey },\n\t\t\t\t\torder: \"desc\",\n\t\t\t\t\tlimit: 1\n\t\t\t\t});\n\t\t\t\tconst floor = [\n\t\t\t\t\trows[0]?.id ?? null,\n\t\t\t\t\tsource.id,\n\t\t\t\t\tsource.bundle_id\n\t\t\t\t].filter((id) => id !== null && isUUIDv7(id)).sort().at(-1);\n\t\t\t\tconst moved = input.action === \"move\" ? await changeRelease(tx, {\n\t\t\t\t\tscope: sourceScope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: source.id,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t}) : null;\n\t\t\t\tconst target = await changeRelease(tx, {\n\t\t\t\t\tscope: targetScope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"insert\",\n\t\t\t\t\t\trow: {\n\t\t\t\t\t\t\t...source,\n\t\t\t\t\t\t\tid: createUUIDv7After(floor ?? null, updatedAtMs),\n\t\t\t\t\t\t\trevision: 1,\n\t\t\t\t\t\t\tscope_key: targetScope.scopeKey,\n\t\t\t\t\t\t\tchannel_id: targetScope.channelId,\n\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\trollout_cohort_count: 1e3,\n\t\t\t\t\t\t\ttarget_cohorts: [],\n\t\t\t\t\t\t\toperation: \"PROMOTE\",\n\t\t\t\t\t\t\tsource_release_id: source.id,\n\t\t\t\t\t\t\tcreated_at_ms: updatedAtMs,\n\t\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tsource: moved === null ? null : mutationResult(moved),\n\t\t\t\t\ttarget: mutationResult(target)\n\t\t\t\t};\n\t\t\t});\n\t\t}),\n\t\trebuildReleaseCatalog: (scopeKey) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { current: _current, ...rebuilt } = await rebuildScope(tx, await catalogScope(tx, scopeKey), updatedAtMs);\n\t\t\t\treturn {\n\t\t\t\t\tattempts: 1,\n\t\t\t\t\t...rebuilt\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tpreflightReleaseCatalogRebuild: (scopeKey) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn dryRun(db, async (tx) => {\n\t\t\t\tconst rebuilt = await rebuildScope(tx, await catalogScope(tx, scopeKey), updatedAtMs);\n\t\t\t\treturn {\n\t\t\t\t\tchanged: rebuilt.changed,\n\t\t\t\t\tcurrentCatalog: rebuilt.current,\n\t\t\t\t\tdiagnostics: rebuilt.diagnostics,\n\t\t\t\t\tprojectedCatalog: rebuilt.catalog\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tensureChannel,\n\t\tdeleteChannel: (id) => deleteChannel(db, id),\n\t\tupdateBundle: (id, update) => db.transaction(async (tx) => {\n\t\t\tconst current = await tx.findOne(\"bundles\", { id });\n\t\t\tif (current === null) throw new DatabaseBundleNotFoundError(id);\n\t\t\tconst { patches, ...fields } = update;\n\t\t\tconst next = {\n\t\t\t\t...rowToBundle(toBundleRow(current)),\n\t\t\t\t...fields,\n\t\t\t\tid\n\t\t\t};\n\t\t\tconst { id: _id, ...set } = bundleToRow(next);\n\t\t\tupdateBundle(tx, current, set);\n\t\t\tif (patches !== void 0) await replaceBundlePatches(tx, current, bundleToPatchRows({\n\t\t\t\t...next,\n\t\t\t\tpatches\n\t\t\t}));\n\t\t}),\n\t\tdeleteBundles: async (ids) => {\n\t\t\ttry {\n\t\t\t\tawait db.transaction(async (tx) => {\n\t\t\t\t\tfor (const id of new Set(ids)) {\n\t\t\t\t\t\tconst current = await tx.findOne(\"bundles\", { id });\n\t\t\t\t\t\tif (current !== null) await deleteBundle(tx, current);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DatabaseConstraintError && error.reason === \"referenced\") throw new DatabaseRowReferencedError();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreOperations };\n", "import { createCoreReads } from \"./reads.mjs\";\nimport { createCoreOperations } from \"./operations.mjs\";\n//#region src/core/api.ts\n/**\n* The update check answers from one Release Catalog row, so a transaction\n* changes what the cacheable client routes answer only when it writes one.\n* The purge runs once, after the attempt that commits.\n*/\nconst purgingCachedRoutes = (db, onCachedRoutesChange) => {\n\tif (onCachedRoutesChange === void 0) return db;\n\treturn {\n\t\t...db,\n\t\tasync transaction(fn) {\n\t\t\tlet changed = false;\n\t\t\tconst result = await db.transaction((tx) => {\n\t\t\t\tchanged = false;\n\t\t\t\treturn fn({\n\t\t\t\t\t...tx,\n\t\t\t\t\tcreate: (model, row) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\ttx.create(model, row);\n\t\t\t\t\t},\n\t\t\t\t\tupdate: (model, row, set) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\ttx.update(model, row, set);\n\t\t\t\t\t},\n\t\t\t\t\tdelete: (model, row) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\treturn tx.delete(model, row);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (changed) await onCachedRoutesChange();\n\t\t\treturn result;\n\t\t}\n\t};\n};\n/** Core's reads and typed writes over one database handle. */\nconst createCoreApi = (db, storage, options = {}) => {\n\tconst reads = createCoreReads(db, storage);\n\treturn {\n\t\t...reads,\n\t\t...createCoreOperations(purgingCachedRoutes(db, options.onCachedRoutesChange), options),\n\t\t/** One read, which checks the schema settings first. */\n\t\tready: async () => {\n\t\t\tawait reads.listReleaseCatalogs({ limit: 1 });\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreApi };\n", "import { createCoreReads } from \"../core/reads.mjs\";\nimport { createCoreApi } from \"../core/api.mjs\";\nimport { HotUpdaterConfigError } from \"./configError.mjs\";\nimport { checkReservedId } from \"../plugins/official.mjs\";\nimport { clientPluginsOf } from \"./clientPlugins.mjs\";\nimport { createEngine } from \"@hot-updater/plugin-core\";\n//#region src/assembly/assemblePlugins.ts\nconst PLUGIN_KEYS = /* @__PURE__ */ new Set([\n\t\"id\",\n\t\"provides\",\n\t\"schemaVersion\",\n\t\"schema\",\n\t\"namespace\",\n\t\"init\",\n\t\"cli\"\n]);\nconst CLI_KEYS = /* @__PURE__ */ new Set([\"clientCredential\", \"clientPlugin\"]);\nconst INSTANCE_KEYS = /* @__PURE__ */ new Set([\n\t\"api\",\n\t\"endpoints\",\n\t\"clientAuth\"\n]);\nconst METHODS = /* @__PURE__ */ new Set([\n\t\"GET\",\n\t\"POST\",\n\t\"PUT\",\n\t\"PATCH\",\n\t\"DELETE\"\n]);\n/** An id that prefixes table names is a SQL name; one that does not may use camelCase. */\nconst PREFIX_ID = /^[a-z][a-z0-9_]*$/u;\nconst UNPREFIXED_ID = /^[a-z][A-Za-z0-9_]*$/u;\nconst PATH = /^(\\/(:?[A-Za-z0-9_.~-]+))+$/u;\nconst fail = (message) => {\n\tthrow new HotUpdaterConfigError(message);\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst checkPlugin = (value, at) => {\n\tif (!isRecord(value)) return fail(`${at} is not a plugin.`);\n\tconst unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));\n\tif (unknown !== void 0) fail(`${at} has an unknown key \"${unknown}\".`);\n\tconst plugin = value;\n\tif (plugin.namespace !== void 0 && plugin.namespace !== false) fail(`${at} may only set namespace: false.`);\n\tconst pattern = plugin.namespace === false ? UNPREFIXED_ID : PREFIX_ID;\n\tif (typeof plugin.id !== \"string\" || !pattern.test(plugin.id)) fail(`${at} needs an id matching ${pattern.source}.`);\n\tif (plugin.id === \"core\") fail(`${at} uses the id \"core\", which is core's own.`);\n\tcheckReservedId(value, at);\n\tif (typeof plugin.schemaVersion !== \"string\" || !isRecord(plugin.schema) || typeof plugin.init !== \"function\") fail(`Plugin \"${plugin.id}\" needs a schemaVersion, a schema, and init.`);\n\tconst provides = plugin.provides;\n\tif (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 }.`);\n\tconst cli = value.cli;\n\tif (cli !== void 0) {\n\t\tif (!isRecord(cli) || Object.keys(cli).some((key) => !CLI_KEYS.has(key))) fail(`Plugin \"${plugin.id}\" cli may only hold clientCredential and clientPlugin.`);\n\t\tif (cli.clientCredential !== void 0 && plugin.provides?.clientAuth !== true) fail(`Plugin \"${plugin.id}\" adds cli.clientCredential without declaring provides: { clientAuth: true }.`);\n\t}\n\treturn plugin;\n};\nconst checkEndpoint = (id, value) => {\n\tconst endpoint = isRecord(value) ? value : {};\n\tif (!METHODS.has(endpoint.method) || typeof endpoint.path !== \"string\" || !PATH.test(endpoint.path) || endpoint.access !== \"client\" && endpoint.access !== \"admin\" || typeof endpoint.handler !== \"function\") fail(`Plugin \"${id}\" has an endpoint that needs a method, a path like /name/:param, access \"client\" or \"admin\", and a handler.`);\n\treturn {\n\t\t...endpoint,\n\t\tplugin: id\n\t};\n};\nconst checkInstance = (plugin, instance) => {\n\tconst { id } = plugin;\n\tif (!isRecord(instance)) return fail(`Plugin \"${id}\" init returned no instance.`);\n\tif (typeof instance.then === \"function\") fail(`Plugin \"${id}\" init returned a promise; init must be synchronous.`);\n\tconst unknown = Object.keys(instance).find((key) => !INSTANCE_KEYS.has(key));\n\tif (unknown !== void 0 || !(\"api\" in instance)) fail(`Plugin \"${id}\" init must return { api, endpoints?, clientAuth? }${unknown === void 0 ? \"\" : `, not \"${unknown}\"`}.`);\n\tconst declared = plugin.provides?.clientAuth === true;\n\tconst clientAuth = instance.clientAuth;\n\tif (declared !== (clientAuth !== void 0)) fail(declared ? `Plugin \"${id}\" declares provides: { clientAuth: true } but its instance has no clientAuth.` : `Plugin \"${id}\" returns clientAuth without declaring provides: { clientAuth: true }.`);\n\tif (clientAuth !== void 0 && (typeof clientAuth.authenticate !== \"function\" || !Array.isArray(clientAuth.varyHeaders) || !clientAuth.varyHeaders.every((header) => typeof header === \"string\"))) fail(`Plugin \"${id}\" clientAuth needs varyHeaders and authenticate.`);\n\tconst endpoints = instance.endpoints ?? [];\n\tif (!Array.isArray(endpoints)) fail(`Plugin \"${id}\" endpoints must be an array.`);\n\treturn {\n\t\tapi: instance.api,\n\t\tclientAuth,\n\t\tendpoints: endpoints.map((endpoint) => checkEndpoint(id, endpoint))\n\t};\n};\n/**\n* Checks every plugin, runs each `init` once against one engine over the\n* database, and collects APIs, endpoints, and clientAuth. Core's reads run\n* on the same engine, so plugins read core through `ctx.core`.\n*/\nconst assemblePlugins = (value, database, { now = Date.now, storage = { resolveFileUrl: async () => null } } = {}) => {\n\tif (!Array.isArray(value)) return fail(\"plugins must be an array of plugins.\");\n\tconst plugins = value.map((plugin, position) => checkPlugin(plugin, `plugins[${position}]`));\n\tconst ids = /* @__PURE__ */ new Set();\n\tfor (const { id } of plugins) {\n\t\tif (ids.has(id)) fail(`Plugin \"${id}\" is registered twice.`);\n\t\tids.add(id);\n\t}\n\tclientPluginsOf(plugins);\n\tconst engine = createEngine(database, {\n\t\tplugins,\n\t\tnow\n\t});\n\tconst { onCachedRoutesChange } = database;\n\tconst core = createCoreApi(engine.core, storage, {\n\t\tnow,\n\t\t...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange: () => onCachedRoutesChange.call(database) }\n\t});\n\tconst reads = createCoreReads(engine.core, storage);\n\tconst api = {};\n\tconst endpoints = [];\n\tlet clientAuth;\n\tfor (const plugin of plugins) {\n\t\tconst instance = checkInstance(plugin, plugin.init({\n\t\t\tdb: engine.database(plugin),\n\t\t\tcore: reads,\n\t\t\tnow\n\t\t}));\n\t\tif (instance.clientAuth !== void 0) {\n\t\t\tif (clientAuth !== void 0) fail(`Plugins \"${clientAuth.plugin}\" and \"${plugin.id}\" both provide clientAuth; keep one.`);\n\t\t\tconst provided = instance.clientAuth;\n\t\t\tclientAuth = {\n\t\t\t\tplugin: plugin.id,\n\t\t\t\tvaryHeaders: provided.varyHeaders,\n\t\t\t\tauthenticate: (headers) => provided.authenticate(headers)\n\t\t\t};\n\t\t}\n\t\tendpoints.push(...instance.endpoints);\n\t\tapi[plugin.id] = instance.api;\n\t}\n\treturn {\n\t\tcore,\n\t\tapi,\n\t\tendpoints,\n\t\t...clientAuth === void 0 ? {} : { clientAuth },\n\t\tflush: engine.flush\n\t};\n};\n//#endregion\nexport { HotUpdaterConfigError, assemblePlugins };\n", "//#region src/handlerErrors.ts\nvar HandlerBadRequestError = class extends Error {\n\tname = \"HandlerBadRequestError\";\n\tconstructor(message) {\n\t\tsuper(message);\n\t}\n};\n//#endregion\nexport { HandlerBadRequestError };\n", "import { HandlerBadRequestError } from \"./handlerErrors.mjs\";\n//#region src/handlerParameters.ts\nconst decodeMaybe = (value) => {\n\tif (value === void 0) return void 0;\n\ttry {\n\t\treturn decodeURIComponent(value);\n\t} catch {\n\t\treturn value;\n\t}\n};\nconst isPlatform = (value) => value === \"ios\" || value === \"android\";\nconst requireRouteParam = (params, key) => {\n\tconst value = params[key];\n\tif (!value) throw new HandlerBadRequestError(`Missing route parameter: ${key}`);\n\treturn value;\n};\nconst requirePlatformParam = (params) => {\n\tconst platform = requireRouteParam(params, \"platform\");\n\tif (!isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);\n\treturn platform;\n};\nconst parseBooleanSearchParam = (url, key) => {\n\tconst value = url.searchParams.get(key);\n\tif (value === null) return void 0;\n\tif (value === \"true\") return true;\n\tif (value === \"false\") return false;\n\tthrow new HandlerBadRequestError(`The '${key}' query parameter must be 'true' or 'false'.`);\n};\n//#endregion\nexport { decodeMaybe, isPlatform, parseBooleanSearchParam, requirePlatformParam, requireRouteParam };\n", "import { HandlerBadRequestError } from \"./handlerErrors.mjs\";\nimport { decodeMaybe, isPlatform, parseBooleanSearchParam, requireRouteParam } from \"./handlerParameters.mjs\";\nimport { DatabaseBundleNotFoundError, DatabaseRowReferencedError, ReleaseCatalogMutationError, ReleaseManagementError } from \"@hot-updater/plugin-core\";\n//#region src/handlerAdminRoutes.ts\nconst json = (body, status = 200) => Response.json(body, { status });\nconst notFound = () => json({ error: \"Not found\" }, 404);\nconst noContent = () => new Response(null, { status: 204 });\n/** Runs `route` on core, answering its refusals. */\nconst onCore = (route) => async (params, request, api) => answer(() => route(api.core, request, params));\n/** Core's refusals as HTTP answers; anything else is a server error. */\nconst answer = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof ReleaseManagementError || error instanceof ReleaseCatalogMutationError) {\n\t\t\tconst status = error.code === \"RELEASE_NOT_FOUND\" ? 404 : error.code === \"VERSION_CONFLICT\" ? 409 : 400;\n\t\t\treturn json({\n\t\t\t\tcode: error.code,\n\t\t\t\terror: error.message\n\t\t\t}, status);\n\t\t}\n\t\tif (error instanceof DatabaseBundleNotFoundError) return json({\n\t\t\tcode: \"BUNDLE_NOT_FOUND\",\n\t\t\terror: error.message\n\t\t}, 404);\n\t\tif (error instanceof DatabaseRowReferencedError) return json({\n\t\t\tcode: \"REFERENCED\",\n\t\t\terror: error.message\n\t\t}, 409);\n\t\tthrow error;\n\t}\n};\nconst LIMITS = {\n\tdefaultValue: 50,\n\tmaxValue: 500\n};\n/** `order`, `cursor`, and `limit`: one keyset page. */\nconst keyset = (url, maxValue = LIMITS.maxValue) => {\n\tconst order = url.searchParams.get(\"order\") ?? \"desc\";\n\tif (order !== \"asc\" && order !== \"desc\") throw new HandlerBadRequestError(\"order must be 'asc' or 'desc'.\");\n\tconst limitParam = url.searchParams.get(\"limit\");\n\tconst limit = limitParam === null ? Math.min(LIMITS.defaultValue, maxValue) : Number(limitParam);\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxValue) throw new HandlerBadRequestError(`limit must be between 1 and ${maxValue}.`);\n\tconst cursor = url.searchParams.get(\"cursor\");\n\treturn {\n\t\torder,\n\t\tlimit,\n\t\t...cursor === null ? {} : { after: cursor }\n\t};\n};\n/** A page and the cursor of the next one, when the page is full. */\nconst page = (rows, { limit }, keyOf, extra = {}) => json({\n\tdata: rows,\n\t...rows.length === limit && rows.length > 0 ? { next: keyOf(rows.at(-1)) } : {},\n\t...extra\n});\nconst platformOf = (url) => {\n\tconst platform = url.searchParams.get(\"platform\");\n\tif (platform === null) return void 0;\n\tif (!isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);\n\treturn platform;\n};\n/** The one filter set a release list names; any other mix of filters is refused. */\nconst releaseFilter = (url) => {\n\tconst params = url.searchParams;\n\tconst named = [\n\t\t\"channelId\",\n\t\t\"platform\",\n\t\t\"bundleId\",\n\t\t\"scopeKey\"\n\t].filter((name) => params.has(name));\n\tconst enabled = parseBooleanSearchParam(url, \"enabled\");\n\tconst withEnabled = enabled === void 0 ? {} : { enabled };\n\tconst set = named.join(\",\");\n\tif (set === \"\" && enabled === void 0) return { kind: \"all\" };\n\tif (set === \"channelId,platform\") {\n\t\tconst platform = platformOf(url);\n\t\treturn {\n\t\t\tkind: \"channelPlatform\",\n\t\t\tchannelId: params.get(\"channelId\"),\n\t\t\tplatform,\n\t\t\t...withEnabled\n\t\t};\n\t}\n\tif (set === \"bundleId\" && enabled === void 0) return {\n\t\tkind: \"bundle\",\n\t\tbundleId: params.get(\"bundleId\")\n\t};\n\tif (set === \"scopeKey\") return {\n\t\tkind: \"scope\",\n\t\tscopeKey: params.get(\"scopeKey\"),\n\t\t...withEnabled\n\t};\n\tthrow new HandlerBadRequestError(\"Releases filter by none, channelId and platform (with enabled), bundleId, or scopeKey (with enabled).\");\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst body = async (request) => {\n\tconst value = await request.json();\n\tif (!isRecord(value)) throw new HandlerBadRequestError(\"Invalid body\");\n\treturn value;\n};\nconst isText = (value) => typeof value === \"string\" && value.length > 0;\nconst isTextOrNull = (value) => value === null || isText(value);\nconst isBundle = (bundle) => isRecord(bundle) && isText(bundle.id) && typeof bundle.platform === \"string\" && isPlatform(bundle.platform) && isTextOrNull(bundle.gitCommitHash) && isText(bundle.manifestStorageUri) && isText(bundle.manifestFileHash) && isText(bundle.assetBaseStorageUri) && (bundle.metadata === void 0 || isRecord(bundle.metadata)) && (bundle.patches === void 0 || bundle.patches === null || Array.isArray(bundle.patches));\nconst isReleasePolicy = (release) => isRecord(release) && isText(release.channel) && typeof release.enabled === \"boolean\" && typeof release.shouldForceUpdate === \"boolean\" && isTextOrNull(release.fingerprintHash) && isTextOrNull(release.targetAppVersion) && (release.message === null || typeof release.message === \"string\") && (release.rolloutCohortCount === void 0 || Number.isSafeInteger(release.rolloutCohortCount) && release.rolloutCohortCount >= 0 && release.rolloutCohortCount <= 1e3) && (release.targetCohorts === void 0 || Array.isArray(release.targetCohorts) && release.targetCohorts.every(isText));\n/** A deployment's shape: a new bundle or a stored bundle's id, and its release policy. */\nconst isDeployment = (value) => isRecord(value) && isReleasePolicy(value.release) && (\"bundleId\" in value ? isText(value.bundleId) && !(\"bundle\" in value) : isBundle(value.bundle));\n/** An expected release revision from a body number or a query string. */\nconst revisionOf = (value) => {\n\tif (value === void 0 || value === null || value === \"\") return void 0;\n\tconst revision = typeof value === \"string\" ? Number(value) : value;\n\tif (typeof revision !== \"number\" || !Number.isSafeInteger(revision) || revision < 1) throw new HandlerBadRequestError(\"Invalid expected Release revision\");\n\treturn revision;\n};\n/** A policy change's body: `{ expectedRevision?, patch }`. */\nconst policyInput = async (request) => {\n\tconst input = await body(request);\n\tif (!isRecord(input.patch)) throw new HandlerBadRequestError(\"Invalid Release policy mutation\");\n\tconst expectedRevision = revisionOf(input.expectedRevision);\n\treturn {\n\t\tpatch: input.patch,\n\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t};\n};\n/** A bundle update's body: the fields it changes, never another bundle's id. */\nconst bundleUpdateOf = (value, bundleId) => {\n\tif (!isRecord(value)) throw new HandlerBadRequestError(\"Invalid bundle payload\");\n\tconst { id, ...update } = value;\n\tif (id !== void 0 && id !== bundleId) throw new HandlerBadRequestError(\"Bundle id mismatch\");\n\treturn update;\n};\nconst scopeKeyOf = (params) => decodeMaybe(requireRouteParam(params, \"scopeKey\")) ?? \"\";\n/** Every admin route's handler, by the name `ADMIN_ROUTES` mounts it under. */\nconst createAdminRouteHandlers = () => ({\n\tlistBundles: onCore(async (core, request) => {\n\t\tconst url = new URL(request.url);\n\t\tconst input = keyset(url, 100);\n\t\tconst platform = platformOf(url);\n\t\tconst withTotal = parseBooleanSearchParam(url, \"total\") === true;\n\t\tconst [rows, total] = await Promise.all([core.listBundles({\n\t\t\t...input,\n\t\t\t...platform ? { platform } : {}\n\t\t}), withTotal ? core.countBundles(platform) : void 0]);\n\t\treturn page(rows, input, (row) => row.bundle.id, total === void 0 ? {} : { total });\n\t}),\n\tgetBundle: onCore(async (core, _request, params) => {\n\t\tconst detail = await core.getBundle(requireRouteParam(params, \"id\"));\n\t\treturn detail === null ? notFound() : json({ data: detail });\n\t}),\n\tlistReleases: onCore(async (core, request) => {\n\t\tconst url = new URL(request.url);\n\t\tconst input = keyset(url);\n\t\tconst rows = await core.listReleases({\n\t\t\t...input,\n\t\t\tfilter: releaseFilter(url)\n\t\t});\n\t\treturn page(rows, input, (row) => row.id);\n\t}),\n\tlistReleaseCatalogs: onCore(async (core, request) => {\n\t\tconst input = keyset(new URL(request.url));\n\t\tconst rows = await core.listReleaseCatalogs(input);\n\t\treturn page(rows, input, (row) => row.scope_key);\n\t}),\n\t/** With `name`, the one channel of that name: 1 read. */\n\tgetChannels: onCore(async (core, request) => {\n\t\tconst name = new URL(request.url).searchParams.get(\"name\");\n\t\tif (name === null) return json({ data: await core.listChannels() });\n\t\tconst channel = await core.findChannelByName(name);\n\t\treturn channel === null ? notFound() : json({ data: channel });\n\t}),\n\t/** The channel named in the body, created when missing. */\n\tcreateChannel: onCore(async (core, request) => {\n\t\tconst { name } = await body(request);\n\t\tif (typeof name !== \"string\" || name.trim().length === 0) throw new HandlerBadRequestError(\"Invalid channel name\");\n\t\treturn json({ data: await core.ensureChannel(name) });\n\t}),\n\t/** 204 when deleted; 404 or 409 with the reason otherwise. */\n\tdeleteChannel: onCore(async (core, _request, params) => {\n\t\tconst result = await core.deleteChannel(decodeMaybe(requireRouteParam(params, \"id\")) ?? \"\");\n\t\tif (result.deleted) return noContent();\n\t\treturn json({ data: result }, result.reason === \"not_found\" ? 404 : 409);\n\t}),\n\tgetRelease: onCore(async (core, _request, params) => {\n\t\tconst row = await core.getRelease(requireRouteParam(params, \"id\"));\n\t\treturn row === null ? notFound() : json({ data: row });\n\t}),\n\tupdateRelease: onCore(async (core, request, params) => json({ data: await core.updateReleasePolicy({\n\t\t...await policyInput(request),\n\t\treleaseId: requireRouteParam(params, \"id\")\n\t}) })),\n\tpreflightRelease: onCore(async (core, request, params) => json({ data: await core.preflightReleasePolicy({\n\t\t...await policyInput(request),\n\t\treleaseId: requireRouteParam(params, \"id\")\n\t}) })),\n\t/** Hard deletion names the release twice: in the path and as `confirm`. */\n\tdeleteRelease: onCore(async (core, request, params) => {\n\t\tconst releaseId = requireRouteParam(params, \"id\");\n\t\tconst url = new URL(request.url);\n\t\tif (url.searchParams.get(\"confirm\") !== releaseId) throw new HandlerBadRequestError(\"Release hard deletion requires confirm=<release-id>\");\n\t\tconst expectedRevision = revisionOf(url.searchParams.get(\"expectedRevision\"));\n\t\treturn json({ data: await core.deleteRelease({\n\t\t\treleaseId,\n\t\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t\t}) });\n\t}),\n\tgetReleaseCatalogRow: onCore(async (core, _request, params) => {\n\t\tconst row = await core.getReleaseCatalogRow(scopeKeyOf(params));\n\t\treturn row === null ? notFound() : json({ data: row });\n\t}),\n\trebuildReleaseCatalog: onCore(async (core, _request, params) => json({ data: await core.rebuildReleaseCatalog(scopeKeyOf(params)) })),\n\tupdateBundle: onCore(async (core, request, params) => {\n\t\tconst bundleId = requireRouteParam(params, \"id\");\n\t\tawait core.updateBundle(bundleId, bundleUpdateOf(await request.json(), bundleId));\n\t\treturn noContent();\n\t}),\n\tcountBundles: onCore(async (core, request) => json({ data: await core.countBundles(platformOf(new URL(request.url))) })),\n\tcountBundleChildren: onCore(async (core, request) => {\n\t\tconst ids = (new URL(request.url).searchParams.get(\"ids\") ?? \"\").split(\",\").filter((id) => id.length > 0);\n\t\tif (ids.length === 0 || ids.length > 100) throw new HandlerBadRequestError(\"Bundle child counts take ids=<bundle id>,... with 1 to 100 ids.\");\n\t\treturn json({ data: await core.countBundleChildren(ids) });\n\t}),\n\tlistBundleChildren: onCore(async (core, request, params) => {\n\t\tconst input = keyset(new URL(request.url));\n\t\tconst rows = await core.listPatchesFromBase(requireRouteParam(params, \"id\"), input);\n\t\treturn page(rows, input, (row) => row.bundle_id);\n\t}),\n\tfindBaseCandidates: onCore(async (core, request, params) => {\n\t\tconst url = new URL(request.url);\n\t\tconst before = url.searchParams.get(\"before\");\n\t\tconst limit = Number(url.searchParams.get(\"limit\") ?? \"3\");\n\t\tif (before === null || !Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new HandlerBadRequestError(\"Base candidates need before=<bundle id> and a limit between 1 and 100.\");\n\t\treturn json({ data: await core.findBaseBundleIds(decodeMaybe(requireRouteParam(params, \"candidateKey\")) ?? \"\", before, limit) });\n\t}),\n\tdeployReleases: onCore(async (core, request) => {\n\t\tconst { deployments } = await body(request);\n\t\tif (!Array.isArray(deployments) || deployments.length === 0 || !deployments.every(isDeployment)) throw new HandlerBadRequestError(\"Deploy needs deployments, each a bundle and its release policy.\");\n\t\treturn json({ data: await core.deploy(deployments) }, 201);\n\t}),\n\tpromoteRelease: onCore(async (core, request, params) => {\n\t\tconst input = await body(request);\n\t\tif (typeof input.targetChannel !== \"string\" || input.action !== void 0 && input.action !== \"copy\" && input.action !== \"move\") throw new HandlerBadRequestError(\"Invalid Release promotion\");\n\t\tconst expectedRevision = revisionOf(input.expectedRevision);\n\t\treturn json({ data: await core.promoteRelease({\n\t\t\treleaseId: requireRouteParam(params, \"id\"),\n\t\t\ttargetChannel: input.targetChannel,\n\t\t\t...input.action === void 0 ? {} : { action: input.action },\n\t\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t\t}) });\n\t}),\n\tpreflightReleaseCatalogRebuild: onCore(async (core, _request, params) => json({ data: await core.preflightReleaseCatalogRebuild(scopeKeyOf(params)) })),\n\tdeleteBundles: onCore(async (core, request) => {\n\t\tconst { ids } = await body(request);\n\t\tif (!Array.isArray(ids) || !ids.every((id) => typeof id === \"string\" && id.length > 0)) throw new HandlerBadRequestError(\"Bundle deletion needs ids\");\n\t\tawait core.deleteBundles(ids);\n\t\treturn noContent();\n\t})\n});\n/** The admin mount's routes, by the handler that serves each. */\nconst ADMIN_ROUTES = [\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases\",\n\t\thandler: \"deployReleases\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases/:id/promote\",\n\t\thandler: \"promoteRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"getRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/releases\",\n\t\thandler: \"listReleases\"\n\t},\n\t{\n\t\tmethod: \"PATCH\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"updateRelease\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases/:id/preflight\",\n\t\thandler: \"preflightRelease\"\n\t},\n\t{\n\t\tmethod: \"DELETE\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"deleteRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/release-catalogs/:scopeKey\",\n\t\thandler: \"getReleaseCatalogRow\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/release-catalogs\",\n\t\thandler: \"listReleaseCatalogs\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/release-catalogs/:scopeKey/rebuild\",\n\t\thandler: \"rebuildReleaseCatalog\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/release-catalogs/:scopeKey/preflight\",\n\t\thandler: \"preflightReleaseCatalogRebuild\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/channels\",\n\t\thandler: \"getChannels\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/channels\",\n\t\thandler: \"createChannel\"\n\t},\n\t{\n\t\tmethod: \"DELETE\",\n\t\tpath: \"/channels/:id\",\n\t\thandler: \"deleteChannel\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/count\",\n\t\thandler: \"countBundles\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/child-counts\",\n\t\thandler: \"countBundleChildren\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/:id\",\n\t\thandler: \"getBundle\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles\",\n\t\thandler: \"listBundles\"\n\t},\n\t{\n\t\tmethod: \"PATCH\",\n\t\tpath: \"/bundles/:id\",\n\t\thandler: \"updateBundle\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/bundles/delete\",\n\t\thandler: \"deleteBundles\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/:id/children\",\n\t\thandler: \"listBundleChildren\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/base-candidates/:candidateKey\",\n\t\thandler: \"findBaseCandidates\"\n\t}\n];\n//#endregion\nexport { ADMIN_ROUTES, answer, createAdminRouteHandlers };\n", "import { requirePlatformParam, requireRouteParam } from \"./handlerParameters.mjs\";\nimport { canonicalizeAppVersion } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/handlerReleaseCatalogRoutes.ts\nconst CATALOG_CONTENT_TYPE = \"application/vnd.hot-updater.release-catalog+json; version=1\";\nconst ARTIFACT_CONTENT_TYPE = \"application/vnd.hot-updater.artifact+json; version=1\";\nconst ORIGIN_CACHE_TTL_MS = 5e3;\nconst ORIGIN_CACHE_MAX_ENTRIES = 128;\n/** Marks the 404 of a scope that has no catalog. */\nconst NO_CATALOG_HEADER = \"x-hot-updater-catalog\";\n/** A shared cache keeps a catalog, or a scope's lack of one, five seconds. */\nconst CATALOG_CACHE_CONTROL = \"public, max-age=0, s-maxage=5\";\n/**\n* The same five seconds for a CDN that reads `CDN-Cache-Control` (RFC 9213),\n* such as Cloudflare's Workers Cache, which then ignores `Cache-Control`.\n* `s-maxage` forbids serving stale, so there an expired catalog held requests\n* at that location until the origin answered. Here, for five more seconds,\n* the CDN answers with the expired copy while it revalidates in the\n* background. `stale-if-error=0` keeps origin errors visible: without it,\n* Cloudflare serves a stale copy on error indefinitely.\n*\n* A device can see a catalog up to 15 seconds after a deploy or a Roll back\n* replaced it: the origin's 5-second catalog memo, then 5 seconds fresh and\n* 5 stale at the CDN. A revoked API key can read a cached catalog up to\n* 10 seconds. Devices and caches that don't read the header keep\n* `Cache-Control`.\n*/\nconst CATALOG_CDN_CACHE_CONTROL = \"public, max-age=5, stale-while-revalidate=5, stale-if-error=0\";\nconst privateNotFound = () => Response.json({ error: \"Not found\" }, {\n\tstatus: 404,\n\theaders: { \"cache-control\": \"private, no-store\" }\n});\nconst badRequest = (error) => Response.json({ error }, {\n\tstatus: 400,\n\theaders: { \"cache-control\": \"private, no-store\" }\n});\n/**\n* A 400 for a catalog path whose scope is malformed, such as a channel name\n* where its base64url key belongs; null for a well-formed scope.\n*/\nconst invalidScope = (input) => {\n\ttry {\n\t\tcreateReleaseCatalogScopeKey(input);\n\t\treturn null;\n\t} catch (error) {\n\t\treturn badRequest(error instanceof Error ? error.message : \"Invalid Release Catalog scope\");\n\t}\n};\n/**\n* A scope with no catalog yet, such as a store version before its first\n* OTA release: cached like a catalog, so its update checks don't all reach\n* the origin, and it holds nothing an API key protects. The header tells it\n* apart from a 404 for a wrong URL: clients read it as \"no update\", and\n* doctor as a live catalog route.\n*/\nconst missingCatalog = () => Response.json({ error: \"Not found\" }, {\n\tstatus: 404,\n\theaders: {\n\t\t\"cache-control\": CATALOG_CACHE_CONTROL,\n\t\t\"cdn-cache-control\": CATALOG_CDN_CACHE_CONTROL,\n\t\tvary: \"Accept-Encoding\",\n\t\t[NO_CATALOG_HEADER]: \"none\"\n\t}\n});\nconst responseHash = async (body) => {\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(body));\n\treturn [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n};\nconst catalogResponse = async (catalog, request) => {\n\tif (catalog === null) return missingCatalog();\n\tconst body = JSON.stringify(catalog);\n\tconst etag = `\"sha256:${await responseHash(body)}\"`;\n\tconst headers = {\n\t\t\"cache-control\": CATALOG_CACHE_CONTROL,\n\t\t\"cdn-cache-control\": CATALOG_CDN_CACHE_CONTROL,\n\t\t\"content-type\": CATALOG_CONTENT_TYPE,\n\t\tetag,\n\t\tvary: \"Accept-Encoding\"\n\t};\n\tif (request.headers.get(\"if-none-match\") === etag) return new Response(null, {\n\t\theaders,\n\t\tstatus: 304\n\t});\n\treturn new Response(body, {\n\t\theaders,\n\t\tstatus: 200\n\t});\n};\nconst createReleaseCatalogRouteHandlers = () => {\n\tconst cache = /* @__PURE__ */ new Map();\n\tconst inFlight = /* @__PURE__ */ new Map();\n\tconst loadCatalog = async (key, load) => {\n\t\tconst cached = cache.get(key);\n\t\tif (cached !== void 0 && cached.expiresAt > Date.now()) {\n\t\t\tcache.delete(key);\n\t\t\tcache.set(key, cached);\n\t\t\treturn cached.catalog;\n\t\t}\n\t\tif (cached !== void 0) cache.delete(key);\n\t\tconst pending = inFlight.get(key);\n\t\tif (pending !== void 0) return pending;\n\t\tconst next = load().then((catalog) => {\n\t\t\tif (catalog !== null) {\n\t\t\t\tcache.set(key, {\n\t\t\t\t\tcatalog,\n\t\t\t\t\texpiresAt: Date.now() + ORIGIN_CACHE_TTL_MS\n\t\t\t\t});\n\t\t\t\twhile (cache.size > ORIGIN_CACHE_MAX_ENTRIES) {\n\t\t\t\t\tconst oldestKey = cache.keys().next().value;\n\t\t\t\t\tif (oldestKey === void 0) break;\n\t\t\t\t\tcache.delete(oldestKey);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\t\tinFlight.set(key, next);\n\t\ttry {\n\t\t\treturn await next;\n\t\t} finally {\n\t\t\tinFlight.delete(key);\n\t\t}\n\t};\n\treturn {\n\t\tappVersionReleaseCatalog: async (params, request, { core }) => {\n\t\t\tconst rawAppVersion = requireRouteParam(params, \"appVersion\");\n\t\t\tconst appVersion = canonicalizeAppVersion(rawAppVersion);\n\t\t\tif (appVersion === null || appVersion !== rawAppVersion) return badRequest(\"Invalid app version\");\n\t\t\tconst input = {\n\t\t\t\tappVersion,\n\t\t\t\tchannelKey: requireRouteParam(params, \"channelKey\"),\n\t\t\t\tplatform: requirePlatformParam(params),\n\t\t\t\tstrategy: \"APP_VERSION\"\n\t\t\t};\n\t\t\tconst invalid = invalidScope(input);\n\t\t\tif (invalid) return invalid;\n\t\t\treturn catalogResponse(await loadCatalog(`app-version:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);\n\t\t},\n\t\tfingerprintReleaseCatalog: async (params, request, { core }) => {\n\t\t\tconst input = {\n\t\t\t\tchannelKey: requireRouteParam(params, \"channelKey\"),\n\t\t\t\tfingerprintHash: requireRouteParam(params, \"fingerprintHash\"),\n\t\t\t\tplatform: requirePlatformParam(params),\n\t\t\t\tstrategy: \"FINGERPRINT\"\n\t\t\t};\n\t\t\tconst invalid = invalidScope(input);\n\t\t\tif (invalid) return invalid;\n\t\t\treturn catalogResponse(await loadCatalog(`fingerprint:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);\n\t\t},\n\t\tartifactV1: async (params, _request, { core }) => {\n\t\t\tconst info = await core.getArtifactInfo(requireRouteParam(params, \"targetBundleId\"), requireRouteParam(params, \"currentBundleId\"), 1);\n\t\t\tif (info === null) return privateNotFound();\n\t\t\treturn new Response(JSON.stringify(info), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: {\n\t\t\t\t\t\"cache-control\": \"private, no-store\",\n\t\t\t\t\t\"content-type\": ARTIFACT_CONTENT_TYPE\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n//#endregion\nexport { createReleaseCatalogRouteHandlers };\n", "//#region src/internalRouter.ts\nconst normalizePath = (path) => {\n\tif (!path) return \"/\";\n\tif (path === \"/\") return path;\n\tconst withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\treturn withLeadingSlash.endsWith(\"/\") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;\n};\nconst toSegments = (path) => {\n\tconst normalized = normalizePath(path);\n\treturn normalized === \"/\" ? [] : normalized.slice(1).split(\"/\");\n};\nfunction createRouter() {\n\treturn { routes: [] };\n}\nfunction addRoute(router, method, path, data) {\n\tconst segments = toSegments(path);\n\tconst paramNames = segments.filter((segment) => segment.startsWith(\":\")).map((segment) => segment.slice(1));\n\trouter.routes.push({\n\t\tdata,\n\t\tmethod: method.toUpperCase(),\n\t\tparamNames,\n\t\tsegments\n\t});\n}\nfunction findRoute(router, method, path) {\n\tconst normalizedMethod = method.toUpperCase();\n\tconst pathSegments = toSegments(path);\n\tfor (const route of router.routes) {\n\t\tif (route.method !== normalizedMethod) continue;\n\t\tif (route.segments.length !== pathSegments.length) continue;\n\t\tconst params = {};\n\t\tlet matched = true;\n\t\tfor (let index = 0; index < route.segments.length; index += 1) {\n\t\t\tconst routeSegment = route.segments[index];\n\t\t\tconst pathSegment = pathSegments[index];\n\t\t\tif (routeSegment.startsWith(\":\")) {\n\t\t\t\tparams[routeSegment.slice(1)] = pathSegment;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (routeSegment !== pathSegment) {\n\t\t\t\tmatched = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (matched) return {\n\t\t\tdata: route.data,\n\t\t\tparams\n\t\t};\n\t}\n}\n//#endregion\nexport { addRoute, createRouter, findRoute };\n", "import { HotUpdaterConfigError } from \"./assembly/configError.mjs\";\nimport { HandlerBadRequestError } from \"./handlerErrors.mjs\";\nimport { ADMIN_ROUTES, createAdminRouteHandlers } from \"./handlerAdminRoutes.mjs\";\nimport { createReleaseCatalogRouteHandlers } from \"./handlerReleaseCatalogRoutes.mjs\";\nimport { createVersionRouteHandlers } from \"./handlerVersionRoutes.mjs\";\nimport { addRoute, createRouter, findRoute } from \"./internalRouter.mjs\";\nimport { HotUpdaterSchemaMigrationRequiredError } from \"@hot-updater/plugin-core\";\n//#region src/handler.ts\nconst withPrivateNoStore = (response) => {\n\tconst headers = new Headers(response.headers);\n\theaders.set(\"cache-control\", \"private, no-store\");\n\treturn new Response(response.body, {\n\t\theaders,\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText\n\t});\n};\nconst errorResponse = (error, status) => Response.json({ error }, {\n\theaders: { \"cache-control\": \"private, no-store\" },\n\tstatus\n});\n/** `/version` never passes through the client policy. */\nconst PUBLIC_CLIENT_ROUTES = /* @__PURE__ */ new Set([\"version\"]);\nconst routesOf = Symbol.for(\"@hot-updater/server/routes\");\nconst withVary = (response, varyHeaders) => {\n\tconst cacheControl = response.headers.get(\"cache-control\") ?? \"\";\n\tif (varyHeaders.length === 0 || cacheControl === \"\" || /private|no-store/u.test(cacheControl)) return response;\n\tconst headers = new Headers(response.headers);\n\theaders.set(\"vary\", [response.headers.get(\"vary\"), ...varyHeaders].filter(Boolean).join(\", \"));\n\treturn new Response(response.body, {\n\t\theaders,\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText\n\t});\n};\nconst createRequestHandler = ({ api, clientPolicy, privateResponses = false, routeHandlers, router }) => async (request) => {\n\ttry {\n\t\tconst match = findRoute(router, request.method, new URL(request.url).pathname);\n\t\tif (!match) return errorResponse(\"Not found\", 404);\n\t\tconst guarded = clientPolicy !== void 0 && !PUBLIC_CLIENT_ROUTES.has(match.data);\n\t\tif (guarded) {\n\t\t\tlet authenticated;\n\t\t\ttry {\n\t\t\t\tauthenticated = await clientPolicy.authenticate(request);\n\t\t\t} catch {\n\t\t\t\treturn errorResponse(\"Service unavailable\", 503);\n\t\t\t}\n\t\t\tif (!authenticated) return errorResponse(\"Unauthorized\", 401);\n\t\t}\n\t\tconst handler = routeHandlers[match.data];\n\t\tif (!handler) return errorResponse(\"Handler not found\", 500);\n\t\tconst response = await handler(match.params, request, api);\n\t\tif (privateResponses) return withPrivateNoStore(response);\n\t\treturn guarded ? withVary(response, clientPolicy.varyHeaders) : response;\n\t} catch (error) {\n\t\tif (error instanceof HandlerBadRequestError) return errorResponse(error.message, 400);\n\t\tif (error instanceof HotUpdaterSchemaMigrationRequiredError) {\n\t\t\tconsole.error(error.message);\n\t\t\treturn errorResponse(\"Service unavailable\", 503);\n\t\t}\n\t\tconsole.error(\"Hot Updater handler error:\", error);\n\t\treturn Response.json({ error: \"Internal server error\" }, {\n\t\t\theaders: { \"cache-control\": \"private, no-store\" },\n\t\t\tstatus: 500\n\t\t});\n\t}\n};\nfunction createHotUpdaterHandlers({ api, clientPolicy, endpoints = [], plugins = [] }) {\n\tconst routeHandlers = {\n\t\t...createVersionRouteHandlers(plugins),\n\t\t...createReleaseCatalogRouteHandlers(),\n\t\t...createAdminRouteHandlers()\n\t};\n\tconst routes = [];\n\tconst shapes = /* @__PURE__ */ new Map();\n\tconst mount = (router, admin) => (method, path, handler) => {\n\t\tconst shape = `${admin ? \"admin\" : \"client\"} ${method} ${path.replaceAll(/:[^/]+/gu, \":\")}`;\n\t\tconst taken = shapes.get(shape);\n\t\tif (taken !== void 0) throw new HotUpdaterConfigError(`${handler} (${method} ${path}) collides with ${taken} on handlers.${admin ? \"admin\" : \"client\"}.`);\n\t\tshapes.set(shape, handler);\n\t\taddRoute(router, method, path, handler);\n\t\troutes.push({\n\t\t\tmethod,\n\t\t\tpath,\n\t\t\taccess: admin ? \"admin\" : PUBLIC_CLIENT_ROUTES.has(handler) ? \"public\" : \"client\"\n\t\t});\n\t};\n\tconst clientRouter = createRouter();\n\tconst addClientRoute = mount(clientRouter, false);\n\taddClientRoute(\"GET\", \"/version\", \"version\");\n\taddClientRoute(\"GET\", \"/release-catalogs/app-version/:platform/:channelKey/:appVersion\", \"appVersionReleaseCatalog\");\n\taddClientRoute(\"GET\", \"/release-catalogs/fingerprint/:platform/:channelKey/:fingerprintHash\", \"fingerprintReleaseCatalog\");\n\taddClientRoute(\"GET\", \"/artifacts/v1/:targetBundleId/from/:currentBundleId\", \"artifactV1\");\n\tconst adminRouter = createRouter();\n\tconst addAdminRoute = mount(adminRouter, true);\n\taddAdminRoute(\"GET\", \"/version\", \"adminVersion\");\n\tfor (const route of ADMIN_ROUTES) addAdminRoute(route.method, route.path, route.handler);\n\tfor (const endpoint of endpoints) {\n\t\tconst name = `plugin ${endpoint.plugin}: ${endpoint.method} ${endpoint.path}`;\n\t\trouteHandlers[name] = (params, request) => endpoint.handler(request, params);\n\t\t(endpoint.access === \"admin\" ? addAdminRoute : addClientRoute)(endpoint.method, endpoint.path, name);\n\t}\n\tconst handlers = {\n\t\tclient: createRequestHandler({\n\t\t\tapi,\n\t\t\t...clientPolicy === void 0 ? {} : { clientPolicy },\n\t\t\trouteHandlers,\n\t\t\trouter: clientRouter\n\t\t}),\n\t\tadmin: createRequestHandler({\n\t\t\tapi,\n\t\t\tprivateResponses: true,\n\t\t\trouteHandlers,\n\t\t\trouter: adminRouter\n\t\t})\n\t};\n\tObject.defineProperty(handlers, routesOf, { value: Object.freeze(routes) });\n\treturn Object.freeze(handlers);\n}\n//#endregion\nexport { createHotUpdaterHandlers };\n", "//#region src/storageAccess.ts\n/** A URL devices download from, which only an absolute HTTP(S) URL can be. */\nconst assertRemoteUrl = (value) => {\n\tlet protocol;\n\ttry {\n\t\tprotocol = new URL(value).protocol;\n\t} catch {}\n\tif (protocol !== \"http:\" && protocol !== \"https:\") throw new Error(\"Storage getDownloadUrl must resolve to an absolute HTTP(S) URL.\");\n\treturn value;\n};\nconst getStorageProtocol = (storageUri) => new URL(storageUri).protocol.replace(\":\", \"\");\nconst isRemoteUrlProtocol = (protocol) => protocol === \"http\" || protocol === \"https\";\n/**\n* Reads and download URLs over the server's storage, for the URIs of its\n* protocol; an HTTP(S) URI is used as it is.\n*/\nconst createStorageAccess = (storageAdapter) => {\n\tconst findStorage = (protocol) => storageAdapter.protocol === protocol ? storageAdapter : void 0;\n\tconst readStorageResponse = async (storageUri) => {\n\t\tconst protocol = getStorageProtocol(storageUri);\n\t\tconst storage = findStorage(protocol);\n\t\tif (storage) {\n\t\t\tif (!storage.get) return null;\n\t\t\treturn (await storage.get({ storageUri })).response;\n\t\t}\n\t\tif (isRemoteUrlProtocol(protocol)) {\n\t\t\tconst response = await fetch(storageUri);\n\t\t\treturn response.ok ? response : null;\n\t\t}\n\t\tthrow new Error(`No storage adapter for protocol: ${protocol}`);\n\t};\n\tconst resolveFileUrl = async (storageUri) => {\n\t\tif (!storageUri) return null;\n\t\tconst protocol = getStorageProtocol(storageUri);\n\t\tconst storage = findStorage(protocol);\n\t\tif (!storage) {\n\t\t\tif (isRemoteUrlProtocol(protocol)) return storageUri;\n\t\t\tthrow new Error(`No storage adapter for protocol: ${protocol}`);\n\t\t}\n\t\tif (!storage.getDownloadUrl) return null;\n\t\tconst { url: downloadUrl } = await storage.getDownloadUrl({ storageUri });\n\t\treturn assertRemoteUrl(downloadUrl);\n\t};\n\tconst readStorageText = async (storageUri) => {\n\t\treturn (await readStorageResponse(storageUri))?.text() ?? null;\n\t};\n\treturn {\n\t\treadStorageText,\n\t\tresolveFileUrl\n\t};\n};\n//#endregion\nexport { createStorageAccess };\n", "import { HotUpdaterConfigError } from \"./assembly/configError.mjs\";\nimport { clientPluginsOf } from \"./assembly/clientPlugins.mjs\";\nimport { assemblePlugins } from \"./assembly/assemblePlugins.mjs\";\nimport { createHotUpdaterHandlers } from \"./handler.mjs\";\nimport { createStorageAccess } from \"./storageAccess.mjs\";\nimport { assertStorageOperations } from \"@hot-updater/plugin-core\";\n//#region src/createHotUpdaterCore.ts\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\nconst isAdapter = (value) => isRecord(value) && [\n\t\"fits\",\n\t\"get\",\n\t\"query\",\n\t\"write\"\n].every((method) => typeof value[method] === \"function\");\n/** The configured database, when it runs on the storage engine. */\nconst databaseOf = (value) => {\n\tif (isRecord(value) && typeof value.name === \"string\") {\n\t\tif (isAdapter(value.adapter)) return value;\n\t\tif (\"core\" in value && \"fetchAdmin\" in value) throw new HotUpdaterConfigError(\"standaloneRepository reaches a server's admin API from the CLI and console. createHotUpdater needs the server's own database, such as kyselyAdapter(...).\");\n\t}\n\tthrow new HotUpdaterConfigError(\"database must be a Hot Updater database adapter, such as kyselyAdapter(...) or postgres(...).\");\n};\n/** The configured storage, when it is a storage adapter. */\nconst storageOf = (value) => {\n\tif (isRecord(value) && typeof value.name === \"string\" && typeof value.protocol === \"string\") return value;\n\tthrow new HotUpdaterConfigError(\"storage must be a storage adapter, such as s3Storage(...): the one hot-updater.config.ts uploads with.\");\n};\n/** `\"public\"`, or nothing. */\nconst isPublic = (value) => {\n\tif (value === void 0) return false;\n\tif (value === \"public\") return true;\n\tthrow new HotUpdaterConfigError(\"clientAccess must be \\\"public\\\"; to protect client routes, add a plugin that provides clientAuth to plugins.\");\n};\nfunction createHotUpdater(options) {\n\tconst database = databaseOf(options.database);\n\tconst storage = storageOf(options.storage);\n\tconst { readStorageText, resolveFileUrl } = createStorageAccess(storage);\n\tconst publicClients = isPublic(options.clientAccess);\n\tconst configured = Object.freeze([...options.plugins ?? []]);\n\tconst plugins = assemblePlugins(configured, database, { storage: {\n\t\treadStorageText,\n\t\tresolveFileUrl\n\t} });\n\tconst clientPlugins = Object.freeze(clientPluginsOf(configured));\n\tconst clientAuth = plugins.clientAuth;\n\tif (clientAuth !== void 0 && publicClients) throw new HotUpdaterConfigError(`Plugin \"${clientAuth.plugin}\" provides clientAuth, so remove clientAccess.`);\n\tif (clientAuth === void 0 && !publicClients) throw new HotUpdaterConfigError(\"Set clientAccess to \\\"public\\\", or add a plugin that provides clientAuth.\");\n\tconst varyHeaders = Object.freeze((clientAuth?.varyHeaders ?? []).map((header) => header.toLowerCase()));\n\tconst clientPolicy = clientAuth === void 0 ? void 0 : {\n\t\tvaryHeaders,\n\t\tauthenticate: (request) => clientAuth.authenticate(request.headers)\n\t};\n\tconst handlers = createHotUpdaterHandlers({\n\t\tapi: { core: plugins.core },\n\t\t...clientPolicy === void 0 ? {} : { clientPolicy },\n\t\tendpoints: plugins.endpoints,\n\t\tplugins: Object.keys(plugins.api)\n\t});\n\tlet serving = false;\n\treturn {\n\t\tadapterName: database.name,\n\t\tget handlers() {\n\t\t\tif (!serving) {\n\t\t\t\tassertStorageOperations(storage, [\"get\", \"getDownloadUrl\"]);\n\t\t\t\tserving = true;\n\t\t\t}\n\t\t\treturn handlers;\n\t\t},\n\t\tcore: plugins.core,\n\t\tapi: plugins.api,\n\t\tflush: plugins.flush,\n\t\tdatabase,\n\t\tstorage,\n\t\tplugins: configured,\n\t\tclientPlugins,\n\t\tclientEndpoints: Object.freeze(plugins.endpoints.filter((endpoint) => endpoint.access === \"client\").map(({ plugin, method, path }) => Object.freeze({\n\t\t\tplugin,\n\t\t\tmethod,\n\t\t\tpath\n\t\t}))),\n\t\t...clientAuth === void 0 ? {} : { clientAuth: Object.freeze({\n\t\t\tplugin: clientAuth.plugin,\n\t\t\tvaryHeaders\n\t\t}) }\n\t};\n}\n//#endregion\nexport { createHotUpdater };\n", "//#region src/server/apiKeys.ts\nconst API_KEY_HEADER_NAME = \"x-api-key\";\nconst BASE64URL_32_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst bytesToBase64Url = (bytes) => {\n\tlet binary = \"\";\n\tfor (const byte of bytes) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst isApiKey = (value) => {\n\tif (!BASE64URL_32_PATTERN.test(value)) return false;\n\ttry {\n\t\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\t\tconst binary = atob(`${base64}=`);\n\t\tconst bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));\n\t\treturn bytes.byteLength === 32 && bytesToBase64Url(bytes) === value;\n\t} catch {\n\t\treturn false;\n\t}\n};\nconst normalizeApiKeyHeaderName = (value = API_KEY_HEADER_NAME) => {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(\"apiKeys({ headerName }) must name a valid header.\");\n\ttry {\n\t\tconst headers = new Headers();\n\t\theaders.set(value, \"\");\n\t\treturn headers.keys().next().value;\n\t} catch {\n\t\tthrow new TypeError(\"apiKeys({ headerName }) must name a valid header.\");\n\t}\n};\nconst hashApiKey = async (apiKey) => {\n\tif (!isApiKey(apiKey)) throw new TypeError(\"API key must be a canonical 32-byte base64url value.\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(apiKey));\n\treturn bytesToBase64Url(new Uint8Array(digest));\n};\nconst apiKeyId = () => {\n\tconst bytes = /* @__PURE__ */ new Uint8Array(16);\n\tcrypto.getRandomValues(bytes);\n\treturn `api-${bytesToBase64Url(bytes)}`;\n};\nconst normalizeApiKeyName = (name) => {\n\tconst normalized = name.trim();\n\tif (normalized.length === 0 || normalized.length > 64 || /[\\p{Cc}\\p{Cf}]/u.test(normalized)) throw new TypeError(\"API key names must contain 1-64 visible characters.\");\n\treturn normalized;\n};\nconst toApiKeyMetadata = ({ hash: _hash, ...metadata }) => Object.freeze(metadata);\nconst registerApiKey = async (input) => {\n\tconst hash = await hashApiKey(input.apiKey);\n\tconst createdAtMs = input.createdAtMs ?? Date.now();\n\tif (!Number.isSafeInteger(createdAtMs) || createdAtMs < 0) throw new TypeError(\"API key creation time must be non-negative.\");\n\tconst record = Object.freeze({\n\t\tcreated_at_ms: createdAtMs,\n\t\thash,\n\t\tid: apiKeyId(),\n\t\tname: normalizeApiKeyName(input.name),\n\t\tprefix: input.apiKey.slice(0, 6),\n\t\trevoked_at_ms: null,\n\t\trole: \"client\"\n\t});\n\tif (await input.apiKeys.create(record) === \"existing\") {\n\t\tconst existing = await input.apiKeys.findByHash(hash);\n\t\tif (existing === null || existing.revoked_at_ms !== null) throw new Error(\"The API key has been revoked.\");\n\t\treturn Object.freeze({\n\t\t\tapiKey: input.apiKey,\n\t\t\trecord: toApiKeyMetadata(existing)\n\t\t});\n\t}\n\treturn Object.freeze({\n\t\tapiKey: input.apiKey,\n\t\trecord: toApiKeyMetadata(record)\n\t});\n};\nconst createApiKey = (input) => {\n\tconst bytes = /* @__PURE__ */ new Uint8Array(32);\n\tcrypto.getRandomValues(bytes);\n\treturn registerApiKey({\n\t\tapiKey: bytesToBase64Url(bytes),\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t});\n};\n/**\n* Provisions the client API key used by managed init.\n*\n* A saved plaintext key is registered idempotently; otherwise a new key is\n* created. Callers must persist or display the returned plaintext because the\n* database stores only its hash.\n*/\nconst provisionApiKey = (input) => {\n\tconst existingApiKey = input.existingApiKey?.trim();\n\treturn existingApiKey ? registerApiKey({\n\t\tapiKey: existingApiKey,\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t}) : createApiKey({\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t});\n};\nconst authenticateApiKey = async (input) => {\n\tconst apiKey = input.request.headers.get(normalizeApiKeyHeaderName(input.headerName));\n\tif (apiKey === null || !isApiKey(apiKey)) return false;\n\tconst hash = await hashApiKey(apiKey);\n\tconst record = await input.apiKeys.findByHash(hash);\n\treturn record !== null && record.hash === hash && record.role === \"client\" && record.revoked_at_ms === null;\n};\nconst createApiKeyManagement = (input) => Object.freeze({\n\tasync create({ name }) {\n\t\tconst created = await createApiKey({\n\t\t\tapiKeys: input.apiKeys,\n\t\t\tname\n\t\t});\n\t\treturn Object.freeze({\n\t\t\tapiKey: created.apiKey,\n\t\t\trecord: created.record\n\t\t});\n\t},\n\tasync list() {\n\t\treturn Object.freeze((await input.apiKeys.list()).map(toApiKeyMetadata));\n\t},\n\tasync revoke({ id }) {\n\t\tconst record = await input.apiKeys.revoke({\n\t\t\tid,\n\t\t\trevokedAtMs: Date.now()\n\t\t});\n\t\treturn record === null ? null : toApiKeyMetadata(record);\n\t}\n});\n//#endregion\nexport { API_KEY_HEADER_NAME, apiKeyId, authenticateApiKey, createApiKey, createApiKeyManagement, hashApiKey, isApiKey, normalizeApiKeyHeaderName, normalizeApiKeyName, provisionApiKey, registerApiKey };\n", "//#region src/server/cli.ts\n/** The environment variable init stores the app's API key in. */\nconst API_KEY_ENV = \"HOT_UPDATER_API_KEY\";\n/** A new API key: 32 random bytes, base64url, as the plugin creates them. */\nconst generateApiKey = () => {\n\tconst bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));\n\treturn btoa(String.fromCharCode(...bytes)).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\n/** The API key that init provisions for an app, sent in `headerName`. */\nconst apiKeysCli = (headerName) => ({ clientCredential: {\n\tlabel: \"API key\",\n\theader: headerName,\n\tenv: API_KEY_ENV,\n\tgenerate: generateApiKey,\n\tprovision: async (api, { existing, name }) => (await api.provision({\n\t\t...existing === void 0 ? {} : { existingApiKey: existing },\n\t\tname\n\t})).apiKey\n} });\n//#endregion\nexport { API_KEY_ENV, apiKeysCli };\n", "import { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/server/model.ts\nconst toRow = (row) => ({\n\tid: row.id,\n\thash: row.hash,\n\tname: row.name,\n\tprefix: row.prefix,\n\trole: row.role,\n\tcreated_at_ms: row.created_at_ms,\n\trevoked_at_ms: row.revoked_at_ms\n});\n/** Today's `ApiKeyModel` on the engine: one unique read by hash, keyed writes. */\nconst createApiKeyModel = (db) => ({\n\tasync create(row) {\n\t\ttry {\n\t\t\treturn await db.transaction(async (tx) => {\n\t\t\t\tif (await tx.findOne(\"api_keys\", { hash: row.hash }) !== null) return \"existing\";\n\t\t\t\ttx.create(\"api_keys\", row);\n\t\t\t\treturn \"created\";\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseConstraintError && error.reason === \"unique\") return \"existing\";\n\t\t\tthrow error;\n\t\t}\n\t},\n\tasync findByHash(hash) {\n\t\tconst row = await db.findOne(\"api_keys\", { hash });\n\t\treturn row === null ? null : toRow(row);\n\t},\n\t/** Every key, newest first, then by id; the whole list is the result. */\n\tasync list() {\n\t\tconst rows = [];\n\t\tlet cursor;\n\t\tdo {\n\t\t\tconst page = await db.findMany(\"api_keys\", {\n\t\t\t\tindex: \"byCreated\",\n\t\t\t\twhere: {},\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit: 500,\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\trows.push(...page.rows.map(toRow));\n\t\t\tcursor = page.next;\n\t\t} while (cursor !== void 0);\n\t\treturn rows.sort((left, right) => right.created_at_ms - left.created_at_ms || (left.id < right.id ? -1 : left.id > right.id ? 1 : 0));\n\t},\n\trevoke: ({ id, revokedAtMs }) => db.transaction(async (tx) => {\n\t\tconst row = await tx.findOne(\"api_keys\", { id });\n\t\tif (row === null) return null;\n\t\ttx.update(\"api_keys\", row, { revoked_at_ms: revokedAtMs });\n\t\treturn toRow({\n\t\t\t...row,\n\t\t\trevoked_at_ms: revokedAtMs\n\t\t});\n\t})\n});\n//#endregion\nexport { createApiKeyModel };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"apiKeys\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "import { defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\n/** v1's `api_keys` columns; the plaintext key is never stored, only its SHA-256 digest. */\nconst apiKeysSchema = { api_keys: defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\thash: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64,\n\t\tunique: true\n\t},\n\tname: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64\n\t},\n\tprefix: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\trole: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tcreated_at_ms: { type: \"integer\" },\n\trevoked_at_ms: {\n\t\ttype: \"integer\",\n\t\trequired: false\n\t}\n}, {\n\tkey: [\"id\"],\n\tindexes: { byCreated: {\n\t\teq: [],\n\t\tsort: [\"created_at_ms\"]\n\t} }\n}) };\n//#endregion\nexport { apiKeysSchema };\n", "import { API_KEY_HEADER_NAME, authenticateApiKey, createApiKeyManagement, normalizeApiKeyHeaderName, provisionApiKey, registerApiKey } from \"./apiKeys.mjs\";\nimport { apiKeysCli } from \"./cli.mjs\";\nimport { createApiKeyModel } from \"./model.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { apiKeysSchema } from \"./schema.mjs\";\nimport { definePlugin } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\n/**\n* API keys: protects client routes with keys whose SHA-256 digests\n* are stored, and manages them in-process.\n*/\nconst apiKeys = (options = {}) => {\n\tconst headerName = normalizeApiKeyHeaderName(options.headerName ?? \"x-api-key\");\n\tconst plugin = definePlugin({\n\t\tid: \"apiKeys\",\n\t\tnamespace: false,\n\t\tprovides: { clientAuth: true },\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: apiKeysSchema,\n\t\tinit: ({ db }) => {\n\t\t\tconst model = createApiKeyModel(db);\n\t\t\treturn {\n\t\t\t\tapi: {\n\t\t\t\t\t...createApiKeyManagement({ apiKeys: model }),\n\t\t\t\t\t/** Registers a known plaintext key idempotently, for managed init. */\n\t\t\t\t\tregister: (input) => registerApiKey({\n\t\t\t\t\t\t...input,\n\t\t\t\t\t\tapiKeys: model\n\t\t\t\t\t}),\n\t\t\t\t\t/** Reuses a saved key or creates one, for managed init. */\n\t\t\t\t\tprovision: (input) => provisionApiKey({\n\t\t\t\t\t\t...input,\n\t\t\t\t\t\tapiKeys: model\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\tclientAuth: {\n\t\t\t\t\tvaryHeaders: [headerName],\n\t\t\t\t\tauthenticate: (headers) => authenticateApiKey({\n\t\t\t\t\t\tapiKeys: model,\n\t\t\t\t\t\theaderName,\n\t\t\t\t\t\trequest: { headers }\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcli: apiKeysCli(headerName)\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { API_KEY_HEADER_NAME, apiKeys, apiKeysSchema, createApiKeyModel };\n", "import { defineAggregate, defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\nconst HOUR_MS = 36e5;\nconst DAY_MS = 864e5;\nconst DEFAULT_INSIGHTS_RETENTION = {\n\trawDays: 90,\n\tdailyDays: 400\n};\nconst bucketRetention = (days) => ({\n\tfield: \"bucket_start_ms\",\n\tdays\n});\n/** Every kind of row the table keeps belongs in installation history. */\nconst MOVEMENTS = /* @__PURE__ */ new Set([\n\t\"UPDATE_DOWNLOADED\",\n\t\"UPDATE_APPLIED\",\n\t\"RECOVERED\",\n\t\"UPDATE_FAILED\",\n\t\"UNCHANGED\"\n]);\n/** A failed update check: it names no target bundle, so no bundle list shows it. */\nconst isFailedCheck = (row) => row.type === \"UPDATE_FAILED\" && row.metadata?.failure?.stage === \"check\";\nconst metadataOf = (row) => row.metadata ?? {};\n/** A download or apply that arrived after its target ran: it counts nothing. */\nconst isLateEvent = (row) => metadataOf(row).late === true;\n/**\n* Whether a stored row launched its installation into a bundle release: an\n* apply, or a kept UNCHANGED row that moved the installation to another\n* bundle of a release, as when the apply report never arrived or a rollback\n* to the built-in bundle took it there. A first report, a release change of\n* the bundle already running, and a late row launch nothing.\n*/\nconst isLaunch = (row) => {\n\tif (isLateEvent(row)) return false;\n\tif (row.type === \"UPDATE_APPLIED\") return true;\n\tif (row.type !== \"UNCHANGED\") return false;\n\tconst kinds = metadataOf(row).change?.kinds ?? [];\n\treturn kinds.includes(\"bundle\") && !kinds.includes(\"first_seen\") && row.to_release_id !== null;\n};\n/**\n* The bundle a stored row's bundle filter matches: `from:<bundle>` for a\n* recovery; `to:<bundle>` for a download, an apply, and an update failure;\n* `on:<bundle>` for an UNCHANGED row that launched a bundle (`isLaunch`), a\n* key no other row uses. None for a failed check, which targets no bundle, a\n* late row, or any other UNCHANGED row.\n*/\nconst bundleRefsOf = (row) => {\n\tif (isFailedCheck(row) || isLateEvent(row)) return [];\n\tif (row.type === \"RECOVERED\") return [`from:${row.from_bundle_id}`];\n\tif (row.type === \"UNCHANGED\") return isLaunch(row) ? [`on:${row.to_bundle_id}`] : [];\n\treturn [`to:${row.to_bundle_id}`];\n};\n/** The key a bundle filter reads, as `bundleRefsOf` writes it. */\nconst bundleRefOfFilter = (filter) => filter.type === \"RECOVERED\" ? `from:${filter.fromBundleId}` : filter.type === \"UNCHANGED\" ? `on:${filter.toBundleId}` : `to:${filter.toBundleId}`;\n/**\n* Downloads, applies, recoveries, update failures, and the UNCHANGED\n* reports that changed what their installation runs, whole. An UNCHANGED\n* report that changes nothing counts as a launch and moves its\n* installation's head, but no row keeps it.\n*/\nconst bundleEvents = (days) => defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tinstall_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\tuser_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255,\n\t\trequired: false\n\t},\n\tfrom_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tfrom_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\tchannel: { type: \"string\" },\n\tmetadata: { type: \"json\" },\n\treceived_at_ms: { type: \"integer\" }\n}, {\n\tkey: [\"id\"],\n\tderived: {\n\t\t/** The UTC day the event was received in. */\n\t\tday: {\n\t\t\ttype: \"integer\",\n\t\t\tcompute: (row) => row.received_at_ms - row.received_at_ms % DAY_MS\n\t\t},\n\t\t/** Every stored event belongs in installation history. */\n\t\tmovement_install_id: {\n\t\t\ttype: \"string\",\n\t\t\tcompute: (row) => MOVEMENTS.has(row.type) ? row.install_id : null\n\t\t},\n\t\t/** The bundle a bundle filter matches (`bundleRefsOf`). */\n\t\tbundle_ref: {\n\t\t\ttype: \"string\",\n\t\t\tmulti: true,\n\t\t\tcompute: (row) => bundleRefsOf(row)\n\t\t}\n\t},\n\tindexes: {\n\t\tmovementsByInstall: {\n\t\t\teq: [\"movement_install_id\"],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t},\n\t\tbyBundle: {\n\t\t\teq: [\n\t\t\t\t\"platform\",\n\t\t\t\t\"channel\",\n\t\t\t\t\"type\",\n\t\t\t\t\"bundle_ref\",\n\t\t\t\t\"day\"\n\t\t\t],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t},\n\t\t/** Events of every scope by day, for the console's unfiltered event list. */\n\t\tbyDay: {\n\t\t\teq: [\"day\"],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t}\n\t},\n\tretention: {\n\t\tfield: \"day\",\n\t\tdays\n\t}\n});\n/**\n* Each installation's latest event, whole, so reading it is one point read.\n* Its gauges count it in the UTC day of that event. An update failure moves\n* nothing, so no head holds one.\n*/\nconst bundleEventHeads = (days) => defineTable({\n\tinstall_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tuser_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255,\n\t\trequired: false\n\t},\n\tfrom_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tfrom_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\tchannel: { type: \"string\" },\n\tmetadata: { type: \"json\" },\n\treceived_at_ms: { type: \"integer\" }\n}, {\n\tkey: [\"install_id\"],\n\tindexes: { byUser: {\n\t\teq: [\"user_id\"],\n\t\tsort: [\"install_id\"]\n\t} },\n\tretention: {\n\t\tfield: \"received_at_ms\",\n\t\tdays\n\t}\n});\n/**\n* Shards are keyed by install id. Counters are blind increments and never\n* conflict, so they keep 8. Gauges and sketches are read, merged, and written\n* back. B3's rollout gate on PostgreSQL retried 2.4% of transactions at 8\n* shards and 1.3% at 16. DynamoDB's transactions take longer, so D8's gate\n* on DynamoDB Local retried 2\u201324% at 16, almost all on gauge rows, and 1\u20135%\n* with gauges at 32. Sketches stay at 16: each shard row carries 2 KB of\n* registers that every read merges.\n*\n* Every Insights aggregate is `batched`: on DynamoDB and Firestore, which\n* bill each write, an event's changes apply after it commits, merged with\n* other events' into one write per row, on one shard per writer.\n*/\nconst COUNTER_SHARDS = 8;\nconst GAUGE_SHARDS = 32;\nconst SKETCH_SHARDS = 16;\n/** Rows keyed by a hashed identity (scope and period) and a bucket. */\nconst identityFields = {\n\tidentity: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n};\nconst window = {\n\teq: [\"identity\"],\n\tsort: [\"bucket_start_ms\"]\n};\n/** What a release or channel row counts in every period kind. */\nconst WINDOW_COUNTERS = [\n\t\"downloads\",\n\t\"failed_launches\",\n\t\"patch_downloads\",\n\t\"patch_fallbacks\"\n];\n/**\n* Hourly or daily counters: a release or channel row counts downloads,\n* launches that crashed and recovered (`failed_launches`), and downloads a\n* patch delivered and those that fell back from one.\n*/\nconst counters = (retention) => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tcounters: WINDOW_COUNTERS,\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { window },\n\tretention\n});\n/**\n* A release's counters since its first report, at bucket 0: the windowed\n* counters, its applies, which the bundle list reads, and its failed updates\n* (`failed_updates`), since no breakdown row outlives the raw period; windowed\n* reads sum `insights_failures` instead.\n*/\nconst lifetimeCounters = () => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tcounters: [\n\t\t...WINDOW_COUNTERS,\n\t\t\"applies\",\n\t\t\"failed_updates\"\n\t],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { window }\n});\n/**\n* Unique-installation sketches of one period kind: a usage row's active\n* installations (`activity_users`), and a `failure` or `check` row's\n* installations whose update or update check failed (`failed_users`).\n*/\nconst sketches = (retention) => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tdistinct: [\"activity_users\", \"failed_users\"],\n\tshards: SKETCH_SHARDS,\n\tbatched: true,\n\tindexes: { window },\n\tretention\n});\n/** Installations whose update to a release failed, since its first failure: kept, at bucket 0. */\nconst lifetimeSketches = () => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tdistinct: [\"failed_users\"],\n\tshards: SKETCH_SHARDS,\n\tbatched: true,\n\tindexes: { window }\n});\n/**\n* Update failures by what failed, a row an hour. `release_id` is the failed\n* update's target release, or empty for a failed check or an unknown target.\n* `stage` and `reason` say where and why it failed, and `detail` what else\n* the client knew, as the JSON array `[resource, httpStatus, originCode,\n* transport]`. Every index is in key order, so its counters stay blind\n* increments.\n*/\nconst insightsFailures = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\tbucket_start_ms: { type: \"integer\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tstage: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\treason: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64\n\t},\n\tdetail: {\n\t\ttype: \"string\",\n\t\tmaxLength: 160\n\t}\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"bucket_start_ms\",\n\t\t\"release_id\",\n\t\t\"stage\",\n\t\t\"reason\",\n\t\t\"detail\"\n\t],\n\tcounters: [\"events\"],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { byScope: {\n\t\teq: [\"platform\", \"channel\"],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/** Installations counted in the UTC day of their latest event, so reads sum whole UTC days. */\nconst insightsDistribution = (retention) => defineAggregate({\n\tchannel: { type: \"string\" },\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"channel\",\n\t\t\"platform\",\n\t\t\"app_version\",\n\t\t\"release_id\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"latest_installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: {\n\t\tbyScope: {\n\t\t\teq: [\"channel\", \"platform\"],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t},\n\t\tbyVersion: {\n\t\t\teq: [\n\t\t\t\t\"channel\",\n\t\t\t\t\"platform\",\n\t\t\t\t\"app_version\"\n\t\t\t],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t}\n\t},\n\tretention\n});\n/**\n* The installations of `insights_distribution` that run their native build's\n* built-in bundle, by its ID (`builtin_bundle_id`), within the same rows:\n* reads move them out of the row of their release, or of no release.\n*/\nconst insightsBuiltinDistribution = (retention) => defineAggregate({\n\tchannel: { type: \"string\" },\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbuiltin_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"channel\",\n\t\t\"platform\",\n\t\t\"app_version\",\n\t\t\"release_id\",\n\t\t\"builtin_bundle_id\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"latest_installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: {\n\t\tbyScope: {\n\t\t\teq: [\"channel\", \"platform\"],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t},\n\t\tbyVersion: {\n\t\t\teq: [\n\t\t\t\t\"channel\",\n\t\t\t\t\"platform\",\n\t\t\t\t\"app_version\"\n\t\t\t],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t}\n\t},\n\tretention\n});\n/** Latest events by the bundle they came from or went to, bucketed like the distribution. */\nconst insightsLatestByBundle = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\tbundle_field: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tbundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"bundle_field\",\n\t\t\"bundle_id\",\n\t\t\"type\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: { byBundle: {\n\t\teq: [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"bundle_field\",\n\t\t\t\"bundle_id\",\n\t\t\t\"type\"\n\t\t],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/**\n* Stored events by outcome and the bundle a bundle filter matches, a row an\n* hour, which a failed check has none of; and every stored event, a row a UTC\n* day (`DAILY_EVENTS`). Bundle counts sum the hourly rows, and event lists\n* read either to skip days without events.\n*/\nconst insightsOutcomes = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbundle_ref: {\n\t\ttype: \"string\",\n\t\tmaxLength: 41\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"type\",\n\t\t\"bundle_ref\",\n\t\t\"bucket_start_ms\"\n\t],\n\tcounters: [\"events\"],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { byRef: {\n\t\teq: [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"type\",\n\t\t\t\"bundle_ref\"\n\t\t],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/**\n* The `insights_outcomes` identity that counts every stored event, for the\n* global event list. Its bucket is a UTC day, not an hour. Every event's\n* platform is ios or android, so no outcome row of a bundle filter shares it.\n*/\nconst DAILY_EVENTS = {\n\tplatform: \"*\",\n\tchannel: \"\",\n\ttype: \"\",\n\tbundle_ref: \"\"\n};\n/**\n* Insights' tables, each expiring after its period. The periods are values\n* the engine applies at runtime; the tables and indexes are the same for\n* any periods.\n*/\nconst createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTION) => {\n\tconst hourly = bucketRetention(rawDays);\n\tconst daily = bucketRetention(dailyDays);\n\treturn {\n\t\tbundle_events: bundleEvents(rawDays),\n\t\tbundle_event_heads: bundleEventHeads(dailyDays),\n\t\t/** Hourly counters and sketches: the raw period. */\n\t\tinsights_overview: counters(hourly),\n\t\tinsights_sketches: sketches(hourly),\n\t\t/** Daily counters and sketches: the daily period. */\n\t\tinsights_overview_daily: counters(daily),\n\t\tinsights_sketches_daily: sketches(daily),\n\t\t/** A release's counters since its first event, and its failed installations: kept. */\n\t\tinsights_overview_lifetime: lifetimeCounters(),\n\t\tinsights_sketches_lifetime: lifetimeSketches(),\n\t\tinsights_distribution: insightsDistribution(daily),\n\t\tinsights_builtin_distribution: insightsBuiltinDistribution(daily),\n\t\tinsights_latest_by_bundle: insightsLatestByBundle(daily),\n\t\tinsights_outcomes: insightsOutcomes(hourly),\n\t\tinsights_failures: insightsFailures(hourly)\n\t};\n};\nconst insightsSchema = createInsightsSchema();\n//#endregion\nexport { DAILY_EVENTS, DAY_MS, DEFAULT_INSIGHTS_RETENTION, HOUR_MS, bundleRefOfFilter, bundleRefsOf, createInsightsSchema, insightsSchema, isFailedCheck, isLateEvent, isLaunch };\n", "import { DatabaseAdapterInputError, isDatabaseJsonObject } from \"@hot-updater/plugin-core\";\n//#region src/server/eventRow.ts\nconst CHANGE_KINDS = /* @__PURE__ */ new Set([\n\t\"first_seen\",\n\t\"bundle\",\n\t\"release\",\n\t\"app_version\",\n\t\"channel\",\n\t\"native_build\"\n]);\nconst isBundleEventChange = (value) => isDatabaseJsonObject(value) && Array.isArray(value.kinds) && value.kinds.length > 0 && value.kinds.every((kind) => CHANGE_KINDS.has(kind)) && (value.previous === null || isDatabaseJsonObject(value.previous) && typeof value.previous.bundle_id === \"string\" && (value.previous.release_id === null || typeof value.previous.release_id === \"string\") && typeof value.previous.app_version === \"string\" && typeof value.previous.channel === \"string\" && isOptional(value.previous, \"min_bundle_id\", isString));\nconst isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);\nconst isString = (value) => typeof value === \"string\";\nconst isDatabaseHttpResponse = (value) => isDatabaseJsonObject(value) && (value.resource === \"catalog\" || value.resource === \"artifact\") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === \"boolean\" && Number.isSafeInteger(value.received_at_ms);\n/** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */\nconst isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, \"resource\", isString) && isOptional(value, \"http_status\", (status) => Number.isSafeInteger(status)) && isOptional(value, \"transport\", isString) && isOptional(value, \"origin_code\", isString) && isOptional(value, \"error_message\", isString) && isOptional(value, \"error_stack\", isString);\nconst isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === \"string\" && (value.update_strategy === null || value.update_strategy === \"fingerprint\" || value.update_strategy === \"appVersion\") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === \"string\") && (value.sdk_version === null || typeof value.sdk_version === \"string\") && isOptional(value, \"min_bundle_id\", isString) && isOptional(value, \"failure\", isDatabaseBundleEventFailure) && isOptional(value, \"http_response\", isDatabaseHttpResponse) && isOptional(value, \"delivery\", isString) && isOptional(value, \"patch_fallback\", (flag) => typeof flag === \"boolean\") && isOptional(value, \"change\", isBundleEventChange) && isOptional(value, \"late\", (flag) => flag === true) && isOptional(value, \"implied_download\", (flag) => flag === true);\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/**\n* The built-in bundle a report says its installation runs: the running\n* bundle, which a download leaves at its source, when it is the native\n* build's built-in bundle, whatever Release selected it. Null for any other\n* bundle, and for a report without the build's built-in bundle ID.\n*/\nconst runningBuiltinBundleId = (row) => {\n\tconst running = row.type === \"UPDATE_DOWNLOADED\" ? row.from_bundle_id : row.to_bundle_id;\n\tconst builtin = isRecord(row.metadata) ? row.metadata.min_bundle_id : null;\n\treturn typeof builtin === \"string\" && running === builtin ? builtin : null;\n};\nconst isIdentity = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 255;\nconst isTextOrNull = (value) => value === null || typeof value === \"string\";\n/** Each bundle event field and what it holds. */\nconst BUNDLE_EVENT_FIELDS = {\n\tid: (value) => typeof value === \"string\",\n\ttype: (value) => value === \"UPDATE_DOWNLOADED\" || value === \"UPDATE_APPLIED\" || value === \"RECOVERED\" || value === \"UPDATE_FAILED\" || value === \"UNCHANGED\",\n\tinstall_id: isIdentity,\n\tuser_id: (value) => value === null || isIdentity(value),\n\tfrom_bundle_id: isTextOrNull,\n\tfrom_release_id: isTextOrNull,\n\tto_release_id: isTextOrNull,\n\tto_bundle_id: (value) => typeof value === \"string\",\n\tplatform: (value) => value === \"ios\" || value === \"android\",\n\tapp_version: (value) => typeof value === \"string\",\n\tchannel: (value) => typeof value === \"string\",\n\tmetadata: isDatabaseBundleEventMetadata,\n\treceived_at_ms: (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0\n};\nconst hasMetadata = (row, key) => isRecord(row.metadata) && Object.hasOwn(row.metadata, key);\nconst updateStrategyOf = (row) => isRecord(row.metadata) ? row.metadata.update_strategy : void 0;\n/**\n* A movement, or a failed update, names the bundle it left and how the\n* device updates, and a failed update says what failed; an unchanged report\n* names neither.\n*/\nconst hasEventInvariants = (row) => (row.type === \"UPDATE_DOWNLOADED\" || row.type === \"UPDATE_APPLIED\" || row.type === \"RECOVERED\" || row.type === \"UPDATE_FAILED\") && typeof row.from_bundle_id === \"string\" && (updateStrategyOf(row) === \"fingerprint\" || updateStrategyOf(row) === \"appVersion\") && (row.type !== \"UPDATE_FAILED\" || isRecord(row.metadata) && isRecord(row.metadata.failure)) && !hasMetadata(row, \"change\") && (!hasMetadata(row, \"late\") || row.type === \"UPDATE_DOWNLOADED\" || row.type === \"UPDATE_APPLIED\") && (!hasMetadata(row, \"implied_download\") || row.type === \"UPDATE_APPLIED\" || row.type === \"RECOVERED\") || row.type === \"UNCHANGED\" && !hasMetadata(row, \"late\") && row.from_bundle_id === null && updateStrategyOf(row) === null;\n/**\n* Throws unless `row` has exactly the bundle event fields, each of its type,\n* and the invariants of its event type: `invalid-field` for an unknown field,\n* `invalid-data` for anything else.\n*/\nconst validateBundleEventFields = (row) => {\n\tif (!isRecord(row)) throw new DatabaseAdapterInputError(\"invalid-data\");\n\tfor (const field of Object.keys(row)) if (!Object.hasOwn(BUNDLE_EVENT_FIELDS, field)) throw new DatabaseAdapterInputError(\"invalid-field\");\n\tfor (const [field, valid] of Object.entries(BUNDLE_EVENT_FIELDS)) if (!Object.hasOwn(row, field) || !valid(row[field])) throw new DatabaseAdapterInputError(\"invalid-data\");\n\tif (!hasEventInvariants(row)) throw new DatabaseAdapterInputError(\"invalid-data\");\n};\n//#endregion\nexport { isDatabaseBundleEventMetadata, isRecord, runningBuiltinBundleId, validateBundleEventFields };\n", "import { isRecord, validateBundleEventFields } from \"./eventRow.mjs\";\nimport { bundleRefOfFilter, bundleRefsOf } from \"./schema.mjs\";\nimport { DatabaseAdapterInputError, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/contract.ts\nconst encoder = new TextEncoder();\n/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */\nconst compareInsightsText = (left, right) => {\n\tconst a = encoder.encode(left);\n\tconst b = encoder.encode(right);\n\tfor (let index = 0; index < Math.min(a.length, b.length); index += 1) if (a[index] !== b[index]) return a[index] - b[index];\n\treturn a.length - b.length;\n};\nconst isWellFormedText = (value) => {\n\tfor (const character of value) {\n\t\tconst point = character.codePointAt(0);\n\t\tif (point >= 55296 && point <= 57343) return false;\n\t}\n\treturn true;\n};\nconst isIdentity = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 255 && isWellFormedText(value);\nconst isText = (value) => typeof value === \"string\" && value.length > 0 && isWellFormedText(value);\nconst isTimestamp = (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\nconst isLimit = (value) => isTimestamp(value) && value >= 1 && value <= 101;\nconst hasOnlyKeys = (value, keys) => Object.keys(value).every((key) => keys.includes(key));\nconst hasScope = (value) => (value.platform === \"ios\" || value.platform === \"android\") && isText(value.channel);\nconst isBundleFilter = (value, withKind = false) => {\n\tif (!isRecord(value) || !hasScope(value)) return false;\n\tconst keys = [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"type\",\n\t\t...withKind ? [\"kind\"] : []\n\t];\n\treturn value.type === \"RECOVERED\" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, \"fromBundleId\"]) : (value.type === \"UPDATE_DOWNLOADED\" || value.type === \"UPDATE_APPLIED\" || value.type === \"UPDATE_FAILED\" || value.type === \"UNCHANGED\") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, \"toBundleId\"]);\n};\nconst isEventFilter = (value) => {\n\tif (!isRecord(value)) return false;\n\tif (value.kind === \"all\") return hasOnlyKeys(value, [\"kind\"]);\n\tif (value.kind === \"installationMovement\") return isIdentity(value.installId) && hasOnlyKeys(value, [\"kind\", \"installId\"]);\n\treturn value.kind === \"bundle\" && isBundleFilter(value, true);\n};\nconst validateRow = (model, row, result = false) => {\n\ttry {\n\t\tvalidateBundleEventFields(row);\n\t\tif (!isRecord(row) || typeof row.id !== \"string\" || !isUUIDv7(row.id) || [...Object.values(row), ...isRecord(row.metadata) ? Object.values(row.metadata) : []].some((value) => typeof value === \"string\" && !isWellFormedText(value))) throw new DatabaseAdapterInputError(\"invalid-data\");\n\t} catch (error) {\n\t\tif (result) throw new DatabaseAdapterInputError(\"invalid-result\");\n\t\tthrow error;\n\t}\n};\n/** Throws `invalid-data` unless `row` is a complete, well-formed bundle event row. */\nconst assertBundleEventRow = (row) => validateRow(\"bundle_events\", row);\n/**\n* Downloads, applies, recoveries, failed updates, and the UNCHANGED rows\n* kept for a change belong in installation history.\n*/\nconst isInsightsMovementEvent = (event) => event.type === \"UPDATE_DOWNLOADED\" || event.type === \"UPDATE_APPLIED\" || event.type === \"RECOVERED\" || event.type === \"UPDATE_FAILED\" || event.type === \"UNCHANGED\";\nconst matchesInsightsEventFilter = (event, filter) => {\n\tif (filter.kind === \"all\") return true;\n\tif (filter.kind === \"installationMovement\") return event.install_id === filter.installId && isInsightsMovementEvent(event);\n\treturn event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && bundleRefsOf(event).includes(bundleRefOfFilter(filter));\n};\nconst invalidQuery = () => {\n\tthrow new DatabaseAdapterInputError(\"invalid-query\");\n};\nconst invalidResult = () => {\n\tthrow new DatabaseAdapterInputError(\"invalid-result\");\n};\nconst validateCount = (count) => isTimestamp(count) ? count : invalidResult();\nconst isTimeRange = (value) => isRecord(value) && hasOnlyKeys(value, [\"start\", \"end\"]) && isTimestamp(value.start) && isTimestamp(value.end) && value.start < value.end;\nconst isReleaseReference = (value) => isRecord(value) && hasOnlyKeys(value, [\n\t\"releaseId\",\n\t\"platform\",\n\t\"channel\"\n]) && isIdentity(value.releaseId) && hasScope(value);\nconst validateAggregateResult = (value) => {\n\tconst result = isRecord(value) ? value : invalidResult();\n\tif (!isTimestamp(result.measuredAtMs)) invalidResult();\n\tconst coverage = result.coverage;\n\tif (!isRecord(coverage) || coverage.kind !== \"complete\" && coverage.kind !== \"partial\" || coverage.sinceMs !== null && !isTimestamp(coverage.sinceMs)) invalidResult();\n};\n/** Validate custom and bundled providers at the same public boundary. */\nconst createValidatedInsightsModel = (model) => ({\n\tasync recordEvent(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\"event\"])) throw new DatabaseAdapterInputError(\"invalid-data\");\n\t\tvalidateRow(\"bundle_events\", input.event);\n\t\tawait model.recordEvent(input);\n\t},\n\tasync listEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"sinceMs\",\n\t\t\t\"beforeReceivedAtMs\",\n\t\t\t\"after\",\n\t\t\t\"limit\"\n\t\t]) || !isEventFilter(input.filter) || !isLimit(input.limit) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs !== void 0 && !isTimestamp(input.sinceMs)) invalidQuery();\n\t\tconst sinceMs = input.sinceMs ?? 0;\n\t\tif (sinceMs > input.beforeReceivedAtMs || input.after !== void 0 && (!isRecord(input.after) || !hasOnlyKeys(input.after, [\"receivedAtMs\", \"id\"]) || !isTimestamp(input.after.receivedAtMs) || typeof input.after.id !== \"string\" || !isUUIDv7(input.after.id) || input.after.receivedAtMs < sinceMs || input.after.receivedAtMs >= input.beforeReceivedAtMs)) invalidQuery();\n\t\tconst rows = await model.listEvents(input);\n\t\tif (!Array.isArray(rows) || rows.length > input.limit) invalidResult();\n\t\tlet previous = input.after;\n\t\tfor (const row of rows) {\n\t\t\tvalidateRow(\"bundle_events\", row, true);\n\t\t\tif (row.received_at_ms < sinceMs || row.received_at_ms >= input.beforeReceivedAtMs || !matchesInsightsEventFilter(row, input.filter) || previous !== void 0 && (row.received_at_ms > previous.receivedAtMs || row.received_at_ms === previous.receivedAtMs && row.id >= previous.id)) invalidResult();\n\t\t\tprevious = {\n\t\t\t\treceivedAtMs: row.received_at_ms,\n\t\t\t\tid: row.id\n\t\t\t};\n\t\t}\n\t\treturn rows;\n\t},\n\tasync findLatestEvents(input) {\n\t\tif (!isRecord(input)) invalidQuery();\n\t\tif (\"installId\" in input) {\n\t\t\tif (!hasOnlyKeys(input, [\"installId\"]) || !isIdentity(input.installId)) invalidQuery();\n\t\t} else if (!hasOnlyKeys(input, [\n\t\t\t\"userId\",\n\t\t\t\"afterInstallId\",\n\t\t\t\"limit\"\n\t\t]) || !isIdentity(input.userId) || !isLimit(input.limit) || input.afterInstallId !== void 0 && !isIdentity(input.afterInstallId)) invalidQuery();\n\t\tconst rows = await model.findLatestEvents(input);\n\t\tif (!Array.isArray(rows) || rows.length > (\"installId\" in input ? 1 : input.limit)) invalidResult();\n\t\tlet previous = \"installId\" in input ? void 0 : input.afterInstallId;\n\t\tfor (const row of rows) {\n\t\t\tvalidateRow(\"bundle_events\", row, true);\n\t\t\tif (\"installId\" in input ? row.install_id !== input.installId : row.user_id !== input.userId || previous !== void 0 && compareInsightsText(row.install_id, previous) <= 0) invalidResult();\n\t\t\tprevious = row.install_id;\n\t\t}\n\t\treturn rows;\n\t},\n\tasync countLatestEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"sinceMs\",\n\t\t\t\"bundle\"\n\t\t]) || !hasScope(input) || !isTimestamp(input.sinceMs) || input.bundle !== void 0 && (!Array.isArray(input.bundle) || input.bundle.length < 1 || input.bundle.length > 2 || input.bundle.some((bundle) => !isRecord(bundle) || !hasOnlyKeys(bundle, [\n\t\t\t\"field\",\n\t\t\t\"value\",\n\t\t\t\"types\"\n\t\t]) || bundle.field !== \"from_bundle_id\" && bundle.field !== \"to_bundle_id\" || !isText(bundle.value) || !Array.isArray(bundle.types) || bundle.types.length === 0 || bundle.types.some((type) => ![\n\t\t\t\"UNCHANGED\",\n\t\t\t\"UPDATE_DOWNLOADED\",\n\t\t\t\"UPDATE_APPLIED\",\n\t\t\t\"RECOVERED\"\n\t\t].includes(type))))) invalidQuery();\n\t\treturn validateCount(await model.countLatestEvents(input));\n\t},\n\tasync countEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"sinceMs\",\n\t\t\t\"beforeReceivedAtMs\"\n\t\t]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();\n\t\treturn validateCount(await model.countEvents(input));\n\t},\n\tasync countEventSeries(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"timeRange\",\n\t\t\t\"intervalMs\"\n\t\t]) || !isBundleFilter(input.filter) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs)) invalidQuery();\n\t\tconst { start, end } = input.timeRange;\n\t\tconst { intervalMs } = input;\n\t\tif (intervalMs === 0 || intervalMs % 36e5 !== 0 || start % 36e5 !== 0 || (end - start) % intervalMs !== 0 || end - start > 7776e6) invalidQuery();\n\t\tconst points = await model.countEventSeries(input);\n\t\tif (!Array.isArray(points) || points.length !== (end - start) / intervalMs || points.some((point, index) => !isRecord(point) || !hasOnlyKeys(point, [\"startMs\", \"events\"]) || point.startMs !== start + index * intervalMs || !isTimestamp(point.events))) invalidResult();\n\t\treturn points;\n\t},\n\tasync getReleaseActivity(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\"releases\"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();\n\t\tconst result = await model.getReleaseActivity(input);\n\t\tif (!isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord(item) || !isReleaseReference(item.release) || !isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();\n\t\treturn result;\n\t},\n\tasync getAppUsage(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"channel\",\n\t\t\t\"platform\",\n\t\t\t\"appVersion\",\n\t\t\t\"timeRange\",\n\t\t\t\"intervalMs\"\n\t\t]) || !isText(input.channel) || ![\n\t\t\t\"all\",\n\t\t\t\"ios\",\n\t\t\t\"android\"\n\t\t].includes(input.platform) || input.appVersion !== void 0 && !isText(input.appVersion) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs) || input.intervalMs < 36e5) invalidQuery();\n\t\tconst result = await model.getAppUsage(input);\n\t\tvalidateAggregateResult(result);\n\t\tif (!isTimestamp(result.activeInstallations) || !Array.isArray(result.points) || !Array.isArray(result.appVersions) || !Array.isArray(result.versions) || !Array.isArray(result.platforms) || !Array.isArray(result.bundleDistribution)) invalidResult();\n\t\treturn result;\n\t}\n});\n//#endregion\nexport { assertBundleEventRow, compareInsightsText, createValidatedInsightsModel, isInsightsMovementEvent, matchesInsightsEventFilter };\n", "import { createValidatedInsightsModel } from \"./contract.mjs\";\n//#region src/server/model.ts\n/**\n* The plugin's API as `InsightsModel`, validated at its boundary: what the\n* Insights routes, the console, and the e2e harness read through.\n*/\nconst createInsightsModel = (api) => createValidatedInsightsModel({\n\trecordEvent: ({ event }) => api.recordEvent(event),\n\tlistEvents: api.listEvents,\n\tfindLatestEvents: api.findLatestEvents,\n\tcountLatestEvents: api.countLatestEvents,\n\tcountEvents: api.countEvents,\n\tcountEventSeries: api.countEventSeries,\n\tgetReleaseActivity: api.getReleaseActivity,\n\tgetAppUsage: api.getAppUsage\n});\n//#endregion\nexport { createInsightsModel };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"insights\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "//#region src/server/errors.ts\n/**\n* What Insights' API throws for an input it refuses, such as an unknown\n* event field or a malformed cursor; its routes answer 400 for it.\n*/\nvar InsightsBadRequestError = class extends Error {\n\tname = \"InsightsBadRequestError\";\n};\nvar InsightsPayloadTooLargeError = class extends Error {\n\tmaximumBytes;\n\tname = \"InsightsPayloadTooLargeError\";\n\tconstructor(maximumBytes) {\n\t\tsuper(`Event payload exceeds ${maximumBytes} bytes`);\n\t\tthis.maximumBytes = maximumBytes;\n\t}\n};\n//#endregion\nexport { InsightsBadRequestError, InsightsPayloadTooLargeError };\n", "import { InsightsBadRequestError, InsightsPayloadTooLargeError } from \"./errors.mjs\";\nimport { createUUIDv7, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/eventInput.ts\nconst MAX_EVENT_STRING_LENGTH = 1024;\nconst MAX_IDENTITY_LENGTH = 255;\nconst EVENT_BODY_MAX_BYTES = 16384;\nfunction isRecord(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction requireStringField(payload, key) {\n\tconst value = payload[key];\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH || new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new InsightsBadRequestError(`Invalid event field: ${key}`);\n\treturn value;\n}\nfunction requireNullableStringField(payload, key) {\n\tif (payload[key] === null) return null;\n\treturn requireStringField(payload, key);\n}\nfunction requireIdentityField(payload, key) {\n\tconst value = requireStringField(payload, key);\n\tif (value.length > MAX_IDENTITY_LENGTH) throw new InsightsBadRequestError(`Invalid event field: ${key}`);\n\treturn value;\n}\n/**\n* The report's idempotency key, when the client sends one: it creates the\n* UUIDv7 once and repeats it on every retry of that report.\n*/\nfunction readEventId(payload) {\n\tconst value = payload.eventId;\n\tif (value === void 0) return void 0;\n\tif (!isUUIDv7(value)) throw new InsightsBadRequestError(\"Invalid event field: eventId\");\n\treturn value;\n}\n/**\n* The native build's built-in bundle ID: a bundle ID's length at most, and\n* left out when it is missing or malformed, so the report still records.\n*/\nconst readMinBundleId = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 36 ? value : null;\n/** One value of an open set: any other value reads as `unknown`. */\nconst oneOf = (values, value) => values.includes(value) ? value : \"unknown\";\nconst STAGES = [\n\t\"check\",\n\t\"download\",\n\t\"install\"\n];\nconst REASONS = [\n\t\"network\",\n\t\"http\",\n\t\"invalid_response\",\n\t\"hash_mismatch\",\n\t\"signature\",\n\t\"patch\",\n\t\"extract\",\n\t\"storage\"\n];\nconst RESOURCES = [\n\t\"catalog\",\n\t\"artifact\",\n\t\"manifest\",\n\t\"file\",\n\t\"patch\",\n\t\"archive\"\n];\nconst TRANSPORTS = [\n\t\"timeout\",\n\t\"dns\",\n\t\"tls\",\n\t\"connection\",\n\t\"offline\",\n\t\"cancelled\"\n];\nconst DELIVERIES = [\n\t\"patch\",\n\t\"manifest\",\n\t\"archive\"\n];\n/** A storage error code: letters, digits, and `._-`. */\nconst CODE = /^[A-Za-z0-9._-]{1,64}$/;\nconst readCode = (value) => typeof value === \"string\" && CODE.test(value) ? value : void 0;\nconst readMetadata = (payload) => isRecord(payload.metadata) ? payload.metadata : {};\n/**\n* What an UPDATE_FAILED report says failed. It never refuses the report: an\n* unknown value of a set reads as `unknown`, a missing or malformed failure\n* as an unknown stage and reason, and a malformed optional field is left out,\n* as is a null one.\n*/\nfunction readFailure(value) {\n\tconst failure = isRecord(value) ? value : {};\n\tconst httpStatus = failure.httpStatus;\n\tconst originCode = readCode(failure.originCode);\n\tconst errorMessage = typeof failure.errorMessage === \"string\" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;\n\tconst errorStack = typeof failure.errorStack === \"string\" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;\n\treturn {\n\t\tstage: oneOf(STAGES, failure.stage),\n\t\treason: oneOf(REASONS, failure.reason),\n\t\t...failure.resource == null ? {} : { resource: oneOf(RESOURCES, failure.resource) },\n\t\t...Number.isSafeInteger(httpStatus) && httpStatus >= 100 && httpStatus <= 599 ? { httpStatus } : {},\n\t\t...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },\n\t\t...originCode === void 0 ? {} : { originCode },\n\t\t...errorMessage === void 0 ? {} : { errorMessage },\n\t\t...errorStack === void 0 ? {} : { errorStack }\n\t};\n}\nfunction readHttpResponse(value) {\n\tif (!isRecord(value) || value.resource !== \"catalog\" && value.resource !== \"artifact\" || typeof value.path !== \"string\" || value.path.length > 1024 || !Number.isSafeInteger(value.status) || value.status < 100 || value.status > 599 || value.body !== null && (typeof value.body !== \"string\" || new TextEncoder().encode(JSON.stringify(value.body)).byteLength > 4096) || typeof value.bodyTruncated !== \"boolean\" || !Number.isSafeInteger(value.receivedAtMs) || value.receivedAtMs < 0) throw new InsightsBadRequestError(\"Invalid HTTP response details\");\n\treturn {\n\t\tresource: value.resource,\n\t\tpath: value.path,\n\t\tstatus: value.status,\n\t\tbody: value.body,\n\t\tbodyTruncated: value.bodyTruncated,\n\t\treceivedAtMs: value.receivedAtMs\n\t};\n}\nasync function readBoundedText(request) {\n\tconst contentLength = request.headers.get(\"content-length\");\n\tconst declaredByteLength = Number(contentLength);\n\tif (contentLength !== null && Number.isSafeInteger(declaredByteLength) && declaredByteLength > 16384) throw new InsightsPayloadTooLargeError(EVENT_BODY_MAX_BYTES);\n\tif (request.body === null) return \"\";\n\tconst reader = request.body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet byteLength = 0;\n\tlet text = \"\";\n\twhile (true) {\n\t\tconst result = await reader.read();\n\t\tif (result.done) break;\n\t\tbyteLength += result.value.byteLength;\n\t\tif (byteLength > 16384) {\n\t\t\tawait reader.cancel();\n\t\t\tthrow new InsightsPayloadTooLargeError(EVENT_BODY_MAX_BYTES);\n\t\t}\n\t\ttext += decoder.decode(result.value, { stream: true });\n\t}\n\treturn text + decoder.decode();\n}\nasync function parseJson(request) {\n\tconst text = await readBoundedText(request);\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) throw new InsightsBadRequestError(\"Invalid event payload\");\n\t\tthrow error;\n\t}\n}\nfunction requireEvent(payload) {\n\tif (!isRecord(payload)) throw new InsightsBadRequestError(\"Invalid event payload\");\n\tconst platform = requireStringField(payload, \"platform\");\n\tif (platform !== \"ios\" && platform !== \"android\") throw new InsightsBadRequestError(\"Invalid event field: platform\");\n\tconst eventId = readEventId(payload);\n\tconst metadata = readMetadata(payload);\n\tconst httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };\n\tconst base = {\n\t\t...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },\n\t\t...eventId === void 0 ? {} : { eventId },\n\t\tinstallId: requireIdentityField(payload, \"installId\"),\n\t\ttoBundleId: requireStringField(payload, \"toBundleId\"),\n\t\t...payload.userId === void 0 ? {} : { userId: requireIdentityField(payload, \"userId\") },\n\t\tplatform,\n\t\tappVersion: requireStringField(payload, \"appVersion\"),\n\t\tchannel: requireStringField(payload, \"channel\"),\n\t\tcohort: requireStringField(payload, \"cohort\"),\n\t\tfingerprintHash: requireNullableStringField(payload, \"fingerprintHash\"),\n\t\tsdkVersion: payload.sdkVersion === void 0 ? null : requireNullableStringField(payload, \"sdkVersion\"),\n\t\tminBundleId: readMinBundleId(payload.minBundleId),\n\t\tfromReleaseId: requireNullableStringField(payload, \"fromReleaseId\"),\n\t\ttoReleaseId: requireNullableStringField(payload, \"toReleaseId\")\n\t};\n\tconst type = requireStringField(payload, \"type\");\n\tconst movement = () => {\n\t\tconst updateStrategy = requireStringField(payload, \"updateStrategy\");\n\t\tif (updateStrategy !== \"fingerprint\" && updateStrategy !== \"appVersion\") throw new InsightsBadRequestError(\"Invalid event field: updateStrategy\");\n\t\treturn {\n\t\t\t...base,\n\t\t\tfromBundleId: requireStringField(payload, \"fromBundleId\"),\n\t\t\tupdateStrategy\n\t\t};\n\t};\n\tswitch (type) {\n\t\tcase \"UPDATE_DOWNLOADED\": {\n\t\t\tconst delivery = metadata.delivery;\n\t\t\tconst read = {\n\t\t\t\t...httpMetadata,\n\t\t\t\t...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },\n\t\t\t\t...metadata.patchFallback === true ? { patchFallback: true } : {}\n\t\t\t};\n\t\t\treturn {\n\t\t\t\t...movement(),\n\t\t\t\ttype,\n\t\t\t\t...Object.keys(read).length === 0 ? {} : { metadata: read }\n\t\t\t};\n\t\t}\n\t\tcase \"UPDATE_APPLIED\":\n\t\tcase \"RECOVERED\": return {\n\t\t\t...movement(),\n\t\t\ttype\n\t\t};\n\t\tcase \"UPDATE_FAILED\": return {\n\t\t\t...movement(),\n\t\t\ttype,\n\t\t\tmetadata: {\n\t\t\t\t...httpMetadata,\n\t\t\t\tfailure: readFailure(metadata.failure)\n\t\t\t}\n\t\t};\n\t\tcase \"UNCHANGED\":\n\t\t\tif (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new InsightsBadRequestError(\"Invalid unchanged event shape\");\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\ttype,\n\t\t\t\tfromBundleId: null,\n\t\t\t\tupdateStrategy: null\n\t\t\t};\n\t\tdefault: throw new InsightsBadRequestError(\"Invalid event field: type\");\n\t}\n}\nasync function parseBundleEventRequest(request) {\n\treturn requireEvent(await parseJson(request));\n}\nfunction createBundleEventRow(input) {\n\tinput = requireEvent(input);\n\tconst base = {\n\t\tapp_version: input.appVersion,\n\t\tchannel: input.channel,\n\t\tfrom_release_id: input.fromReleaseId,\n\t\tid: input.eventId ?? createUUIDv7(),\n\t\tinstall_id: input.installId,\n\t\tplatform: input.platform,\n\t\treceived_at_ms: Date.now(),\n\t\tto_bundle_id: input.toBundleId,\n\t\tto_release_id: input.toReleaseId,\n\t\tuser_id: input.userId ?? null\n\t};\n\tconst response = input.metadata?.httpResponse;\n\tconst metadata = {\n\t\t...response ? { http_response: {\n\t\t\tresource: response.resource,\n\t\t\tpath: response.path,\n\t\t\tstatus: response.status,\n\t\t\tbody: response.body,\n\t\t\tbody_truncated: response.bodyTruncated,\n\t\t\treceived_at_ms: response.receivedAtMs\n\t\t} } : {},\n\t\tcohort: input.cohort,\n\t\tfingerprint_hash: input.fingerprintHash,\n\t\tsdk_version: input.sdkVersion ?? null,\n\t\t...input.minBundleId ? { min_bundle_id: input.minBundleId } : {},\n\t\tupdate_strategy: input.updateStrategy\n\t};\n\tswitch (input.type) {\n\t\tcase \"UPDATE_DOWNLOADED\": {\n\t\t\tconst { delivery, patchFallback } = input.metadata ?? {};\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\t\ttype: input.type,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...metadata,\n\t\t\t\t\t...delivery === void 0 ? {} : { delivery },\n\t\t\t\t\t...patchFallback ? { patch_fallback: true } : {}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tcase \"UPDATE_APPLIED\":\n\t\tcase \"RECOVERED\": return {\n\t\t\t...base,\n\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\ttype: input.type,\n\t\t\tmetadata\n\t\t};\n\t\tcase \"UPDATE_FAILED\": {\n\t\t\tconst { failure } = input.metadata;\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\t\ttype: input.type,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...metadata,\n\t\t\t\t\tfailure: {\n\t\t\t\t\t\tstage: failure.stage,\n\t\t\t\t\t\treason: failure.reason,\n\t\t\t\t\t\t...failure.errorMessage === void 0 ? {} : { error_message: failure.errorMessage },\n\t\t\t\t\t\t...failure.errorStack === void 0 ? {} : { error_stack: failure.errorStack },\n\t\t\t\t\t\t...failure.resource === void 0 ? {} : { resource: failure.resource },\n\t\t\t\t\t\t...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },\n\t\t\t\t\t\t...failure.transport === void 0 ? {} : { transport: failure.transport },\n\t\t\t\t\t\t...failure.originCode === void 0 ? {} : { origin_code: failure.originCode }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tcase \"UNCHANGED\": return {\n\t\t\t...base,\n\t\t\tfrom_bundle_id: null,\n\t\t\ttype: input.type,\n\t\t\tmetadata\n\t\t};\n\t}\n}\n//#endregion\nexport { EVENT_BODY_MAX_BYTES, createBundleEventRow, parseBundleEventRequest };\n", "import { compareInsightsText, isInsightsMovementEvent } from \"./contract.mjs\";\nimport { InsightsBadRequestError } from \"./errors.mjs\";\nimport { createBundleEventRow } from \"./eventInput.mjs\";\nimport { isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/provider.ts\nconst DEFAULT_PAGE_LIMIT = 50;\nconst MAX_PAGE_LIMIT = 100;\nconst MAX_EVENT_ID_LENGTH = 1024;\nconst MAX_IDENTITY_LENGTH = 255;\nconst MAX_CURSOR_LENGTH = 8192;\nconst HOUR_MS = 36e5;\nconst DAY_MS = 24 * HOUR_MS;\nconst WINDOW_MS = {\n\t\"24h\": 864e5,\n\t\"7d\": 6048e5,\n\t\"30d\": 2592e6\n};\n/**\n* The longest receipt range, `[sinceMs, beforeReceivedAtMs)`, of a global or\n* bundle event list, and the range one covers without `sinceMs`: raw events\n* are listed inside a time range, as analytics products list them. It is a\n* duration, so a range that ends mid-day touches 91 UTC days. Installation\n* history is one index range and reads back to `sinceMs`.\n*/\nconst EVENT_LIST_RANGE_MS = 2160 * HOUR_MS;\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst requireString = (value, label, maximumLength) => {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > maximumLength || new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new InsightsBadRequestError(`Invalid ${label}.`);\n\treturn value;\n};\nconst requireTimestamp = (value, label) => {\n\tif (!Number.isSafeInteger(value) || Number(value) < 0) throw new InsightsBadRequestError(`Invalid ${label}.`);\n\treturn Number(value);\n};\nconst readLimit = (value) => {\n\tconst limit = value ?? DEFAULT_PAGE_LIMIT;\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_PAGE_LIMIT) throw new InsightsBadRequestError(\"Invalid page limit.\");\n\treturn limit;\n};\nconst encodeBase64Url = (value) => {\n\tconst bytes = new TextEncoder().encode(value);\n\tlet binary = \"\";\n\tfor (const byte of bytes) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst decodeBase64Url = (value) => {\n\tif (value.length === 0 || value.length > MAX_CURSOR_LENGTH) throw new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\ttry {\n\t\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\t\tconst padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n\t\tconst binary = atob(padded);\n\t\tconst bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));\n\t\treturn new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n\t} catch {\n\t\tthrow new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\t}\n};\nconst encodeCursor = (value) => encodeBase64Url(JSON.stringify(value));\nconst decodeCursor = (value) => {\n\ttry {\n\t\treturn JSON.parse(decodeBase64Url(value));\n\t} catch (error) {\n\t\tif (error instanceof InsightsBadRequestError) throw error;\n\t\tthrow new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\t}\n};\nconst readScope = (input) => {\n\tif (input.platform !== \"ios\" && input.platform !== \"android\") throw new InsightsBadRequestError(\"Invalid Insights platform.\");\n\treturn {\n\t\tplatform: input.platform,\n\t\tchannel: requireString(input.channel, \"channel\", MAX_EVENT_ID_LENGTH)\n\t};\n};\nconst bundleFilter = (input) => {\n\tconst scope = readScope(input);\n\tconst bundleId = requireString(input.bundleId, \"bundle ID\", MAX_EVENT_ID_LENGTH);\n\tswitch (input.outcome) {\n\t\tcase \"downloaded\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_DOWNLOADED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tcase \"applied\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_APPLIED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tcase \"recovered\": return {\n\t\t\t...scope,\n\t\t\ttype: \"RECOVERED\",\n\t\t\tfromBundleId: bundleId\n\t\t};\n\t\tcase \"failed\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_FAILED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tdefault: throw new InsightsBadRequestError(\"Invalid Insights outcome.\");\n\t}\n};\nconst sameFilter = (left, right) => {\n\tif (!isRecord(left) || left.kind !== right.kind) return false;\n\tswitch (right.kind) {\n\t\tcase \"all\": return true;\n\t\tcase \"installationMovement\": return left.installId === right.installId;\n\t\tcase \"bundle\": return left.platform === right.platform && left.channel === right.channel && left.type === right.type && (right.type === \"RECOVERED\" ? left.fromBundleId === right.fromBundleId : left.toBundleId === right.toBundleId);\n\t}\n};\nconst readEventCursor = (value, filter) => {\n\tconst cursor = decodeCursor(value);\n\tif (!isRecord(cursor) || cursor.version !== 2 || cursor.kind !== \"events\" || !isRecord(cursor.filter) || !isRecord(cursor.after)) throw new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\tif (!sameFilter(cursor.filter, filter)) throw new InsightsBadRequestError(\"Insights cursor does not match the requested events.\");\n\tif (typeof cursor.after.id !== \"string\" || !isUUIDv7(cursor.after.id)) throw new InsightsBadRequestError(\"Invalid Insights event cursor ID.\");\n\treturn {\n\t\tafter: {\n\t\t\tid: cursor.after.id,\n\t\t\treceivedAtMs: requireTimestamp(cursor.after.receivedAtMs, \"event cursor\")\n\t\t},\n\t\tbeforeReceivedAtMs: requireTimestamp(cursor.beforeReceivedAtMs, \"event cutoff\"),\n\t\tkind: \"events\",\n\t\tsinceMs: requireTimestamp(cursor.sinceMs, \"event start\"),\n\t\tfilter,\n\t\tversion: 2\n\t};\n};\nconst readUserInstallationCursor = (value, userId) => {\n\tconst cursor = decodeCursor(value);\n\tif (!isRecord(cursor) || cursor.version !== 1 || cursor.kind !== \"user-installations\" || cursor.userId !== userId) throw new InsightsBadRequestError(\"Insights cursor does not match the requested user ID.\");\n\treturn {\n\t\tafterInstallId: requireString(cursor.afterInstallId, \"installation cursor\", MAX_IDENTITY_LENGTH),\n\t\tkind: \"user-installations\",\n\t\tuserId,\n\t\tversion: 1\n\t};\n};\nconst compareEventNewest = (left, right) => right.received_at_ms - left.received_at_ms || compareInsightsText(right.id, left.id);\nconst isAfterEventCursor = (row, after) => row.received_at_ms < after.receivedAtMs || row.received_at_ms === after.receivedAtMs && compareInsightsText(row.id, after.id) < 0;\nconst assertEventRows = (rows, input) => {\n\tif (rows.length > input.limit) throw new Error(\"Insights database returned too many event rows.\");\n\tfor (let index = 0; index < rows.length; index += 1) {\n\t\tconst row = rows[index];\n\t\tconst previous = rows[index - 1];\n\t\tif (!row || typeof row.id !== \"string\" || !isUUIDv7(row.id) || !Number.isSafeInteger(row.received_at_ms) || row.received_at_ms >= input.beforeReceivedAtMs || row.received_at_ms < input.sinceMs || previous !== void 0 && compareEventNewest(previous, row) >= 0 || input.after !== void 0 && !isAfterEventCursor(row, input.after) || input.filter.kind === \"installationMovement\" && (row.install_id !== input.filter.installId || !isInsightsMovementEvent(row)) || input.filter.kind === \"bundle\" && (row.platform !== input.filter.platform || row.channel !== input.filter.channel || row.type !== input.filter.type || (input.filter.type === \"RECOVERED\" ? row.from_bundle_id !== input.filter.fromBundleId : row.to_bundle_id !== input.filter.toBundleId))) throw new Error(\"Insights database returned invalid event rows.\");\n\t}\n};\n/** An `UPDATE_FAILED` row's failure, as the event lists show it. */\nconst toFailure = (failure) => ({\n\tstage: failure.stage,\n\treason: failure.reason,\n\t...failure.error_message === void 0 ? {} : { errorMessage: failure.error_message },\n\t...failure.error_stack === void 0 ? {} : { errorStack: failure.error_stack },\n\t...failure.resource === void 0 ? {} : { resource: failure.resource },\n\t...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },\n\t...failure.transport === void 0 ? {} : { transport: failure.transport },\n\t...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code }\n});\n/** What a row's metadata adds for its type: a failure or a delivery. */\nconst eventDetails = ({ type, metadata }) => ({\n\t...metadata.http_response !== void 0 ? { httpResponse: {\n\t\tresource: metadata.http_response.resource,\n\t\tpath: metadata.http_response.path,\n\t\tstatus: metadata.http_response.status,\n\t\tbody: metadata.http_response.body,\n\t\tbodyTruncated: metadata.http_response.body_truncated,\n\t\treceivedAtMs: metadata.http_response.received_at_ms\n\t} } : {},\n\t...type === \"UPDATE_FAILED\" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},\n\t...type === \"UPDATE_DOWNLOADED\" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},\n\t...type === \"UPDATE_DOWNLOADED\" && metadata.patch_fallback === true ? { patchFallback: true } : {},\n\t...type === \"UNCHANGED\" && metadata.change !== void 0 ? { change: {\n\t\tkinds: metadata.change.kinds,\n\t\t...metadata.change.previous === null ? {} : { previous: {\n\t\t\tbundleId: metadata.change.previous.bundle_id,\n\t\t\treleaseId: metadata.change.previous.release_id,\n\t\t\tappVersion: metadata.change.previous.app_version,\n\t\t\tchannel: metadata.change.previous.channel,\n\t\t\t...metadata.change.previous.min_bundle_id === void 0 ? {} : { minBundleId: metadata.change.previous.min_bundle_id }\n\t\t} }\n\t} } : {},\n\t...metadata.late === true ? { late: true } : {},\n\t...metadata.implied_download === true ? { impliedDownload: true } : {}\n});\nconst toEventHistoryRow = (row) => ({\n\t...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },\n\t...row.metadata.sdk_version == null ? {} : { sdkVersion: row.metadata.sdk_version },\n\t...row.metadata.min_bundle_id === void 0 ? {} : { minBundleId: row.metadata.min_bundle_id },\n\tappVersion: row.app_version,\n\tchannel: row.channel,\n\tcohort: row.metadata.cohort,\n\tfromBundleId: row.from_bundle_id,\n\tid: row.id,\n\tinstallId: row.install_id,\n\tplatform: row.platform,\n\treceivedAtMs: row.received_at_ms,\n\ttoBundleId: row.to_bundle_id,\n\ttype: row.type,\n\tuserId: row.user_id,\n\t...eventDetails(row)\n});\nconst toInstallationRow = (row) => ({\n\t...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},\n\t...row.metadata.min_bundle_id === void 0 ? {} : { minBundleId: row.metadata.min_bundle_id },\n\tappVersion: row.app_version,\n\tchannel: row.channel,\n\tcohort: row.metadata.cohort,\n\tinstallId: row.install_id,\n\tlastKnownBundleId: row.type === \"UPDATE_DOWNLOADED\" ? row.from_bundle_id : row.to_bundle_id,\n\tpendingBundleId: row.type === \"UPDATE_DOWNLOADED\" ? row.to_bundle_id : null,\n\tpendingReleaseId: row.type === \"UPDATE_DOWNLOADED\" ? row.to_release_id : null,\n\tlatestStatus: row.type,\n\tplatform: row.platform,\n\treceivedAtMs: row.received_at_ms,\n\tuserId: row.user_id\n});\n/**\n* Where a list without `sinceMs` starts: 90 days before its cutoff for the\n* global and bundle lists, at the first event for installation history.\n*/\nconst defaultEventStart = (filter, beforeReceivedAtMs) => filter.kind === \"installationMovement\" ? 0 : Math.max(0, beforeReceivedAtMs - EVENT_LIST_RANGE_MS);\n/** Whether a cursor's row lies inside the list's range. */\nconst isInsideBounds = ({ after }, bounds) => after.receivedAtMs >= bounds.sinceMs && after.receivedAtMs < bounds.beforeReceivedAtMs;\n/** A page's range: its cursor's, which the request may repeat but not change. */\nconst readEventBounds = (input, cursor, filter) => {\n\tconst beforeReceivedAtMs = cursor?.beforeReceivedAtMs ?? (input.beforeReceivedAtMs === void 0 ? Date.now() : requireTimestamp(input.beforeReceivedAtMs, \"event cutoff\"));\n\tif (cursor !== void 0 && input.beforeReceivedAtMs !== void 0 && input.beforeReceivedAtMs !== beforeReceivedAtMs) throw new InsightsBadRequestError(\"Insights cursor does not match the requested event cutoff.\");\n\tconst sinceMs = cursor?.sinceMs ?? (input.sinceMs === void 0 ? defaultEventStart(filter, beforeReceivedAtMs) : requireTimestamp(input.sinceMs, \"event start\"));\n\tconst bounds = {\n\t\tbeforeReceivedAtMs,\n\t\tsinceMs\n\t};\n\tif (sinceMs > beforeReceivedAtMs || input.sinceMs !== void 0 && input.sinceMs !== sinceMs || cursor !== void 0 && !isInsideBounds(cursor, bounds)) throw new InsightsBadRequestError(\"Insights cursor or range does not match the requested event start.\");\n\tif (filter.kind !== \"installationMovement\" && beforeReceivedAtMs - sinceMs > 7776e6) throw new InsightsBadRequestError(\"Insights event lists cover at most 90 days: send a sinceMs no more than 90 days before beforeReceivedAtMs.\");\n\treturn bounds;\n};\nconst pageEventRows = async (model, input, filter, map) => {\n\tconst limit = readLimit(input.limit);\n\tconst cursor = input.cursor === void 0 ? void 0 : readEventCursor(input.cursor, filter);\n\tconst bounds = readEventBounds(input, cursor, filter);\n\tconst query = {\n\t\tfilter,\n\t\t...bounds,\n\t\t...cursor === void 0 ? {} : { after: cursor.after },\n\t\tlimit\n\t};\n\tconst rows = await model.listEvents(query);\n\tassertEventRows(rows, query);\n\tconst last = rows.at(-1);\n\treturn {\n\t\tbeforeReceivedAtMs: bounds.beforeReceivedAtMs,\n\t\tdata: rows.map(map),\n\t\tnextCursor: rows.length === limit && last ? encodeCursor({\n\t\t\tafter: {\n\t\t\t\tid: last.id,\n\t\t\t\treceivedAtMs: last.received_at_ms\n\t\t\t},\n\t\t\t...bounds,\n\t\t\tkind: \"events\",\n\t\t\tfilter,\n\t\t\tversion: 2\n\t\t}) : null\n\t};\n};\nconst assertInstallationRows = (rows, input) => {\n\tif (rows.length > input.limit) throw new Error(\"Insights database returned too many installation rows.\");\n\tfor (let index = 0; index < rows.length; index += 1) {\n\t\tconst row = rows[index];\n\t\tconst previous = rows[index - 1];\n\t\tif (!row || row.user_id !== input.userId || input.afterInstallId !== void 0 && compareInsightsText(row.install_id, input.afterInstallId) <= 0 || previous !== void 0 && compareInsightsText(previous.install_id, row.install_id) >= 0) throw new Error(\"Insights database returned invalid installation rows.\");\n\t}\n};\nconst createInsightsProvider = (model) => Object.freeze({\n\tasync appendBundleEvent(input) {\n\t\tconst event = createBundleEventRow(input);\n\t\tawait model.recordEvent({ event });\n\t},\n\tlistEvents(input) {\n\t\tconst filter = input.bundle === void 0 ? { kind: \"all\" } : {\n\t\t\tkind: \"bundle\",\n\t\t\t...bundleFilter(input.bundle)\n\t\t};\n\t\treturn pageEventRows(model, input, filter, toEventHistoryRow);\n\t},\n\tasync listInstallationEvents(input) {\n\t\tif (\"bundle\" in input && input.bundle !== void 0) throw new InsightsBadRequestError(\"Installation movement queries cannot include a bundle filter.\");\n\t\tconst installId = requireString(input.installId, \"install ID\", MAX_IDENTITY_LENGTH);\n\t\treturn pageEventRows(model, input, {\n\t\t\tkind: \"installationMovement\",\n\t\t\tinstallId\n\t\t}, (row) => toEventHistoryRow(row));\n\t},\n\tasync getInstallation({ installId }) {\n\t\tconst normalizedInstallId = requireString(installId, \"install ID\", MAX_IDENTITY_LENGTH);\n\t\tconst rows = await model.findLatestEvents({ installId: normalizedInstallId });\n\t\tconst row = rows[0] ?? null;\n\t\tif (rows.length > 1 || row !== null && row.install_id !== normalizedInstallId) throw new Error(\"Insights database returned an invalid installation.\");\n\t\treturn row === null ? null : toInstallationRow(row);\n\t},\n\tasync pageInstallationsByCurrentUserId(input) {\n\t\tconst userId = requireString(input.userId, \"user ID\", MAX_IDENTITY_LENGTH);\n\t\tconst limit = readLimit(input.limit);\n\t\tconst cursor = input.cursor === void 0 ? void 0 : readUserInstallationCursor(input.cursor, userId);\n\t\tconst databaseInput = {\n\t\t\tuserId,\n\t\t\t...cursor === void 0 ? {} : { afterInstallId: cursor.afterInstallId },\n\t\t\tlimit\n\t\t};\n\t\tconst rows = await model.findLatestEvents(databaseInput);\n\t\tassertInstallationRows(rows, databaseInput);\n\t\tconst last = rows.at(-1);\n\t\treturn {\n\t\t\tdata: rows.map(toInstallationRow),\n\t\t\tnextCursor: rows.length === limit && last ? encodeCursor({\n\t\t\t\tafterInstallId: last.install_id,\n\t\t\t\tkind: \"user-installations\",\n\t\t\t\tuserId,\n\t\t\t\tversion: 1\n\t\t\t}) : null\n\t\t};\n\t},\n\tasync getReportingOverview(input) {\n\t\tconst scope = readScope(input);\n\t\tconst { window } = input;\n\t\tif (!Object.hasOwn(WINDOW_MS, window)) throw new InsightsBadRequestError(\"Invalid reporting installation window.\");\n\t\tconst now = Date.now();\n\t\tconst beforeReceivedAtMs = now - now % HOUR_MS + (now % HOUR_MS === 0 ? 0 : HOUR_MS);\n\t\tconst reach = Math.max(0, beforeReceivedAtMs - WINDOW_MS[window]);\n\t\tconst sinceMs = reach - reach % DAY_MS;\n\t\tconst measure = async (count) => {\n\t\t\tconst value = await count;\n\t\t\tif (!Number.isSafeInteger(value) || value < 0) throw new Error(\"Insights database returned an invalid count.\");\n\t\t\treturn {\n\t\t\t\tcount: value,\n\t\t\t\tmeasuredAtMs: Date.now()\n\t\t\t};\n\t\t};\n\t\tconst bundleId = input.bundleId === void 0 ? void 0 : requireString(input.bundleId, \"bundle ID\", MAX_EVENT_ID_LENGTH);\n\t\tconst reporting = measure(model.countLatestEvents({\n\t\t\t...scope,\n\t\t\tsinceMs\n\t\t}));\n\t\tif (bundleId === void 0) return {\n\t\t\t...scope,\n\t\t\twindow,\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs,\n\t\t\treportingInstallations: await reporting\n\t\t};\n\t\tconst countOutcome = (outcome) => measure(model.countEvents({\n\t\t\tfilter: bundleFilter({\n\t\t\t\t...scope,\n\t\t\t\tbundleId,\n\t\t\t\toutcome\n\t\t\t}),\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs\n\t\t}));\n\t\tconst [reportingInstallations, bundleInstallations, downloadedReports, appliedReports, recoveredReports, failedReports] = await Promise.all([\n\t\t\treporting,\n\t\t\tmeasure(model.countLatestEvents({\n\t\t\t\t...scope,\n\t\t\t\tsinceMs,\n\t\t\t\tbundle: [{\n\t\t\t\t\tfield: \"from_bundle_id\",\n\t\t\t\t\tvalue: bundleId,\n\t\t\t\t\ttypes: [\"UPDATE_DOWNLOADED\"]\n\t\t\t\t}, {\n\t\t\t\t\tfield: \"to_bundle_id\",\n\t\t\t\t\tvalue: bundleId,\n\t\t\t\t\ttypes: [\n\t\t\t\t\t\t\"UNCHANGED\",\n\t\t\t\t\t\t\"UPDATE_APPLIED\",\n\t\t\t\t\t\t\"RECOVERED\"\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t})),\n\t\t\tcountOutcome(\"downloaded\"),\n\t\t\tcountOutcome(\"applied\"),\n\t\t\tcountOutcome(\"recovered\"),\n\t\t\tcountOutcome(\"failed\")\n\t\t]);\n\t\treturn {\n\t\t\t...scope,\n\t\t\twindow,\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs,\n\t\t\treportingInstallations,\n\t\t\tbundle: {\n\t\t\t\tbundleId,\n\t\t\t\treportingInstallations: bundleInstallations,\n\t\t\t\tdownloadedReports,\n\t\t\t\tappliedReports,\n\t\t\t\trecoveredReports,\n\t\t\t\tfailedReports\n\t\t\t}\n\t\t};\n\t}\n});\n//#endregion\nexport { EVENT_LIST_RANGE_MS, createInsightsProvider };\n", "import { isLateEvent, isLaunch } from \"./schema.mjs\";\n//#region src/server/overview.ts\nconst encodeIdentity = (identity) => [\n\tidentity.scopeKind,\n\tidentity.releaseKind,\n\tidentity.releaseId,\n\tidentity.channel,\n\tidentity.platform,\n\tidentity.appVersionKind,\n\tidentity.appVersion,\n\tidentity.periodKind,\n\tString(identity.bucketStartMs)\n].map((value) => `${new TextEncoder().encode(value).length}:${value}`).join(\"\");\nconst fnv = (value, seed) => {\n\tlet result = seed;\n\tfor (const byte of new TextEncoder().encode(value)) {\n\t\tresult ^= BigInt(byte);\n\t\tresult = BigInt.asUintN(64, result * 1099511628211n);\n\t}\n\treturn result.toString(16).padStart(16, \"0\");\n};\n/** A 128-bit hex key for a string: two FNV-1a 64 hashes with different seeds. */\nconst insightsKey = (value) => `${fnv(value, 14695981039346656037n)}${fnv(value, 9521211207457086692n)}`;\nconst insightsOverviewId = (identity) => insightsKey(encodeIdentity(identity));\nconst hour = (value) => Math.floor(value / 36e5) * 36e5;\nconst insightsOverviewDeltas = (event) => {\n\tconst bucketStartMs = hour(event.received_at_ms);\n\tconst counters = /* @__PURE__ */ new Map();\n\tconst append = (identity, values) => {\n\t\tconst key = encodeIdentity(identity);\n\t\tconst previous = counters.get(key);\n\t\tcounters.set(key, {\n\t\t\tidentity,\n\t\t\tdownloads: (previous?.downloads ?? 0) + values.downloads,\n\t\t\tapplies: (previous?.applies ?? 0) + values.applies,\n\t\t\tfailedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,\n\t\t\tactivityIdentity: previous?.activityIdentity ?? values.activityIdentity\n\t\t});\n\t};\n\tconst metric = (releaseId, values) => {\n\t\tconst windowed = {\n\t\t\t...values,\n\t\t\tapplies: 0\n\t\t};\n\t\tif (releaseId !== null) for (const [periodKind, start] of [[\"lifetime\", 0], [\"hour\", bucketStartMs]]) append({\n\t\t\tscopeKind: \"release\",\n\t\t\treleaseKind: \"specific\",\n\t\t\treleaseId,\n\t\t\tchannel: event.channel,\n\t\t\tplatform: event.platform,\n\t\t\tappVersionKind: \"all\",\n\t\t\tappVersion: \"\",\n\t\t\tperiodKind,\n\t\t\tbucketStartMs: start\n\t\t}, periodKind === \"lifetime\" ? values : windowed);\n\t\tappend({\n\t\t\tscopeKind: \"channel\",\n\t\t\treleaseKind: \"all\",\n\t\t\treleaseId: \"\",\n\t\t\tchannel: event.channel,\n\t\t\tplatform: event.platform,\n\t\t\tappVersionKind: \"all\",\n\t\t\tappVersion: \"\",\n\t\t\tperiodKind: \"hour\",\n\t\t\tbucketStartMs\n\t\t}, windowed);\n\t};\n\tconst implied = event.metadata.implied_download === true ? 1 : 0;\n\tif (!isLateEvent(event) && event.type === \"UPDATE_DOWNLOADED\") metric(event.to_release_id, {\n\t\tdownloads: 1,\n\t\tapplies: 0,\n\t\tfailedLaunches: 0\n\t});\n\telse if (!isLateEvent(event) && isLaunch(event)) metric(event.to_release_id, {\n\t\tdownloads: implied,\n\t\tapplies: 1,\n\t\tfailedLaunches: 0\n\t});\n\telse if (!isLateEvent(event) && event.type === \"RECOVERED\") metric(event.from_release_id, {\n\t\tdownloads: implied,\n\t\tapplies: 0,\n\t\tfailedLaunches: 1\n\t});\n\tfor (const platform of [event.platform, \"all\"]) for (const appVersionKind of [\"specific\", \"all\"]) append({\n\t\tscopeKind: \"usage\",\n\t\treleaseKind: \"all\",\n\t\treleaseId: \"\",\n\t\tchannel: event.channel,\n\t\tplatform,\n\t\tappVersionKind,\n\t\tappVersion: appVersionKind === \"specific\" ? event.app_version : \"\",\n\t\tperiodKind: \"hour\",\n\t\tbucketStartMs\n\t}, {\n\t\tdownloads: 0,\n\t\tapplies: 0,\n\t\tfailedLaunches: 0,\n\t\tactivityIdentity: event.install_id\n\t});\n\treturn [...counters.values()];\n};\n//#endregion\nexport { insightsKey, insightsOverviewDeltas, insightsOverviewId };\n", "import { runningBuiltinBundleId } from \"./eventRow.mjs\";\nimport { DAILY_EVENTS, DAY_MS, HOUR_MS, bundleRefOfFilter, bundleRefsOf, isLaunch } from \"./schema.mjs\";\nimport { assertBundleEventRow } from \"./contract.mjs\";\nimport { insightsKey, insightsOverviewDeltas, insightsOverviewId } from \"./overview.mjs\";\nimport { addDistinct, compareUtf8, extractTimestampFromUUIDv7, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/recordEvent.ts\nconst hourOf = (ms) => ms - ms % HOUR_MS;\nconst dayOf = (ms) => ms - ms % DAY_MS;\n/** The `identity` of an overview or sketch row: its scope and period, hashed. */\nconst insightsIdentity = (identity) => insightsOverviewId({\n\t...identity,\n\tscopeKind: identity.scopeKind,\n\tperiodKind: identity.periodKind,\n\tbucketStartMs: 0\n});\n/**\n* The bucket a head's gauges count it in, the UTC day of its event, and what\n* its distribution row names: the release it runs, which a download leaves\n* at its source, and the built-in bundle, when it runs the native build's.\n* A head stored without the built-in bundle ID counts in no built-in row, so\n* taking it back moves none.\n*/\nconst gaugeSlot = (head) => ({\n\tbucket: dayOf(head.received_at_ms),\n\treleaseId: head.type === \"UPDATE_DOWNLOADED\" ? head.from_release_id : head.to_release_id,\n\tbuiltinBundleId: runningBuiltinBundleId(head)\n});\n/**\n* The `insights_latest_by_bundle` field of a head's (from, to) pair. A head\n* matches a `from` and a `to` predicate of one type at once only through its\n* pair, so this gauge is what a count subtracts to count it once.\n*/\nconst PAIR_FIELD = \"from_to\";\n/** The pair gauge's `bundle_id`: a hash of the two bundle ids, which fit no single 36-character column. */\nconst bundlePairKey = (from, to) => insightsKey(`${from.length}:${from}${to.length}:${to}`);\n/**\n* Moves a head's gauges: the distribution row, and the built-in one when it\n* runs its build's built-in bundle, one row per bundle it references, and\n* its pair; -1 takes back the head an event replaces.\n*/\nconst countHead = (tx, head, delta) => {\n\tconst { bucket, releaseId, builtinBundleId } = gaugeSlot(head);\n\tconst shardBy = head.install_id;\n\ttx.aggregate(\"insights_distribution\", {\n\t\tchannel: head.channel,\n\t\tplatform: head.platform,\n\t\tapp_version: head.app_version,\n\t\trelease_id: releaseId ?? \"\",\n\t\tbucket_start_ms: bucket\n\t}, { latest_installations: delta }, { shardBy });\n\tif (builtinBundleId !== null) tx.aggregate(\"insights_builtin_distribution\", {\n\t\tchannel: head.channel,\n\t\tplatform: head.platform,\n\t\tapp_version: head.app_version,\n\t\trelease_id: releaseId ?? \"\",\n\t\tbuiltin_bundle_id: builtinBundleId,\n\t\tbucket_start_ms: bucket\n\t}, { latest_installations: delta }, { shardBy });\n\tfor (const field of [\"from_bundle_id\", \"to_bundle_id\"]) {\n\t\tconst bundleId = head[field];\n\t\tif (bundleId === null) continue;\n\t\ttx.aggregate(\"insights_latest_by_bundle\", {\n\t\t\tplatform: head.platform,\n\t\t\tchannel: head.channel,\n\t\t\tbundle_field: field,\n\t\t\tbundle_id: bundleId,\n\t\t\ttype: head.type,\n\t\t\tbucket_start_ms: bucket\n\t\t}, { installations: delta }, { shardBy });\n\t}\n\tif (head.from_bundle_id !== null) tx.aggregate(\"insights_latest_by_bundle\", {\n\t\tplatform: head.platform,\n\t\tchannel: head.channel,\n\t\tbundle_field: PAIR_FIELD,\n\t\tbundle_id: bundlePairKey(head.from_bundle_id, head.to_bundle_id),\n\t\ttype: head.type,\n\t\tbucket_start_ms: bucket\n\t}, { installations: delta }, { shardBy });\n};\n/**\n* Where each period's rows go, each with its retention: hours for 90 days,\n* days for 13 months, and a release's lifetime counters kept.\n*/\nconst PERIOD_MODELS = {\n\thour: {\n\t\tcounters: \"insights_overview\",\n\t\tsketches: \"insights_sketches\"\n\t},\n\tday: {\n\t\tcounters: \"insights_overview_daily\",\n\t\tsketches: \"insights_sketches_daily\"\n\t},\n\tlifetime: {\n\t\tcounters: \"insights_overview_lifetime\",\n\t\tsketches: void 0\n\t}\n};\n/** A download's patch counters: a patch delivered it, or it fell back from one. */\nconst patchCounters = (event) => event.type !== \"UPDATE_DOWNLOADED\" ? {} : {\n\t...event.metadata.delivery === \"patch\" ? { patch_downloads: 1 } : {},\n\t...event.metadata.patch_fallback === true ? { patch_fallbacks: 1 } : {}\n};\n/**\n* Counters and sketches for one event: release, channel, and usage rows, with\n* day rollups for channel and usage. Only usage rows keep a sketch, of active\n* installations, and only for the event's platform, since a read for every\n* platform merges the ios and android sketches. A download's patch counters\n* go in the rows that count it.\n*/\nconst countEvent = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tfor (const delta of insightsOverviewDeltas(event)) {\n\t\tif (delta.identity.platform === \"all\") continue;\n\t\tconst { bucketStartMs, ...parts } = delta.identity;\n\t\tconst periods = parts.scopeKind === \"channel\" || parts.scopeKind === \"usage\" ? [[\"hour\", bucketStartMs], [\"day\", dayOf(event.received_at_ms)]] : [[parts.periodKind, bucketStartMs]];\n\t\tfor (const [periodKind, bucket] of periods) {\n\t\t\tconst models = PERIOD_MODELS[periodKind];\n\t\t\tconst key = {\n\t\t\t\tidentity: insightsIdentity({\n\t\t\t\t\t...parts,\n\t\t\t\t\tperiodKind\n\t\t\t\t}),\n\t\t\t\tbucket_start_ms: bucket\n\t\t\t};\n\t\t\tconst counters = {\n\t\t\t\t...Object.fromEntries([\n\t\t\t\t\t[\"downloads\", delta.downloads],\n\t\t\t\t\t[\"applies\", delta.applies],\n\t\t\t\t\t[\"failed_launches\", delta.failedLaunches]\n\t\t\t\t].filter(([, value]) => value !== 0)),\n\t\t\t\t...delta.downloads === 0 ? {} : patchCounters(event)\n\t\t\t};\n\t\t\tif (Object.keys(counters).length > 0) tx.aggregate(models.counters, key, counters, { shardBy });\n\t\t\tif (models.sketches !== void 0 && delta.activityIdentity !== void 0) tx.aggregate(models.sketches, key, { activity_users: addDistinct(null, delta.activityIdentity) }, { shardBy });\n\t\t}\n\t}\n};\n/**\n* A stored event's outcome rows: its bundle filter's hour, when it has one\n* (`bundleRefsOf`), and every stored event's UTC day. A download that a\n* launch or crash implied counts in its bundle's download hour too, in the\n* hour of that launch or crash, so the download series covers what the\n* release's downloads count; the launch or crash is its row.\n*/\nconst countOutcome = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tconst hour = (type, bundleRef) => tx.aggregate(\"insights_outcomes\", {\n\t\tplatform: event.platform,\n\t\tchannel: event.channel,\n\t\ttype,\n\t\tbundle_ref: bundleRef,\n\t\tbucket_start_ms: hourOf(event.received_at_ms)\n\t}, { events: 1 }, { shardBy });\n\tfor (const bundleRef of bundleRefsOf(event)) hour(event.type, bundleRef);\n\tif (event.metadata.implied_download === true) hour(\"UPDATE_DOWNLOADED\", bundleRefOfFilter({\n\t\ttype: \"UPDATE_DOWNLOADED\",\n\t\ttoBundleId: event.type === \"RECOVERED\" ? event.from_bundle_id : event.to_bundle_id\n\t}));\n\ttx.aggregate(\"insights_outcomes\", {\n\t\t...DAILY_EVENTS,\n\t\tbucket_start_ms: dayOf(event.received_at_ms)\n\t}, { events: 1 }, { shardBy });\n};\n/** The row check requires an UPDATE_FAILED row's failure; its type leaves it optional. */\nconst UNKNOWN_FAILURE = {\n\tstage: \"unknown\",\n\treason: \"unknown\"\n};\n/** A failure's `detail`: what else the client knew, as a JSON array. */\nconst failureDetail = (failure) => JSON.stringify([\n\tfailure.resource ?? null,\n\tfailure.http_status ?? null,\n\tfailure.origin_code ?? null,\n\tfailure.transport ?? null\n]);\n/**\n* An update failure's sketches, breakdown row, and lifetime counter. Its\n* hourly breakdown row is what windowed reads sum, so no hourly or daily\n* counter repeats it. A failed check counts for its channel, in the `check`\n* sketch of installations. Any other failure counts in the channel's\n* `failure` sketch, and for its target release, when it names one, in the\n* release's hourly and lifetime `failure` sketches and its lifetime\n* `failed_updates`, which the bundle detail reads. A failure is no launch\n* and no activity: the installation reports its launch that day.\n*/\nconst countFailure = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tconst failure = event.metadata.failure ?? UNKNOWN_FAILURE;\n\tconst check = failure.stage === \"check\";\n\tconst hour = hourOf(event.received_at_ms);\n\tconst scope = {\n\t\tchannel: event.channel,\n\t\tplatform: event.platform,\n\t\tappVersionKind: \"all\",\n\t\tappVersion: \"\"\n\t};\n\tconst channel = {\n\t\t...scope,\n\t\treleaseKind: \"all\",\n\t\treleaseId: \"\"\n\t};\n\tconst users = { failed_users: addDistinct(null, event.install_id) };\n\tfor (const [periodKind, bucket] of [[\"hour\", hour], [\"day\", dayOf(event.received_at_ms)]]) {\n\t\tconst identity = insightsIdentity({\n\t\t\t...channel,\n\t\t\tscopeKind: check ? \"check\" : \"failure\",\n\t\t\tperiodKind\n\t\t});\n\t\ttx.aggregate(PERIOD_MODELS[periodKind].sketches, {\n\t\t\tidentity,\n\t\t\tbucket_start_ms: bucket\n\t\t}, users, { shardBy });\n\t}\n\tconst releaseId = check ? null : event.to_release_id;\n\tif (releaseId !== null) {\n\t\tconst release = {\n\t\t\t...scope,\n\t\t\treleaseKind: \"specific\",\n\t\t\treleaseId\n\t\t};\n\t\tfor (const [periodKind, bucket, sketches] of [[\n\t\t\t\"hour\",\n\t\t\thour,\n\t\t\t\"insights_sketches\"\n\t\t], [\n\t\t\t\"lifetime\",\n\t\t\t0,\n\t\t\t\"insights_sketches_lifetime\"\n\t\t]]) {\n\t\t\tconst key = (scopeKind) => ({\n\t\t\t\tidentity: insightsIdentity({\n\t\t\t\t\t...release,\n\t\t\t\t\tscopeKind,\n\t\t\t\t\tperiodKind\n\t\t\t\t}),\n\t\t\t\tbucket_start_ms: bucket\n\t\t\t});\n\t\t\ttx.aggregate(sketches, key(\"failure\"), users, { shardBy });\n\t\t}\n\t\ttx.aggregate(\"insights_overview_lifetime\", {\n\t\t\tidentity: insightsIdentity({\n\t\t\t\t...release,\n\t\t\t\tscopeKind: \"release\",\n\t\t\t\tperiodKind: \"lifetime\"\n\t\t\t}),\n\t\t\tbucket_start_ms: 0\n\t\t}, { failed_updates: 1 }, { shardBy });\n\t}\n\ttx.aggregate(\"insights_failures\", {\n\t\tplatform: event.platform,\n\t\tchannel: event.channel,\n\t\tbucket_start_ms: hour,\n\t\trelease_id: releaseId ?? \"\",\n\t\tstage: failure.stage,\n\t\treason: failure.reason,\n\t\tdetail: failureDetail(failure)\n\t}, { events: 1 }, { shardBy });\n};\nconst isNewer = (event, head) => event.received_at_ms !== head.received_at_ms ? event.received_at_ms > head.received_at_ms : compareUtf8(event.id, head.id) > 0;\n/** What a head says its installation runs: a download leaves it at the source. */\nconst runningOf = (head) => head.type === \"UPDATE_DOWNLOADED\" ? {\n\tbundle_id: head.from_bundle_id,\n\trelease_id: head.from_release_id\n} : {\n\tbundle_id: head.to_bundle_id,\n\trelease_id: head.to_release_id\n};\n/** The native build a report or head came from, when its SDK says. */\nconst minBundleIdOf = (row) => row.metadata?.min_bundle_id;\n/** When the client made a report, from the UUIDv7 it gave it. */\nconst madeAt = (id) => isUUIDv7(id) ? extractTimestampFromUUIDv7(id) : null;\n/**\n* A report its installation already moved past, which stays in history but\n* moves and counts nothing:\n* - a download or an apply of the bundle the head already runs, or a\n* download that repeats the head's pending one, from the same bundle to\n* the same bundle: the installation's download or launch already counted;\n* - an UNCHANGED report made, by its UUIDv7, before the head's report, even\n* after a later report replaced the apply it preceded: a reload can cut\n* one runtime's report short and deliver it after the next runtime's.\n*\n* Report IDs are made on the device, so a device whose clock jumps back has\n* its launch reports judged late until its clock passes its latest report.\n*/\nconst isLate = (event, head) => {\n\tif (head === null) return false;\n\tif (event.type === \"UPDATE_DOWNLOADED\" || event.type === \"UPDATE_APPLIED\") return event.to_bundle_id === runningOf(head).bundle_id || event.type === \"UPDATE_DOWNLOADED\" && head.type === \"UPDATE_DOWNLOADED\" && event.from_bundle_id === head.from_bundle_id && event.to_bundle_id === head.to_bundle_id;\n\tif (event.type === \"UNCHANGED\") {\n\t\tconst made = madeAt(event.id);\n\t\tconst latest = madeAt(head.id);\n\t\treturn made !== null && latest !== null && made < latest;\n\t}\n\treturn false;\n};\n/**\n* What an UNCHANGED report changes against its installation's head: the\n* running bundle or release, the app version, the channel, or the native\n* build (when both name it), with the head's values before it; `first_seen`\n* when the installation has no head. A report the head already answers, one\n* older than the head, a user switch and any other event type change\n* nothing, so no row keeps them.\n*/\nconst changeOf = (event, head) => {\n\tif (event.type !== \"UNCHANGED\") return null;\n\tif (head === null) return {\n\t\tkinds: [\"first_seen\"],\n\t\tprevious: null\n\t};\n\tif (!isNewer(event, head)) return null;\n\tconst running = runningOf(head);\n\tconst build = minBundleIdOf(event);\n\tconst headBuild = minBundleIdOf(head);\n\tconst kinds = [];\n\tif (event.to_bundle_id !== running.bundle_id) kinds.push(\"bundle\");\n\tif (event.to_release_id !== running.release_id) kinds.push(\"release\");\n\tif (event.app_version !== head.app_version) kinds.push(\"app_version\");\n\tif (event.channel !== head.channel) kinds.push(\"channel\");\n\tif (build !== void 0 && headBuild !== void 0 && build !== headBuild) kinds.push(\"native_build\");\n\treturn kinds.length === 0 ? null : {\n\t\tkinds,\n\t\tprevious: {\n\t\t\tbundle_id: running.bundle_id,\n\t\t\trelease_id: running.release_id,\n\t\t\tapp_version: head.app_version,\n\t\t\tchannel: head.channel,\n\t\t\t...headBuild === void 0 ? {} : { min_bundle_id: headBuild }\n\t\t}\n\t};\n};\n/**\n* Whether a launch or a crash comes with no download report for its target:\n* its head shows neither that download nor the target already running. The\n* native build's built-in bundle is never downloaded, and without a head the\n* server knows nothing of the installation's past, so it implies nothing.\n*/\nconst impliesDownload = (event, head) => {\n\tconst target = event.type === \"RECOVERED\" ? {\n\t\tbundle: event.from_bundle_id,\n\t\trelease: event.from_release_id\n\t} : isLaunch(event) ? {\n\t\tbundle: event.to_bundle_id,\n\t\trelease: event.to_release_id\n\t} : null;\n\tif (target === null || target.release === null || target.bundle === minBundleIdOf(event)) return false;\n\tif (head === null) return false;\n\tif (head.type === \"UPDATE_DOWNLOADED\" && head.to_bundle_id === target.bundle) return false;\n\treturn runningOf(head).bundle_id !== target.bundle;\n};\n/**\n* The event as recorded, with what only the server sets: what a kept\n* UNCHANGED report changed, a late report's flag, and a download its launch\n* or crash implied.\n*/\nconst recordedOf = (event, head) => {\n\tconst { change: _change, late: _late, implied_download: _implied, ...metadata } = event.metadata;\n\tconst reported = {\n\t\t...event,\n\t\tmetadata\n\t};\n\tconst late = isLate(reported, head);\n\tconst change = late ? null : changeOf(reported, head);\n\tconst withChange = change === null ? reported : {\n\t\t...reported,\n\t\tmetadata: {\n\t\t\t...metadata,\n\t\t\tchange\n\t\t}\n\t};\n\treturn {\n\t\trecorded: late && reported.type !== \"UNCHANGED\" ? {\n\t\t\t...reported,\n\t\t\tmetadata: {\n\t\t\t\t...metadata,\n\t\t\t\tlate: true\n\t\t\t}\n\t\t} : !late && impliesDownload(withChange, head) ? {\n\t\t\t...withChange,\n\t\t\tmetadata: {\n\t\t\t\t...withChange.metadata,\n\t\t\t\timplied_download: true\n\t\t\t}\n\t\t} : withChange,\n\t\tlate\n\t};\n};\n/** What an UNCHANGED report must share with its installation's head to repeat it. */\nconst REPEATED_FIELDS = [\n\t\"channel\",\n\t\"platform\",\n\t\"app_version\",\n\t\"to_bundle_id\",\n\t\"to_release_id\",\n\t\"user_id\"\n];\n/**\n* An UNCHANGED report that repeats its installation's head from the same UTC\n* day: the installation already counts as active that day, on that bundle,\n* so the report records nothing. A download's head does not count, because\n* its installation still ran the bundle it downloaded from.\n*/\nconst repeatsHead = (event, head) => event.type === \"UNCHANGED\" && head.type !== \"UPDATE_DOWNLOADED\" && dayOf(event.received_at_ms) === dayOf(head.received_at_ms) && REPEATED_FIELDS.every((field) => event[field] === head[field]);\n/**\n* Records one event in one transaction: one batch read of the event and its\n* installation's head, one of the gauge and sketch rows it changes, then one\n* write. On a database that batches aggregates (DynamoDB, Firestore), the\n* write holds the event's rows and one log row instead, and a compaction\n* reads and writes the aggregate rows. A stored event's id changes nothing\n* when repeated, whichever installation sends it, and neither does the id\n* of the installation's head. An UNCHANGED report that repeats its head on\n* the same UTC day writes nothing at all. An older event still counts in its\n* own hour but never replaces the head. An update failure is stored and\n* counted, but changes what no installation runs, so it moves no head.\n*/\nconst recordEvent = (db, event) => {\n\tassertBundleEventRow(event);\n\treturn db.transaction(async (tx) => {\n\t\tconst [existing, previous] = await Promise.all([tx.findOne(\"bundle_events\", { id: event.id }), tx.findOne(\"bundle_event_heads\", { install_id: event.install_id })]);\n\t\tif (existing !== null || previous?.id === event.id) return;\n\t\tif (previous !== null && repeatsHead(event, previous)) return;\n\t\tconst { recorded, late } = recordedOf(event, previous);\n\t\tif (recorded.type !== \"UNCHANGED\" || recorded.metadata.change !== void 0 && !late) {\n\t\t\ttx.create(\"bundle_events\", recorded);\n\t\t\tcountOutcome(tx, recorded);\n\t\t}\n\t\tif (recorded.type === \"UPDATE_FAILED\") {\n\t\t\tcountFailure(tx, recorded);\n\t\t\treturn;\n\t\t}\n\t\tcountEvent(tx, recorded);\n\t\tif (previous !== null && (late || !isNewer(recorded, previous))) return;\n\t\tif (previous === null) tx.create(\"bundle_event_heads\", recorded);\n\t\telse {\n\t\t\tconst { install_id: _, ...fields } = recorded;\n\t\t\tcountHead(tx, previous, -1);\n\t\t\ttx.update(\"bundle_event_heads\", previous, fields);\n\t\t}\n\t\tcountHead(tx, recorded, 1);\n\t});\n};\n//#endregion\nexport { PAIR_FIELD, bundlePairKey, insightsIdentity, recordEvent };\n", "import { DAILY_EVENTS, DAY_MS, HOUR_MS, bundleRefOfFilter } from \"./schema.mjs\";\nimport \"./provider.mjs\";\nimport { PAIR_FIELD, bundlePairKey, insightsIdentity } from \"./recordEvent.mjs\";\nimport { DatabaseAdapterInputError, compareUtf8, countDistinct, mergeDistinct } from \"@hot-updater/plugin-core\";\n//#region src/server/reads.ts\nconst PAGE = 500;\nconst hourFloor = (ms) => ms - ms % HOUR_MS;\nconst hourCeil = (ms) => hourFloor(ms + HOUR_MS - 1);\nconst dayFloor = (ms) => ms - ms % DAY_MS;\nconst dayCeil = (ms) => dayFloor(ms + DAY_MS - 1);\n/** Every page of one read, in order. */\nconst drain = async (read) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await read(cursor === void 0 ? {} : { cursor });\n\t\trows.push(...page.rows);\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\nconst EVENT_FIELDS = [\n\t\"id\",\n\t\"type\",\n\t\"install_id\",\n\t\"user_id\",\n\t\"from_release_id\",\n\t\"from_bundle_id\",\n\t\"to_release_id\",\n\t\"to_bundle_id\",\n\t\"platform\",\n\t\"app_version\",\n\t\"channel\",\n\t\"metadata\",\n\t\"received_at_ms\"\n];\n/** A stored event or head, as the event row it holds. */\nconst toEvent = (row) => Object.fromEntries(EVENT_FIELDS.map((field) => [field, row[field]]));\nconst scopeOf = (filter) => ({\n\tplatform: filter.platform,\n\tchannel: filter.channel,\n\ttype: filter.type,\n\tbundle_ref: bundleRefOfFilter(filter)\n});\n/** One UTC day of a global or bundle list, newest first. */\nconst eventsOfDay = (db, filter, day, range, limit) => filter.kind === \"all\" ? db.findMany(\"bundle_events\", {\n\tindex: \"byDay\",\n\twhere: { day },\n\trange,\n\torder: \"desc\",\n\tlimit\n}) : db.findMany(\"bundle_events\", {\n\tindex: \"byBundle\",\n\twhere: {\n\t\t...scopeOf(filter),\n\t\tday\n\t},\n\trange,\n\torder: \"desc\",\n\tlimit\n});\n/**\n* The newest UTC day before `day`, and not before `since`'s, that holds an\n* event the list matches, from one outcome row: the global list's per-day\n* count, or the bundle filter's own hourly one.\n*/\nconst newestDayBelow = async (db, filter, day, since) => {\n\tconst counted = filter.kind === \"all\" ? {\n\t\twhere: DAILY_EVENTS,\n\t\tfrom: dayFloor(since)\n\t} : {\n\t\twhere: scopeOf(filter),\n\t\tfrom: hourFloor(since)\n\t};\n\tconst [newest] = (await db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: counted.where,\n\t\trange: {\n\t\t\tgte: counted.from,\n\t\t\tlt: day\n\t\t},\n\t\torder: \"desc\",\n\t\tlimit: 1\n\t})).rows;\n\treturn newest === void 0 ? void 0 : dayFloor(newest.bucket_start_ms);\n};\n/**\n* Newest first over [since, before), after the cursor. The global and bundle\n* lists cover at most 90 \u00D7 24 hours, however many UTC days that touches, and\n* reject a longer range instead of cutting it short. They read one query per\n* UTC day that holds a matching event: a day that holds none is read once,\n* then one outcome row names the newest day below it that does, so a gap of\n* any length costs two reads.\n*/\nconst listEvents = async (db, input) => {\n\tconst since = input.sinceMs ?? 0;\n\tconst range = {\n\t\tgte: since,\n\t\tlt: input.after === void 0 ? input.beforeReceivedAtMs : [input.after.receivedAtMs, input.after.id]\n\t};\n\tconst { filter, limit } = input;\n\tif (filter.kind === \"installationMovement\") return (await db.findMany(\"bundle_events\", {\n\t\tindex: \"movementsByInstall\",\n\t\twhere: { movement_install_id: filter.installId },\n\t\trange,\n\t\torder: \"desc\",\n\t\tlimit\n\t})).rows.map(toEvent);\n\tif (input.beforeReceivedAtMs - since > 7776e6) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst rows = [];\n\tconst bottom = dayFloor(since);\n\tlet day = dayFloor(input.after?.receivedAtMs ?? input.beforeReceivedAtMs - 1);\n\twhile (day !== void 0 && day >= bottom && rows.length < limit) {\n\t\tconst page = await eventsOfDay(db, filter, day, range, limit - rows.length);\n\t\trows.push(...page.rows.map(toEvent));\n\t\tday = page.rows.length > 0 ? day - DAY_MS : day > bottom ? await newestDayBelow(db, filter, day, since) : void 0;\n\t}\n\treturn rows;\n};\n/** One point read for an installation; a user's installations in binary install id order. */\nconst findLatestEvents = async (db, input) => {\n\tif (\"installId\" in input) {\n\t\tconst head = await db.findOne(\"bundle_event_heads\", { install_id: input.installId });\n\t\treturn head === null ? [] : [toEvent(head)];\n\t}\n\treturn (await db.findMany(\"bundle_event_heads\", {\n\t\tindex: \"byUser\",\n\t\twhere: { user_id: input.userId },\n\t\t...input.afterInstallId === void 0 ? {} : { range: { gt: input.afterInstallId } },\n\t\torder: \"asc\",\n\t\tlimit: input.limit\n\t})).rows.map(toEvent);\n};\n/** Raw events of one bundle filter over [from, to), which spans at most two partial hours. */\nconst countRaw = async (db, filter, from, to) => {\n\tlet total = 0;\n\tfor (let day = dayFloor(from); from < to && day < to; day += DAY_MS) {\n\t\tconst rows = await drain((page) => db.findMany(\"bundle_events\", {\n\t\t\tindex: \"byBundle\",\n\t\t\twhere: {\n\t\t\t\t...scopeOf(filter),\n\t\t\t\tday\n\t\t\t},\n\t\t\trange: {\n\t\t\t\tgte: from,\n\t\t\t\tlt: to\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}));\n\t\ttotal += rows.length;\n\t}\n\treturn total;\n};\n/**\n* Whole hours from outcome counters; the partial hours at either edge from\n* raw events. A download filter's whole hours count the downloads a launch\n* or crash implied too, which its raw events do not hold.\n*/\nconst countEvents = async (db, input) => {\n\tconst { filter, sinceMs, beforeReceivedAtMs } = input;\n\tconst start = hourCeil(sinceMs);\n\tconst end = hourFloor(beforeReceivedAtMs);\n\tif (start >= end) return countRaw(db, filter, sinceMs, beforeReceivedAtMs);\n\tconst hours = await drain((page) => db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: scopeOf(filter),\n\t\trange: {\n\t\t\tgte: start,\n\t\t\tlt: end\n\t\t},\n\t\tlimit: PAGE,\n\t\t...page\n\t}));\n\treturn await countRaw(db, filter, sinceMs, start) + hours.reduce((sum, row) => sum + row.events, 0) + await countRaw(db, filter, end, beforeReceivedAtMs);\n};\n/**\n* A bundle filter's stored events in each interval of whole hours, and for a\n* download filter the downloads a launch or crash implied: one read of its\n* hourly counts, every interval present.\n*/\nconst countEventSeries = async (db, input) => {\n\tconst { filter, intervalMs } = input;\n\tconst { start, end } = input.timeRange;\n\tconst events = Array.from({ length: (end - start) / intervalMs }, () => 0);\n\tconst hours = await drain((page) => db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: scopeOf(filter),\n\t\trange: {\n\t\t\tgte: start,\n\t\t\tlt: end\n\t\t},\n\t\tlimit: PAGE,\n\t\t...page\n\t}));\n\tfor (const row of hours) events[Math.floor((row.bucket_start_ms - start) / intervalMs)] += row.events;\n\treturn events.map((count, index) => ({\n\t\tstartMs: start + index * intervalMs,\n\t\tevents: count\n\t}));\n};\n/** A bundle filter's distinct (field, value, type) predicates. */\nconst latestPredicates = (bundle) => {\n\tif (bundle === void 0) return void 0;\n\treturn [...new Map(bundle.flatMap(({ field, value, types }) => types.map((type) => [JSON.stringify([\n\t\tfield,\n\t\tvalue,\n\t\ttype\n\t]), {\n\t\tfield,\n\t\tvalue,\n\t\ttype\n\t}]))).values()];\n};\n/**\n* Latest events at or after `sinceMs`, a UTC day's start: the gauges count\n* each installation in the UTC day of its latest event, so they answer whole\n* days only, and a later start is rejected rather than rounded.\n*/\nconst countLatestEvents = async (db, input) => {\n\tconst { platform, channel, sinceMs: start } = input;\n\tif (start % 864e5 !== 0) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst predicates = latestPredicates(input.bundle);\n\tlet total = 0;\n\tif (predicates === void 0) {\n\t\tconst rows = await drain((page) => db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange: { gte: start },\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}));\n\t\ttotal += rows.reduce((sum, row) => sum + row.latest_installations, 0);\n\t} else {\n\t\tconst gauge = async (bundleField, bundleId, type) => {\n\t\t\treturn (await drain((page) => db.findAggregates(\"insights_latest_by_bundle\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: {\n\t\t\t\t\tplatform,\n\t\t\t\t\tchannel,\n\t\t\t\t\tbundle_field: bundleField,\n\t\t\t\t\tbundle_id: bundleId,\n\t\t\t\t\ttype\n\t\t\t\t},\n\t\t\t\trange: { gte: start },\n\t\t\t\tlimit: PAGE,\n\t\t\t\t...page\n\t\t\t}))).reduce((sum, row) => sum + row.installations, 0);\n\t\t};\n\t\tfor (const { field, value, type } of predicates) total += await gauge(field, value, type);\n\t\tfor (const from of predicates) {\n\t\t\tif (from.field !== \"from_bundle_id\") continue;\n\t\t\tfor (const to of predicates) {\n\t\t\t\tif (to.field !== \"to_bundle_id\" || to.type !== from.type) continue;\n\t\t\t\ttotal -= await gauge(PAIR_FIELD, bundlePairKey(from.value, to.value), from.type);\n\t\t\t}\n\t\t}\n\t}\n\treturn Math.max(0, total);\n};\n/** The oldest whole hour and UTC day that hourly and daily rows still hold. */\nconst retained = (now, { rawDays, dailyDays }) => ({\n\thour: hourCeil(now - rawDays * DAY_MS),\n\tday: dayCeil(now - dailyDays * DAY_MS)\n});\n/**\n* Whether the rows a window reads still hold all of it; an older start is\n* partial from `oldest`, the first bucket its rows keep.\n*/\nconst coverageOf = (start, oldest) => start >= oldest ? {\n\tkind: \"complete\",\n\tsinceMs: 0\n} : {\n\tkind: \"partial\",\n\tsinceMs: oldest\n};\n/**\n* Periods covering [start, end): whole UTC days when `days` and the window is\n* over 48 hours, hours elsewhere. Hourly rows start at `hour`, the raw\n* period ago, so with `days` an edge older than that reads its whole UTC day\n* from the daily rows.\n*/\nconst periodsOf = (range, days, hour) => {\n\tconst start = days && range.start < hour ? dayFloor(range.start) : range.start;\n\tconst end = days && range.end < hour ? dayCeil(range.end) : range.end;\n\tif (!days || end - start <= 1728e5 && start >= hour) return [{\n\t\tperiodKind: \"hour\",\n\t\tstart,\n\t\tend\n\t}];\n\tconst first = Math.min(end, dayCeil(start));\n\tconst last = Math.max(first, dayFloor(end));\n\treturn [\n\t\t{\n\t\t\tperiodKind: \"hour\",\n\t\t\tstart,\n\t\t\tend: first\n\t\t},\n\t\t{\n\t\t\tperiodKind: \"day\",\n\t\t\tstart: first,\n\t\t\tend: last\n\t\t},\n\t\t{\n\t\t\tperiodKind: \"hour\",\n\t\t\tstart: last,\n\t\t\tend\n\t\t}\n\t].filter((period) => period.start < period.end);\n};\n/** The hourly and daily aggregates of counters, and of sketches. */\nconst COUNTERS = {\n\thour: \"insights_overview\",\n\tday: \"insights_overview_daily\"\n};\nconst SKETCHES = {\n\thour: \"insights_sketches\",\n\tday: \"insights_sketches_daily\"\n};\n/** Every counter or sketch row of one identity over [start, end), mixing day and hour periods. */\nconst windowRows = async (db, models, parts, range, days, hour) => {\n\tconst rows = [];\n\tfor (const period of periodsOf(range, days, hour)) {\n\t\tconst identity = insightsIdentity({\n\t\t\t...parts,\n\t\t\tperiodKind: period.periodKind\n\t\t});\n\t\trows.push(...await drain((page) => db.findAggregates(models[period.periodKind], {\n\t\t\tindex: \"window\",\n\t\t\twhere: { identity },\n\t\t\trange: {\n\t\t\t\tgte: period.start,\n\t\t\t\tlt: period.end\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t}\n\treturn rows;\n};\nconst counterRows = (...[db, ...args]) => windowRows(db, COUNTERS, ...args);\nconst sketchRows = (...[db, ...args]) => windowRows(db, SKETCHES, ...args);\nconst releaseParts = (release) => ({\n\tscopeKind: \"release\",\n\treleaseKind: \"specific\",\n\treleaseId: release.releaseId,\n\tchannel: release.channel,\n\tplatform: release.platform,\n\tappVersionKind: \"all\",\n\tappVersion: \"\"\n});\n/** A release's lifetime counters: one logical row at bucket 0. */\nconst lifetimeMetrics = async (db, release) => {\n\tconst identity = insightsIdentity({\n\t\t...releaseParts(release),\n\t\tperiodKind: \"lifetime\"\n\t});\n\tconst [lifetime] = (await db.findAggregates(\"insights_overview_lifetime\", {\n\t\tindex: \"window\",\n\t\twhere: { identity },\n\t\trange: {\n\t\t\tgte: 0,\n\t\t\tlte: 0\n\t\t},\n\t\tlimit: PAGE\n\t})).rows;\n\treturn {\n\t\tdownloads: lifetime?.downloads ?? 0,\n\t\tapplies: lifetime?.applies ?? 0,\n\t\tfailedLaunches: lifetime?.failed_launches ?? 0\n\t};\n};\n/** A channel and platform's usage rows, of every app version or of one. */\nconst usageParts = (channel, platform, appVersion) => ({\n\tscopeKind: \"usage\",\n\treleaseKind: \"all\",\n\treleaseId: \"\",\n\tchannel,\n\tplatform,\n\tappVersionKind: appVersion === void 0 ? \"all\" : \"specific\",\n\tappVersion: appVersion ?? \"\"\n});\n/** Each release's lifetime counters, which are kept: one logical row apiece. */\nconst getReleaseActivity = async (db, input, now) => {\n\tconst measuredAtMs = now();\n\treturn {\n\t\tdata: await Promise.all(input.releases.map(async (release) => ({\n\t\t\trelease,\n\t\t\tmetrics: await lifetimeMetrics(db, release)\n\t\t}))),\n\t\tmeasuredAtMs\n\t};\n};\n/**\n* Entries with installations, most first. Batched gauges sum signed shard\n* rows, so a version or platform everyone left can read 0, and is left out.\n*/\nconst byInstallations = (values) => [...values].flatMap(([name, installations]) => installations > 0 ? [{\n\tname,\n\tinstallations\n}] : []).sort((left, right) => right.installations - left.installations || left.name.localeCompare(right.name, \"en\", { numeric: true }));\nconst getAppUsage = async (db, input, now, retention) => {\n\tconst { timeRange, intervalMs } = input;\n\tconst at = now();\n\tconst kept = retained(at, retention);\n\tconst days = intervalMs % 864e5 === 0 && timeRange.start % 864e5 === 0;\n\tconst reported = input.platform === \"all\" ? [\"ios\", \"android\"] : [input.platform];\n\tconst usage = (await Promise.all(reported.map((platform) => sketchRows(db, usageParts(input.channel, platform, input.appVersion), timeRange, days, kept.hour)))).flat();\n\tconst range = {\n\t\tgte: dayFloor(timeRange.start),\n\t\tlt: timeRange.end\n\t};\n\tconst distribution = [];\n\tconst builtinDistribution = [];\n\tfor (const platform of reported) {\n\t\tdistribution.push(...await drain((page) => input.appVersion === void 0 ? db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}) : db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byVersion\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform,\n\t\t\t\tapp_version: input.appVersion\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t\tbuiltinDistribution.push(...await drain((page) => input.appVersion === void 0 ? db.findAggregates(\"insights_builtin_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}) : db.findAggregates(\"insights_builtin_distribution\", {\n\t\t\tindex: \"byVersion\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform,\n\t\t\t\tapp_version: input.appVersion\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t}\n\tconst points = [];\n\tfor (let start = timeRange.start; start < timeRange.end; start += intervalMs) points.push({\n\t\tstartMs: start,\n\t\tinstallations: countDistinct(mergeDistinct(usage.filter((row) => row.bucket_start_ms >= start && row.bucket_start_ms < start + intervalMs).map((row) => row.activity_users)))\n\t});\n\tconst versions = /* @__PURE__ */ new Map();\n\tconst platforms = /* @__PURE__ */ new Map();\n\tconst bundles = /* @__PURE__ */ new Map();\n\tconst countBundle = (row, releaseId, builtinBundleId, count) => {\n\t\tconst key = JSON.stringify([\n\t\t\trow.app_version,\n\t\t\trow.platform,\n\t\t\treleaseId,\n\t\t\tbuiltinBundleId\n\t\t]);\n\t\tbundles.set(key, {\n\t\t\tappVersion: row.app_version,\n\t\t\tplatform: row.platform,\n\t\t\treleaseId,\n\t\t\tbuiltinBundleId,\n\t\t\tinstallations: (bundles.get(key)?.installations ?? 0) + count\n\t\t});\n\t};\n\tfor (const row of distribution) {\n\t\tconst count = row.latest_installations;\n\t\tversions.set(row.app_version, (versions.get(row.app_version) ?? 0) + count);\n\t\tplatforms.set(row.platform, (platforms.get(row.platform) ?? 0) + count);\n\t\tcountBundle(row, row.release_id || null, null, count);\n\t}\n\tfor (const row of builtinDistribution) {\n\t\tconst releaseId = row.release_id || null;\n\t\tcountBundle(row, releaseId, null, -row.latest_installations);\n\t\tcountBundle(row, releaseId, row.builtin_bundle_id, row.latest_installations);\n\t}\n\tconst sortedVersions = byInstallations(versions);\n\treturn {\n\t\tcoverage: coverageOf(timeRange.start, kept[days ? \"day\" : \"hour\"]),\n\t\tactiveInstallations: countDistinct(mergeDistinct(usage.map((row) => row.activity_users))),\n\t\tpoints,\n\t\tappVersions: sortedVersions.map(({ name }) => name),\n\t\tversions: sortedVersions,\n\t\tplatforms: byInstallations(platforms),\n\t\tbundleDistribution: [...bundles.values()].filter(({ installations }) => installations > 0),\n\t\tmeasuredAtMs: at\n\t};\n};\n/** The longest period the failures read covers: the console's longest, 30 days. */\nconst UPDATE_FAILURES_RANGE_MS = 30 * DAY_MS;\nconst isRange = (range) => range === void 0 || Number.isSafeInteger(range.start) && Number.isSafeInteger(range.end) && range.start >= 0 && range.start < range.end && range.end - range.start <= UPDATE_FAILURES_RANGE_MS;\nconst isText = (value, maxLength) => typeof value === \"string\" && value.length > 0 && value.length <= maxLength;\nconst failed = (...rows) => countDistinct(mergeDistinct(rows.flat().map((row) => row.failed_users)));\n/** Entries of a count map, most first, then in key order. */\nconst mostFirst = (counts) => [...counts].sort(([leftKey, left], [rightKey, right]) => right.events - left.events || compareUtf8(leftKey, rightKey)).map(([, entry]) => entry);\n/** The stages a failure row records: where an update failed. */\nconst FAILURE_STAGES = /* @__PURE__ */ new Set([\n\t\"check\",\n\t\"download\",\n\t\"install\",\n\t\"unknown\"\n]);\n/** Failure rows as their breakdown by stage, reason, and detail. */\nconst breakdownOf = (rows) => {\n\tconst failures = /* @__PURE__ */ new Map();\n\tfor (const { stage, reason, detail, events } of rows) {\n\t\tif (events <= 0) continue;\n\t\tconst key = JSON.stringify([stage, reason]);\n\t\tconst entry = failures.get(key) ?? {\n\t\t\tvalue: {\n\t\t\t\tstage,\n\t\t\t\treason\n\t\t\t},\n\t\t\tevents: 0,\n\t\t\tdetails: /* @__PURE__ */ new Map()\n\t\t};\n\t\tentry.events += events;\n\t\tconst known = entry.details.get(detail) ?? {\n\t\t\tvalue: detail,\n\t\t\tevents: 0\n\t\t};\n\t\tknown.events += events;\n\t\tentry.details.set(detail, known);\n\t\tfailures.set(key, entry);\n\t}\n\treturn mostFirst(failures).map(({ value, events }) => {\n\t\tconst { details } = failures.get(JSON.stringify([value.stage, value.reason]));\n\t\treturn {\n\t\t\t...value,\n\t\t\tevents,\n\t\t\tdetails: mostFirst(details).map(({ value: detail, events }) => {\n\t\t\t\tconst [resource, httpStatus, originCode, transport] = JSON.parse(detail);\n\t\t\t\treturn {\n\t\t\t\t\tresource,\n\t\t\t\t\thttpStatus,\n\t\t\t\t\toriginCode,\n\t\t\t\t\ttransport,\n\t\t\t\t\tevents\n\t\t\t\t};\n\t\t\t})\n\t\t};\n\t});\n};\n/**\n* A release's or a channel's update failures. Since a release's first\n* report: its lifetime counters and failed installations. Over a time range\n* of at most 30 days: failures, failed checks, and the breakdown by stage,\n* reason, and detail, all summed from the breakdown's hourly rows; downloads\n* from the counters; failed installations from their sketches. A release reads hourly rows, a\n* channel daily rows past 48 hours like its activity; the breakdown's rows\n* are hourly, so its coverage is the raw period's.\n*/\nconst getUpdateFailures = async (db, input, now, retention) => {\n\tconst { platform, channel, releaseId, timeRange } = input;\n\tif (platform !== \"ios\" && platform !== \"android\" || !isText(channel, 1024) || releaseId !== void 0 && !isText(releaseId, 36) || !isRange(timeRange) || releaseId === void 0 && timeRange === void 0) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst at = now();\n\tconst kept = retained(at, retention);\n\tconst channelParts = {\n\t\t...usageParts(channel, platform),\n\t\tscopeKind: \"channel\"\n\t};\n\tconst parts = releaseId === void 0 ? channelParts : releaseParts({\n\t\treleaseId,\n\t\tplatform,\n\t\tchannel\n\t});\n\tconst failure = {\n\t\t...parts,\n\t\tscopeKind: \"failure\"\n\t};\n\tif (timeRange === void 0) {\n\t\tconst where = (from) => ({ identity: insightsIdentity({\n\t\t\t...from,\n\t\t\tperiodKind: \"lifetime\"\n\t\t}) });\n\t\tconst [counters, sketches] = await Promise.all([db.findAggregates(\"insights_overview_lifetime\", {\n\t\t\tindex: \"window\",\n\t\t\twhere: where(parts),\n\t\t\trange: {\n\t\t\t\tgte: 0,\n\t\t\t\tlte: 0\n\t\t\t},\n\t\t\tlimit: PAGE\n\t\t}), db.findAggregates(\"insights_sketches_lifetime\", {\n\t\t\tindex: \"window\",\n\t\t\twhere: where(failure),\n\t\t\trange: {\n\t\t\t\tgte: 0,\n\t\t\t\tlte: 0\n\t\t\t},\n\t\t\tlimit: PAGE\n\t\t})]);\n\t\tconst lifetime = counters.rows[0];\n\t\treturn {\n\t\t\tcoverage: {\n\t\t\t\tkind: \"complete\",\n\t\t\t\tsinceMs: 0\n\t\t\t},\n\t\t\tmeasuredAtMs: at,\n\t\t\tfailedUpdates: lifetime?.failed_updates ?? 0,\n\t\t\tfailedInstallations: countDistinct(mergeDistinct(sketches.rows.map((row) => row.failed_users))),\n\t\t\tdownloads: lifetime?.downloads ?? 0,\n\t\t\tpatchDownloads: lifetime?.patch_downloads ?? 0,\n\t\t\tpatchFallbacks: lifetime?.patch_fallbacks ?? 0\n\t\t};\n\t}\n\tconst days = releaseId === void 0;\n\tconst window = [\n\t\ttimeRange,\n\t\tdays,\n\t\tkept.hour\n\t];\n\tconst [counters, failures, checks, active, rows] = await Promise.all([\n\t\tcounterRows(db, parts, ...window),\n\t\tsketchRows(db, failure, ...window),\n\t\tdays ? sketchRows(db, {\n\t\t\t...channelParts,\n\t\t\tscopeKind: \"check\"\n\t\t}, ...window) : [],\n\t\tdays ? sketchRows(db, usageParts(channel, platform), ...window) : [],\n\t\tdrain((page) => db.findAggregates(\"insights_failures\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tplatform,\n\t\t\t\tchannel\n\t\t\t},\n\t\t\trange: {\n\t\t\t\tgte: timeRange.start,\n\t\t\t\tlt: timeRange.end\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}))\n\t]);\n\tconst total = (field) => counters.reduce((sum, row) => sum + row[field], 0);\n\tconst scoped = rows.filter((row) => FAILURE_STAGES.has(row.stage) && (releaseId === void 0 || row.release_id === releaseId));\n\tconst failuresAt = (counted) => scoped.reduce((sum, row) => sum + (counted(row.stage) ? Math.max(0, row.events) : 0), 0);\n\treturn {\n\t\tcoverage: coverageOf(timeRange.start, kept.hour),\n\t\tmeasuredAtMs: at,\n\t\tfailedUpdates: failuresAt((stage) => stage !== \"check\"),\n\t\tfailedInstallations: failed(failures),\n\t\tdownloads: total(\"downloads\"),\n\t\tpatchDownloads: total(\"patch_downloads\"),\n\t\tpatchFallbacks: total(\"patch_fallbacks\"),\n\t\t...days ? { checks: {\n\t\t\tfailures: failuresAt((stage) => stage === \"check\"),\n\t\t\tfailedInstallations: failed(checks),\n\t\t\tactiveInstallations: countDistinct(mergeDistinct(active.map((row) => row.activity_users)))\n\t\t} } : {},\n\t\tbreakdown: breakdownOf(scoped)\n\t};\n};\n//#endregion\nexport { UPDATE_FAILURES_RANGE_MS, countEventSeries, countEvents, countLatestEvents, findLatestEvents, getAppUsage, getReleaseActivity, getUpdateFailures, listEvents };\n", "import { InsightsBadRequestError } from \"./errors.mjs\";\n//#region src/server/queryInput.ts\nconst MAX_PAGE_LIMIT = 100;\nconst MAX_IDENTITY_LENGTH = 255;\nconst MAX_CURSOR_LENGTH = 8192;\nconst readSingle = (url, key) => {\n\tconst values = url.searchParams.getAll(key);\n\tif (values.length > 1) throw new InsightsBadRequestError(`Duplicate '${key}' query parameter.`);\n\treturn values[0];\n};\nconst readPageLimit = (url) => {\n\tconst value = readSingle(url, \"limit\");\n\tif (value === void 0) return void 0;\n\tconst limit = Number(value);\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_PAGE_LIMIT) throw new InsightsBadRequestError(\"Invalid 'limit' query parameter.\");\n\treturn limit;\n};\nconst readCursor = (url) => {\n\tconst cursor = readSingle(url, \"cursor\");\n\tif (cursor !== void 0 && (cursor.length === 0 || cursor.length > MAX_CURSOR_LENGTH)) throw new InsightsBadRequestError(\"Invalid 'cursor' query parameter.\");\n\treturn cursor;\n};\nconst readId = (url, key, maximumLength = MAX_IDENTITY_LENGTH) => {\n\tconst value = readSingle(url, key);\n\tif (value === void 0 || value.length === 0 || value.length > maximumLength) throw new InsightsBadRequestError(`Invalid '${key}' query parameter.`);\n\treturn value;\n};\nconst readTimestamp = (url, key) => {\n\tconst raw = readSingle(url, key);\n\tif (raw === void 0) return void 0;\n\tconst value = Number(raw);\n\tif (!raw.length || !Number.isSafeInteger(value) || value < 0) throw new InsightsBadRequestError(`Invalid '${key}' query parameter.`);\n\treturn value;\n};\nconst readScope = (url) => {\n\tconst platform = readSingle(url, \"platform\");\n\tif (platform !== \"ios\" && platform !== \"android\") throw new InsightsBadRequestError(\"Invalid 'platform' query parameter.\");\n\treturn {\n\t\tplatform,\n\t\tchannel: readId(url, \"channel\", 1024)\n\t};\n};\nconst parseEventPageInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst bundleFields = [\n\t\t\"bundleId\",\n\t\t\"outcome\",\n\t\t\"platform\",\n\t\t\"channel\"\n\t];\n\tlet bundle;\n\tif (bundleFields.some((key) => url.searchParams.has(key))) {\n\t\tconst outcome = readSingle(url, \"outcome\");\n\t\tif (outcome !== \"downloaded\" && outcome !== \"applied\" && outcome !== \"recovered\" && outcome !== \"failed\") throw new InsightsBadRequestError(\"Invalid 'outcome' query parameter.\");\n\t\tbundle = {\n\t\t\t...readScope(url),\n\t\t\tbundleId: readId(url, \"bundleId\", 1024),\n\t\t\toutcome\n\t\t};\n\t}\n\treturn {\n\t\tbeforeReceivedAtMs: readTimestamp(url, \"beforeReceivedAtMs\"),\n\t\tsinceMs: readTimestamp(url, \"sinceMs\"),\n\t\tcursor: readCursor(url),\n\t\tlimit: readPageLimit(url),\n\t\t...bundle === void 0 ? {} : { bundle }\n\t};\n};\nconst parseUserInstallationPageInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst cursor = readCursor(url);\n\tconst limit = readPageLimit(url);\n\treturn {\n\t\tuserId: readId(url, \"userId\"),\n\t\t...cursor === void 0 ? {} : { cursor },\n\t\t...limit === void 0 ? {} : { limit }\n\t};\n};\nconst parseReportingOverviewInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst window = readSingle(url, \"window\") ?? \"30d\";\n\tif (window !== \"24h\" && window !== \"7d\" && window !== \"30d\") throw new InsightsBadRequestError(\"Invalid 'window' query parameter.\");\n\tconst bundleId = readSingle(url, \"bundleId\");\n\treturn {\n\t\t...readScope(url),\n\t\twindow,\n\t\t...bundleId === void 0 ? {} : { bundleId: readId(url, \"bundleId\", 1024) }\n\t};\n};\n//#endregion\nexport { parseEventPageInput, parseReportingOverviewInput, parseUserInstallationPageInput };\n", "import { InsightsBadRequestError, InsightsPayloadTooLargeError } from \"./errors.mjs\";\nimport { parseBundleEventRequest } from \"./eventInput.mjs\";\nimport { parseEventPageInput, parseReportingOverviewInput, parseUserInstallationPageInput } from \"./queryInput.mjs\";\nimport { isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/routes.ts\n/** Seconds a client waits before it resends a request the busy database refused. */\nconst RETRY_AFTER_SECONDS = 5;\nconst json = (body, status, headers = {}) => Response.json(body, {\n\theaders: {\n\t\t\"cache-control\": \"private, no-store\",\n\t\t...headers\n\t},\n\tstatus\n});\nconst requireParam = (params, key) => {\n\tconst value = params[key];\n\tif (value === void 0 || value.length === 0) throw new InsightsBadRequestError(`Missing route parameter: ${key}`);\n\ttry {\n\t\treturn decodeURIComponent(value);\n\t} catch {\n\t\tthrow new InsightsBadRequestError(`Invalid route parameter: ${key}`);\n\t}\n};\nconst run = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof InsightsBadRequestError) return json({ error: error.message }, 400);\n\t\tif (error instanceof InsightsPayloadTooLargeError) return json({ error: error.message }, 413);\n\t\tif (isDatabaseBusyError(error)) {\n\t\t\tconsole.warn(\"[hot-updater] Insights answered 503: the database is busy.\", error);\n\t\t\treturn json({ error: \"Service unavailable\" }, 503, { \"retry-after\": String(RETRY_AFTER_SECONDS) });\n\t\t}\n\t\tthrow error;\n\t}\n};\nconst query = (operation) => run(async () => json(await operation(), 200));\n/** Every Insights route: where it mounts, and the handler it runs. */\nconst INSIGHTS_ROUTES = [\n\t{\n\t\taccess: \"client\",\n\t\tmethod: \"POST\",\n\t\tpath: \"/events\",\n\t\thandler: \"appendBundleEvent\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/events\",\n\t\thandler: \"listEvents\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/overview\",\n\t\thandler: \"getReportingOverview\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations\",\n\t\thandler: \"pageInstallationsByCurrentUserId\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations/:installId/events\",\n\t\thandler: \"listInstallationEvents\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations/:installId\",\n\t\thandler: \"getInstallation\"\n\t}\n];\nconst createInsightsRouteHandlers = (provider) => ({\n\tappendBundleEvent: async (_params, request) => run(async () => {\n\t\tawait provider.appendBundleEvent(await parseBundleEventRequest(request));\n\t\treturn new Response(null, { status: 204 });\n\t}),\n\tgetReportingOverview: (_params, request) => query(() => provider.getReportingOverview(parseReportingOverviewInput(request))),\n\tgetInstallation: (params) => run(async () => {\n\t\tconst installation = await provider.getInstallation({ installId: requireParam(params, \"installId\") });\n\t\treturn installation === null ? json({ error: \"Installation not found\" }, 404) : json(installation, 200);\n\t}),\n\tlistEvents: (_params, request) => query(() => provider.listEvents(parseEventPageInput(request))),\n\tlistInstallationEvents: (params, request) => query(() => provider.listInstallationEvents({\n\t\t...parseEventPageInput(request),\n\t\tinstallId: requireParam(params, \"installId\")\n\t})),\n\tpageInstallationsByCurrentUserId: (_params, request) => query(() => provider.pageInstallationsByCurrentUserId(parseUserInstallationPageInput(request)))\n});\n//#endregion\nexport { INSIGHTS_ROUTES, createInsightsRouteHandlers };\n", "import { DEFAULT_INSIGHTS_RETENTION, createInsightsSchema, insightsSchema } from \"./schema.mjs\";\nimport { createInsightsModel } from \"./model.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { InsightsBadRequestError } from \"./errors.mjs\";\nimport { createInsightsProvider } from \"./provider.mjs\";\nimport { insightsIdentity, recordEvent } from \"./recordEvent.mjs\";\nimport { countEventSeries, countEvents, countLatestEvents, findLatestEvents, getAppUsage, getReleaseActivity, getUpdateFailures, listEvents } from \"./reads.mjs\";\nimport { INSIGHTS_ROUTES, createInsightsRouteHandlers } from \"./routes.mjs\";\nimport { createInsightsAdminReads, createInsightsReads } from \"./adminReads.mjs\";\nimport { DatabaseAdapterInputError, HotUpdaterConfigError, definePlugin, isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\nconst createInsightsApi = (db, now, retention) => ({\n\t/** How long this plugin keeps its rows. */\n\tretention,\n\t/** Records one validated event row; a repeated id changes nothing. */\n\trecordEvent: (event) => recordEvent(db, event),\n\tlistEvents: (input) => listEvents(db, input),\n\tfindLatestEvents: (input) => findLatestEvents(db, input),\n\tcountLatestEvents: (input) => countLatestEvents(db, input),\n\tcountEvents: (input) => countEvents(db, input),\n\tcountEventSeries: (input) => countEventSeries(db, input),\n\tgetReleaseActivity: (input) => getReleaseActivity(db, input, now),\n\tgetAppUsage: (input) => getAppUsage(db, input, now, retention),\n\t/** A release's or a channel's update failures, and their breakdown over a time range. */\n\tgetUpdateFailures: (input) => getUpdateFailures(db, input, now, retention)\n});\n/** `GET /failures`'s query: a scope, an optional release, and a time range or none. */\nconst readFailuresQuery = (url) => {\n\tconst query = url.searchParams;\n\tconst time = (name) => {\n\t\tconst value = query.get(name);\n\t\treturn value === null ? void 0 : Number(value);\n\t};\n\tconst [start, end] = [time(\"start\"), time(\"end\")];\n\tconst platform = query.get(\"platform\");\n\tconst releaseId = query.get(\"releaseId\");\n\tif (platform !== \"ios\" && platform !== \"android\" || start === void 0 !== (end === void 0)) throw new DatabaseAdapterInputError(\"invalid-query\");\n\treturn {\n\t\tplatform,\n\t\tchannel: query.get(\"channel\") ?? \"\",\n\t\t...releaseId === null ? {} : { releaseId },\n\t\t...start === void 0 ? {} : { timeRange: {\n\t\t\tstart,\n\t\t\tend\n\t\t} }\n\t};\n};\n/**\n* The admin route of the update failures read: a release's (`releaseId`)\n* since its first report, or over `start`\u2013`end`, or a channel's over a range,\n* which covers at most 30 days.\n*/\nconst failuresEndpoint = (api) => ({\n\taccess: \"admin\",\n\tmethod: \"GET\",\n\tpath: \"/failures\",\n\thandler: async (request) => {\n\t\ttry {\n\t\t\treturn Response.json(await api.getUpdateFailures(readFailuresQuery(new URL(request.url))), { headers: { \"cache-control\": \"private, no-store\" } });\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseAdapterInputError) return Response.json({ error: \"Send platform and channel, and releaseId or start and end in epoch milliseconds, at most 30 days apart.\" }, { status: 400 });\n\t\t\tif (!isDatabaseBusyError(error)) throw error;\n\t\t\treturn Response.json({ error: \"Service unavailable\" }, {\n\t\t\t\tstatus: 503,\n\t\t\t\theaders: { \"retry-after\": \"5\" }\n\t\t\t});\n\t\t}\n\t}\n});\nconst retentionOf = ({ retention }) => {\n\tconst rawDays = retention?.rawDays ?? 90;\n\tconst dailyDays = retention?.dailyDays ?? 400;\n\tconst whole = (days) => Number.isSafeInteger(days) && days >= 1;\n\tif (!whole(rawDays) || !whole(dailyDays) || dailyDays < rawDays) throw new HotUpdaterConfigError(`insights({ retention }) takes whole days of at least 1, with dailyDays at least rawDays; got rawDays ${rawDays} and dailyDays ${dailyDays}.`);\n\treturn {\n\t\trawDays,\n\t\tdailyDays\n\t};\n};\n/**\n* Insights: bundle lifecycle events and update failures, each\n* installation's latest event, and the counters, gauges, and sketches its\n* reads come from, each kept for its retention. It serves `POST /events` to\n* clients, and the Insights reads, update failures, and retention to admins.\n*/\nconst insights = (options = {}) => {\n\tconst retention = retentionOf(options);\n\tconst plugin = definePlugin({\n\t\tid: \"insights\",\n\t\tnamespace: false,\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: createInsightsSchema(retention),\n\t\tinit: ({ db, now }) => {\n\t\t\tconst api = createInsightsApi(db, now, retention);\n\t\t\tconst routes = createInsightsRouteHandlers(createInsightsProvider(createInsightsModel(api)));\n\t\t\treturn {\n\t\t\t\tapi,\n\t\t\t\tendpoints: [\n\t\t\t\t\t...INSIGHTS_ROUTES.map(({ access, method, path, handler }) => ({\n\t\t\t\t\t\taccess,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\thandler: (request, params) => routes[handler](params, request)\n\t\t\t\t\t})),\n\t\t\t\t\tfailuresEndpoint(api),\n\t\t\t\t\t{\n\t\t\t\t\t\taccess: \"admin\",\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\tpath: \"/retention\",\n\t\t\t\t\t\thandler: async () => Response.json(retention)\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t};\n\t\t},\n\t\tcli: { clientPlugin: {\n\t\t\tmodule: \"@hot-updater/react-native\",\n\t\t\tname: \"insights\"\n\t\t} }\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { DEFAULT_INSIGHTS_RETENTION, InsightsBadRequestError, createInsightsAdminReads, createInsightsModel, createInsightsProvider, createInsightsReads, createInsightsSchema, insights, insightsIdentity, insightsSchema };\n", "//#region src/shared/ownEntry.ts\n/**\n* A record's own entry. Parameter keys and condition names come from users,\n* so `constructor` or `__proto__` must name theirs, never Object.prototype's.\n*/\nconst ownEntry = (record, key) => record !== void 0 && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : void 0;\n//#endregion\nexport { ownEntry };\n", "import { ownEntry } from \"../shared/ownEntry.mjs\";\nimport { semverSatisfies } from \"@hot-updater/plugin-core\";\nimport { getNumericCohortRolloutPosition, getNumericCohortValue, isValidCohort, normalizeCohortValue } from \"@hot-updater/protocol\";\nimport { isValidRange } from \"verkit\";\n//#region src/server/template.ts\nconst EMPTY_REMOTE_CONFIG_TEMPLATE = Object.freeze({\n\tconditions: Object.freeze([]),\n\tparameters: Object.freeze({})\n});\n/**\n* A template's JSON stays under this many characters, so a device's values\n* always fit the 64 KB a client plugin may store under one key.\n*/\nconst REMOTE_CONFIG_MAX_TEMPLATE_LENGTH = 6e4;\nconst REMOTE_CONFIG_MAX_PARAMETERS = 2e3;\nconst REMOTE_CONFIG_MAX_CONDITIONS = 500;\nconst MAX_RULE_VALUES = 100;\nconst MAX_DESCRIPTION_LENGTH = 256;\nconst MAX_CONDITION_NAME_LENGTH = 100;\nconst MAX_RULE_TEXT_LENGTH = 128;\nconst PARAMETER_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,255}$/u;\nconst SEED_PATTERN = /^[A-Za-z0-9_-]{1,64}$/u;\n/** A date-time with its time zone, so it names one instant. */\nconst DATE_TIME_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,3})?)?(?:Z|[+-]\\d{2}:\\d{2})$/u;\nconst VALUE_TYPES = /* @__PURE__ */ new Set([\n\t\"STRING\",\n\t\"NUMBER\",\n\t\"BOOLEAN\",\n\t\"JSON\"\n]);\nconst PLATFORMS = /* @__PURE__ */ new Set([\"ios\", \"android\"]);\n/** A template that cannot be published; `issues` lists every problem found. */\nvar RemoteConfigValidationError = class extends Error {\n\tissues;\n\tname = \"RemoteConfigValidationError\";\n\tconstructor(issues) {\n\t\tsuper(`The Remote Config template is invalid: ${issues.slice(0, 3).map(({ path, message }) => path ? `${path}: ${message}` : message).join(\"; \")}${issues.length > 3 ? ` (and ${issues.length - 3} more)` : \"\"}`);\n\t\tthis.issues = issues;\n\t}\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst visibleText = (value, max) => typeof value === \"string\" && value.trim().length > 0 && value.length <= max && !/[\\p{Cc}]/u.test(value);\n/** Whether a value's text suits its type; the problem otherwise. */\nconst checkValueText = (valueType, text) => {\n\tswitch (valueType) {\n\t\tcase \"NUMBER\": return text.trim().length > 0 && Number.isFinite(Number(text)) ? null : \"must be a number.\";\n\t\tcase \"BOOLEAN\": return text === \"true\" || text === \"false\" ? null : \"must be \\\"true\\\" or \\\"false\\\".\";\n\t\tcase \"JSON\": try {\n\t\t\tJSON.parse(text);\n\t\t\treturn null;\n\t\t} catch {\n\t\t\treturn \"must be valid JSON.\";\n\t\t}\n\t\tdefault: return null;\n\t}\n};\n/**\n* Checks a template and returns it with only its declared fields, or throws\n* `RemoteConfigValidationError` with every problem it finds.\n*/\nconst validateRemoteConfigTemplate = (input) => {\n\tconst issues = [];\n\tconst issue = (path, message) => {\n\t\tissues.push({\n\t\t\tpath,\n\t\t\tmessage\n\t\t});\n\t};\n\tconst unknownKeys = (value, allowed, path) => {\n\t\tfor (const key of Object.keys(value)) if (!allowed.includes(key)) issue(path ? `${path}.${key}` : key, \"is not a template field.\");\n\t};\n\tif (!isRecord(input)) throw new RemoteConfigValidationError([{\n\t\tpath: \"\",\n\t\tmessage: \"A template is an object.\"\n\t}]);\n\tunknownKeys(input, [\"conditions\", \"parameters\"], \"\");\n\tconst conditions = [];\n\tconst conditionNames = /* @__PURE__ */ new Set();\n\tconst rawConditions = input.conditions ?? [];\n\tif (!Array.isArray(rawConditions)) issue(\"conditions\", \"must be a list.\");\n\telse {\n\t\tif (rawConditions.length > 500) issue(\"conditions\", `holds at most 500 conditions.`);\n\t\trawConditions.forEach((raw, index) => {\n\t\t\tconst path = `conditions[${index}]`;\n\t\t\tif (!isRecord(raw)) {\n\t\t\t\tissue(path, \"must be an object.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tunknownKeys(raw, [\"name\", \"rules\"], path);\n\t\t\tconst { name } = raw;\n\t\t\tif (!visibleText(name, MAX_CONDITION_NAME_LENGTH)) issue(`${path}.name`, `must be 1-${MAX_CONDITION_NAME_LENGTH} visible characters.`);\n\t\t\telse if (conditionNames.has(name)) issue(`${path}.name`, `\"${name}\" names another condition too.`);\n\t\t\telse conditionNames.add(name);\n\t\t\tconst rules = validateRules(raw.rules, `${path}.rules`, issue);\n\t\t\tif (typeof name === \"string\") conditions.push({\n\t\t\t\tname,\n\t\t\t\trules\n\t\t\t});\n\t\t});\n\t}\n\tconst parameters = [];\n\tconst rawParameters = input.parameters ?? {};\n\tif (!isRecord(rawParameters)) issue(\"parameters\", \"must be an object keyed by parameter.\");\n\telse {\n\t\tconst keys = Object.keys(rawParameters);\n\t\tif (keys.length > 2e3) issue(\"parameters\", `holds at most ${REMOTE_CONFIG_MAX_PARAMETERS} parameters.`);\n\t\tfor (const key of keys) {\n\t\t\tconst path = `parameters.${key}`;\n\t\t\tif (!PARAMETER_KEY_PATTERN.test(key)) issue(path, \"Parameter keys start with a letter or _, and hold up to 256 letters, digits, and _.\");\n\t\t\tconst raw = rawParameters[key];\n\t\t\tif (!isRecord(raw)) {\n\t\t\t\tissue(path, \"must be an object.\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tunknownKeys(raw, [\n\t\t\t\t\"valueType\",\n\t\t\t\t\"defaultValue\",\n\t\t\t\t\"conditionalValues\",\n\t\t\t\t\"description\"\n\t\t\t], path);\n\t\t\tconst valueType = raw.valueType;\n\t\t\tif (typeof valueType !== \"string\" || !VALUE_TYPES.has(valueType)) {\n\t\t\t\tissue(`${path}.valueType`, \"must be STRING, NUMBER, BOOLEAN, or JSON.\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst type = valueType;\n\t\t\tconst readValue = (value, valuePath) => {\n\t\t\t\tif (!isRecord(value)) {\n\t\t\t\t\tissue(valuePath, \"must be { value } or { useInAppDefault: true }.\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (\"useInAppDefault\" in value) {\n\t\t\t\t\tunknownKeys(value, [\"useInAppDefault\"], valuePath);\n\t\t\t\t\tif (value.useInAppDefault !== true) {\n\t\t\t\t\t\tissue(`${valuePath}.useInAppDefault`, \"must be true.\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn { useInAppDefault: true };\n\t\t\t\t}\n\t\t\t\tunknownKeys(value, [\"value\"], valuePath);\n\t\t\t\tif (typeof value.value !== \"string\") {\n\t\t\t\t\tissue(`${valuePath}.value`, \"must be text.\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst problem = checkValueText(type, value.value);\n\t\t\t\tif (problem !== null) {\n\t\t\t\t\tissue(`${valuePath}.value`, problem);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn { value: value.value };\n\t\t\t};\n\t\t\tconst defaultValue = readValue(raw.defaultValue, `${path}.defaultValue`);\n\t\t\tconst conditionalValues = [];\n\t\t\tif (raw.conditionalValues !== void 0) {\n\t\t\t\tif (!isRecord(raw.conditionalValues)) issue(`${path}.conditionalValues`, \"must be an object keyed by condition.\");\n\t\t\t\telse for (const [conditionName, value] of Object.entries(raw.conditionalValues)) {\n\t\t\t\t\tconst valuePath = `${path}.conditionalValues.${conditionName}`;\n\t\t\t\t\tif (!conditionNames.has(conditionName)) {\n\t\t\t\t\t\tissue(valuePath, `No condition is named \"${conditionName}\".`);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst read = readValue(value, valuePath);\n\t\t\t\t\tif (read !== null) conditionalValues.push([conditionName, read]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet description;\n\t\t\tif (raw.description !== void 0) {\n\t\t\t\tconst text = typeof raw.description === \"string\" ? raw.description.trim() : null;\n\t\t\t\tif (text === null || text.length > MAX_DESCRIPTION_LENGTH) issue(`${path}.description`, `must be text of up to ${MAX_DESCRIPTION_LENGTH} characters.`);\n\t\t\t\telse if (text.length > 0) description = text;\n\t\t\t}\n\t\t\tif (defaultValue !== null) parameters.push([key, {\n\t\t\t\tvalueType: type,\n\t\t\t\tdefaultValue,\n\t\t\t\t...conditionalValues.length === 0 ? {} : { conditionalValues: Object.fromEntries(conditionalValues) },\n\t\t\t\t...description === void 0 ? {} : { description }\n\t\t\t}]);\n\t\t}\n\t}\n\tif (issues.length > 0) throw new RemoteConfigValidationError(issues);\n\tconst template = {\n\t\tconditions,\n\t\tparameters: Object.fromEntries(parameters)\n\t};\n\tconst length = JSON.stringify(template).length;\n\tif (length > 6e4) throw new RemoteConfigValidationError([{\n\t\tpath: \"\",\n\t\tmessage: `The template takes ${length.toLocaleString(\"en-US\")} characters of JSON; the limit is ${REMOTE_CONFIG_MAX_TEMPLATE_LENGTH.toLocaleString(\"en-US\")}.`\n\t}]);\n\treturn template;\n};\nconst textList = (value, path, issue, check, describe) => {\n\tif (!Array.isArray(value) || value.length === 0 || value.length > MAX_RULE_VALUES) {\n\t\tissue(path, `must list 1-${MAX_RULE_VALUES} values.`);\n\t\treturn [];\n\t}\n\tconst list = [];\n\tvalue.forEach((entry, index) => {\n\t\tif (typeof entry !== \"string\" || !check(entry)) issue(`${path}[${index}]`, describe);\n\t\telse if (!list.includes(entry)) list.push(entry);\n\t});\n\treturn list;\n};\nconst RULE_FIELDS = {\n\tplatform: [\"type\", \"platforms\"],\n\tchannel: [\"type\", \"channels\"],\n\tappVersion: [\"type\", \"range\"],\n\tcohort: [\"type\", \"cohorts\"],\n\tpercent: [\n\t\t\"type\",\n\t\t\"seed\",\n\t\t\"from\",\n\t\t\"to\"\n\t],\n\tfingerprint: [\"type\", \"hashes\"],\n\tdateTime: [\n\t\t\"type\",\n\t\t\"from\",\n\t\t\"to\"\n\t]\n};\nconst validateRules = (value, path, issue) => {\n\tif (!Array.isArray(value) || value.length === 0) {\n\t\tissue(path, \"must list at least one rule.\");\n\t\treturn [];\n\t}\n\tconst rules = [];\n\tvalue.forEach((raw, index) => {\n\t\tconst rulePath = `${path}[${index}]`;\n\t\tif (!isRecord(raw) || typeof raw.type !== \"string\") {\n\t\t\tissue(rulePath, \"must be a rule object with a type.\");\n\t\t\treturn;\n\t\t}\n\t\tconst type = raw.type;\n\t\tconst fields = ownEntry(RULE_FIELDS, type);\n\t\tif (fields === void 0) {\n\t\t\tissue(`${rulePath}.type`, \"must be platform, channel, appVersion, cohort, percent, fingerprint, or dateTime.\");\n\t\t\treturn;\n\t\t}\n\t\tfor (const key of Object.keys(raw)) if (!fields.includes(key)) issue(`${rulePath}.${key}`, `is not a field of a ${type} rule.`);\n\t\tswitch (type) {\n\t\t\tcase \"platform\": {\n\t\t\t\tconst platforms = textList(raw.platforms, `${rulePath}.platforms`, issue, (text) => PLATFORMS.has(text), \"must be \\\"ios\\\" or \\\"android\\\".\");\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tplatforms\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"channel\": {\n\t\t\t\tconst channels = textList(raw.channels, `${rulePath}.channels`, issue, (text) => visibleText(text, MAX_RULE_TEXT_LENGTH), `must be a channel name of 1-${MAX_RULE_TEXT_LENGTH} characters.`);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tchannels\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"appVersion\": {\n\t\t\t\tconst range = raw.range;\n\t\t\t\tif (!visibleText(range, MAX_RULE_TEXT_LENGTH) || !isValidRange(range.trim())) {\n\t\t\t\t\tissue(`${rulePath}.range`, \"must be a semver range, such as >=1.4.0 or 2.x.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\trange: range.trim()\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"cohort\": {\n\t\t\t\tconst cohorts = textList(raw.cohorts, `${rulePath}.cohorts`, issue, isValidCohort, \"must be a cohort from 1 to 1000, or a lowercase slug.\").map(normalizeCohortValue);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tcohorts: [...new Set(cohorts)]\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"percent\": {\n\t\t\t\tconst { seed, from, to } = raw;\n\t\t\t\tif (typeof seed !== \"string\" || !SEED_PATTERN.test(seed)) {\n\t\t\t\t\tissue(`${rulePath}.seed`, \"must be 1-64 letters, digits, _, and -.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst isPercent = (value) => typeof value === \"number\" && value >= 0 && value <= 100 && Math.abs(value * 10 - Math.round(value * 10)) < 1e-9;\n\t\t\t\tif (!isPercent(from) || !isPercent(to) || from >= to) {\n\t\t\t\t\tissue(rulePath, \"takes from < to, each a percentage from 0 to 100 in steps of 0.1.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tseed,\n\t\t\t\t\tfrom,\n\t\t\t\t\tto\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"fingerprint\": {\n\t\t\t\tconst hashes = textList(raw.hashes, `${rulePath}.hashes`, issue, (text) => visibleText(text, MAX_RULE_TEXT_LENGTH), `must be a fingerprint of 1-${MAX_RULE_TEXT_LENGTH} characters.`);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\thashes\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"dateTime\": {\n\t\t\t\tconst instant = (field) => {\n\t\t\t\t\tconst value = raw[field];\n\t\t\t\t\tif (value === void 0) return void 0;\n\t\t\t\t\tconst ms = typeof value === \"string\" ? Date.parse(value) : NaN;\n\t\t\t\t\tif (typeof value !== \"string\" || !DATE_TIME_PATTERN.test(value) || !Number.isFinite(ms)) {\n\t\t\t\t\t\tissue(`${rulePath}.${field}`, \"must be an ISO 8601 date-time with a time zone, such as 2026-10-08T10:00:00Z.\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn new Date(ms).toISOString();\n\t\t\t\t};\n\t\t\t\tconst from = instant(\"from\");\n\t\t\t\tconst to = instant(\"to\");\n\t\t\t\tif (from === null || to === null) return;\n\t\t\t\tif (from === void 0 && to === void 0) {\n\t\t\t\t\tissue(rulePath, \"takes from, to, or both.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (from !== void 0 && to !== void 0 && from >= to) {\n\t\t\t\t\tissue(rulePath, \"takes a from before its to.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\t...from === void 0 ? {} : { from },\n\t\t\t\t\t...to === void 0 ? {} : { to }\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\treturn rules;\n};\n/** Whether one rule matches a device. */\nconst matchesRemoteConfigRule = (rule, context) => {\n\tswitch (rule.type) {\n\t\tcase \"platform\": return context.platform !== void 0 && context.platform !== null && rule.platforms.includes(context.platform);\n\t\tcase \"channel\": return typeof context.channel === \"string\" && rule.channels.includes(context.channel);\n\t\tcase \"appVersion\": return typeof context.appVersion === \"string\" && semverSatisfies(rule.range, context.appVersion);\n\t\tcase \"cohort\": return typeof context.cohort === \"string\" && rule.cohorts.includes(normalizeCohortValue(context.cohort));\n\t\tcase \"percent\": {\n\t\t\tif (typeof context.cohort !== \"string\") return false;\n\t\t\tconst cohort = getNumericCohortValue(context.cohort);\n\t\t\tif (cohort === null) return false;\n\t\t\tconst position = getNumericCohortRolloutPosition(rule.seed, cohort);\n\t\t\treturn position >= Math.round(rule.from * 10) && position < Math.round(rule.to * 10);\n\t\t}\n\t\tcase \"fingerprint\": return typeof context.fingerprintHash === \"string\" && rule.hashes.includes(context.fingerprintHash);\n\t\tcase \"dateTime\": return typeof context.now === \"number\" && (rule.from === void 0 || context.now >= Date.parse(rule.from)) && (rule.to === void 0 || context.now < Date.parse(rule.to));\n\t}\n};\n/** Whether every rule of a condition matches a device. */\nconst matchesRemoteConfigCondition = (condition, context) => condition.rules.every((rule) => matchesRemoteConfigRule(rule, context));\n/**\n* Every parameter's value for one device: the value of the first condition,\n* in the template's order, that matches and that the parameter has a value\n* for; otherwise its default value.\n*/\nconst evaluateRemoteConfig = (template, context) => {\n\tconst matched = template.conditions.filter((condition) => matchesRemoteConfigCondition(condition, context)).map(({ name }) => name);\n\treturn Object.fromEntries(Object.entries(template.parameters).map(([key, parameter]) => {\n\t\tlet condition = null;\n\t\tlet chosen = parameter.defaultValue;\n\t\tfor (const name of matched) {\n\t\t\tconst value = ownEntry(parameter.conditionalValues, name);\n\t\t\tif (value !== void 0) {\n\t\t\t\tcondition = name;\n\t\t\t\tchosen = value;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn [key, {\n\t\t\tvalue: \"value\" in chosen ? chosen.value : null,\n\t\t\tcondition\n\t\t}];\n\t}));\n};\n/** The values a device receives: each parameter's text, without in-app defaults. */\nconst resolveRemoteConfigValues = (template, context) => {\n\treturn Object.fromEntries(Object.entries(evaluateRemoteConfig(template, context)).flatMap(([key, { value }]) => value === null ? [] : [[key, value]]));\n};\n//#endregion\nexport { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigValidationError, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, resolveRemoteConfigValues, validateRemoteConfigTemplate };\n", "import { EMPTY_REMOTE_CONFIG_TEMPLATE, resolveRemoteConfigValues, validateRemoteConfigTemplate } from \"./template.mjs\";\nimport { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/server/api.ts\nconst ACTIVE_ID = \"active\";\n/** How long a server answers fetches from the active template it read last. */\nconst ACTIVE_CACHE_TTL_MS = 5e3;\nconst MAX_DESCRIPTION_LENGTH = 256;\nconst MAX_VERSIONS_PAGE = 100;\n/**\n* An argument the API refuses, such as a negative `baseVersion`; the admin\n* routes answer it with `400`.\n*/\nvar RemoteConfigInputError = class extends TypeError {\n\tname = \"RemoteConfigInputError\";\n};\nconst normalizeDescription = (description) => {\n\tif (description === void 0 || description === null) return null;\n\tif (typeof description !== \"string\") throw new RemoteConfigInputError(\"A version description is text.\");\n\tconst trimmed = description.trim();\n\tif (trimmed.length > MAX_DESCRIPTION_LENGTH) throw new RemoteConfigInputError(`A version description holds up to ${MAX_DESCRIPTION_LENGTH} characters.`);\n\treturn trimmed.length === 0 ? null : trimmed;\n};\nconst requireVersionNumber = (value, name) => {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) throw new RemoteConfigInputError(`${name} must be a non-negative integer.`);\n\treturn value;\n};\n/** A template as its `json` column stores it; validation made it plain JSON. */\nconst toColumn = (template) => template;\nconst fromColumn = (value) => value;\nconst toVersion = (row) => Object.freeze({\n\tversion: row.version,\n\tdescription: row.description,\n\tupdateType: row.update_type === \"ROLLBACK\" ? \"ROLLBACK\" : \"PUBLISH\",\n\trollbackSource: row.rollback_source,\n\tcreatedAtMs: row.created_at_ms\n});\n/** Remote Config's API over its tables. */\nconst createRemoteConfigApi = ({ db, now }) => {\n\tlet cached = null;\n\tlet loading = null;\n\tlet generation = 0;\n\tconst readActive = async () => {\n\t\tconst row = await db.findOne(\"remote_config_active\", { id: ACTIVE_ID });\n\t\treturn row === null ? {\n\t\t\tversion: 0,\n\t\t\ttemplate: EMPTY_REMOTE_CONFIG_TEMPLATE,\n\t\t\tupdatedAtMs: null\n\t\t} : {\n\t\t\tversion: row.version,\n\t\t\ttemplate: fromColumn(row.template),\n\t\t\tupdatedAtMs: row.updated_at_ms\n\t\t};\n\t};\n\t/** The active template for fetches: one read per server every few seconds at most. */\n\tconst servedActive = () => {\n\t\tif (cached !== null && cached.expiresAt > now()) return Promise.resolve(cached.active);\n\t\tif (loading !== null) return loading;\n\t\tconst started = generation;\n\t\tconst read = readActive().then((active) => {\n\t\t\tif (generation === started) cached = {\n\t\t\t\tactive,\n\t\t\t\texpiresAt: now() + ACTIVE_CACHE_TTL_MS\n\t\t\t};\n\t\t\treturn active;\n\t\t}).finally(() => {\n\t\t\tif (loading === read) loading = null;\n\t\t});\n\t\tloading = read;\n\t\treturn read;\n\t};\n\tconst commit = async (input) => {\n\t\tconst attempt = () => db.transaction(async (tx) => {\n\t\t\tconst active = await tx.findOne(\"remote_config_active\", { id: ACTIVE_ID });\n\t\t\tconst currentVersion = active?.version ?? 0;\n\t\t\tif (currentVersion !== input.baseVersion) return {\n\t\t\t\tstatus: \"conflict\",\n\t\t\t\tcurrentVersion\n\t\t\t};\n\t\t\tconst version = currentVersion + 1;\n\t\t\tconst at = now();\n\t\t\tconst row = {\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tdescription: input.description,\n\t\t\t\tupdate_type: input.rollbackSource === null ? \"PUBLISH\" : \"ROLLBACK\",\n\t\t\t\trollback_source: input.rollbackSource,\n\t\t\t\tcreated_at_ms: at\n\t\t\t};\n\t\t\ttx.create(\"remote_config_versions\", row);\n\t\t\tif (active === null) tx.create(\"remote_config_active\", {\n\t\t\t\tid: ACTIVE_ID,\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tupdated_at_ms: at\n\t\t\t});\n\t\t\telse tx.update(\"remote_config_active\", active, {\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tupdated_at_ms: at\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tstatus: \"published\",\n\t\t\t\tversion: toVersion(row)\n\t\t\t};\n\t\t});\n\t\ttry {\n\t\t\tconst result = await attempt();\n\t\t\tif (result.status === \"published\") {\n\t\t\t\tgeneration += 1;\n\t\t\t\tcached = null;\n\t\t\t\tloading = null;\n\t\t\t}\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseConstraintError && (error.reason === \"exists\" || error.reason === \"unique\")) return {\n\t\t\t\tstatus: \"conflict\",\n\t\t\t\tcurrentVersion: (await readActive()).version\n\t\t\t};\n\t\t\tthrow error;\n\t\t}\n\t};\n\treturn Object.freeze({\n\t\tgetActive: readActive,\n\t\tpublish: async ({ template, baseVersion, description }) => commit({\n\t\t\ttemplate: validateRemoteConfigTemplate(template),\n\t\t\tbaseVersion: requireVersionNumber(baseVersion, \"baseVersion\"),\n\t\t\tdescription: normalizeDescription(description),\n\t\t\trollbackSource: null\n\t\t}),\n\t\trollback: async ({ version, baseVersion, description }) => {\n\t\t\tconst source = await db.findOne(\"remote_config_versions\", { version: requireVersionNumber(version, \"version\") });\n\t\t\tif (source === null) return { status: \"not_found\" };\n\t\t\treturn commit({\n\t\t\t\ttemplate: fromColumn(source.template),\n\t\t\t\tbaseVersion: requireVersionNumber(baseVersion, \"baseVersion\"),\n\t\t\t\tdescription: normalizeDescription(description) ?? `Rollback to version ${source.version}`,\n\t\t\t\trollbackSource: source.version\n\t\t\t});\n\t\t},\n\t\tlistVersions: async ({ limit = 20, cursor } = {}) => {\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_VERSIONS_PAGE) throw new RemoteConfigInputError(`limit must be an integer from 1 to ${MAX_VERSIONS_PAGE}.`);\n\t\t\tconst page = await db.findMany(\"remote_config_versions\", {\n\t\t\t\tindex: \"byVersion\",\n\t\t\t\twhere: {},\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit,\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\treturn Object.freeze({\n\t\t\t\tversions: Object.freeze(page.rows.map(toVersion)),\n\t\t\t\t...page.next === void 0 ? {} : { next: page.next }\n\t\t\t});\n\t\t},\n\t\tgetVersion: async (version) => {\n\t\t\tconst row = await db.findOne(\"remote_config_versions\", { version: requireVersionNumber(version, \"version\") });\n\t\t\treturn row === null ? null : Object.freeze({\n\t\t\t\t...toVersion(row),\n\t\t\t\ttemplate: fromColumn(row.template)\n\t\t\t});\n\t\t},\n\t\tresolve: async (context) => {\n\t\t\tconst active = await servedActive();\n\t\t\treturn {\n\t\t\t\tversion: active.version,\n\t\t\t\tvalues: resolveRemoteConfigValues(active.template, {\n\t\t\t\t\t...context,\n\t\t\t\t\tnow: context.now ?? now()\n\t\t\t\t})\n\t\t\t};\n\t\t}\n\t});\n};\n//#endregion\nexport { RemoteConfigInputError, createRemoteConfigApi };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"remoteConfig\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "//#region src/shared/wire.ts\n/**\n* The exchange between the app's `remoteConfig()` client plugin and the\n* `remoteConfig()` server plugin: `GET /remote-config`, relative to the\n* `baseURL` the app passes to `HotUpdater.init`. The app\n* sends what conditions read as query parameters, and the server answers the\n* values the published template gives them. Both sides import this module,\n* which imports nothing, so the app's bundle never reaches server code.\n*/\n/** The path both sides use, relative to the app's `baseURL`. */\nconst REMOTE_CONFIG_PATH = \"remote-config\";\n/** The query parameter each context field travels in. */\nconst REMOTE_CONFIG_QUERY = {\n\tplatform: \"platform\",\n\tappVersion: \"appVersion\",\n\tchannel: \"channel\",\n\tcohort: \"cohort\",\n\tfingerprintHash: \"fingerprintHash\"\n};\n/**\n* `GET /remote-config?\u2026`, with a field left out when it is null. It encodes\n* the query itself, since React Native's `URLSearchParams` throws on `set`.\n*/\nconst remoteConfigRequestPath = (context) => {\n\tconst query = Object.keys(REMOTE_CONFIG_QUERY).flatMap((field) => {\n\t\tconst value = context[field];\n\t\treturn value === null ? [] : [`${encodeURIComponent(REMOTE_CONFIG_QUERY[field])}=${encodeURIComponent(value)}`];\n\t});\n\treturn `${REMOTE_CONFIG_PATH}?${query.join(\"&\")}`;\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/** A `200` body, checked; null when it is not one. */\nconst parseRemoteConfigFetchResponse = (value) => {\n\tif (!isRecord(value)) return null;\n\tconst { version, values } = value;\n\tif (typeof version !== \"number\" || !Number.isSafeInteger(version) || version < 0 || !isRecord(values)) return null;\n\tconst entries = Object.entries(values);\n\tif (entries.some(([, text]) => typeof text !== \"string\")) return null;\n\treturn {\n\t\tversion,\n\t\tvalues: Object.fromEntries(entries)\n\t};\n};\n//#endregion\nexport { REMOTE_CONFIG_PATH, REMOTE_CONFIG_QUERY, parseRemoteConfigFetchResponse, remoteConfigRequestPath };\n", "import { RemoteConfigValidationError } from \"./template.mjs\";\nimport { RemoteConfigInputError } from \"./api.mjs\";\nimport { REMOTE_CONFIG_PATH, REMOTE_CONFIG_QUERY } from \"../shared/wire.mjs\";\nimport { DatabaseCursorError, isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/routes.ts\n/** Seconds a client waits before it resends a request the busy database refused. */\nconst RETRY_AFTER_SECONDS = 5;\n/** A shared cache keeps a device's values five seconds, as it keeps a Release Catalog. */\nconst FETCH_CACHE_CONTROL = \"public, max-age=0, s-maxage=5\";\nconst MAX_CONTEXT_LENGTH = 128;\nvar BadRequestError = class extends Error {};\nconst json = (body, status, headers = {}) => Response.json(body, {\n\theaders: {\n\t\t\"cache-control\": \"private, no-store\",\n\t\t...headers\n\t},\n\tstatus\n});\nconst run = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof RemoteConfigValidationError) return json({\n\t\t\terror: error.message,\n\t\t\tissues: error.issues\n\t\t}, 400);\n\t\tif (error instanceof BadRequestError || error instanceof RemoteConfigInputError || error instanceof DatabaseCursorError) return json({ error: error.message }, 400);\n\t\tif (isDatabaseBusyError(error)) {\n\t\t\tconsole.warn(\"[hot-updater] Remote Config answered 503: the database is busy.\", error);\n\t\t\treturn json({ error: \"Service unavailable\" }, 503, { \"retry-after\": String(RETRY_AFTER_SECONDS) });\n\t\t}\n\t\tthrow error;\n\t}\n};\nconst readContext = (request) => {\n\tconst query = new URL(request.url).searchParams;\n\tconst read = (field) => {\n\t\tconst value = query.get(REMOTE_CONFIG_QUERY[field]);\n\t\tif (value === null || value.length === 0) return null;\n\t\tif (value.length > MAX_CONTEXT_LENGTH) throw new BadRequestError(`${field} is too long.`);\n\t\treturn value;\n\t};\n\tconst platform = read(\"platform\");\n\tif (platform !== null && platform !== \"ios\" && platform !== \"android\") throw new BadRequestError(\"platform must be \\\"ios\\\" or \\\"android\\\".\");\n\treturn {\n\t\tplatform,\n\t\tappVersion: read(\"appVersion\"),\n\t\tchannel: read(\"channel\"),\n\t\tcohort: read(\"cohort\"),\n\t\tfingerprintHash: read(\"fingerprintHash\")\n\t};\n};\nconst bodyHash = async (body) => {\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(body));\n\treturn [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n};\nconst readJsonBody = async (request) => {\n\tconst body = await request.json().catch(() => null);\n\tif (typeof body !== \"object\" || body === null || Array.isArray(body)) throw new BadRequestError(\"The request body must be a JSON object.\");\n\treturn body;\n};\nconst versionParam = (params) => {\n\tconst text = params.version ?? \"\";\n\tif (!/^\\d{1,15}$/u.test(text)) throw new BadRequestError(\"The version must be a positive integer.\");\n\treturn Number(text);\n};\nconst publishResponse = (result) => result.status === \"published\" ? json(result.version, 200) : json({\n\terror: `Version ${result.currentVersion} was published since; reload the template and publish again.`,\n\tcurrentVersion: result.currentVersion\n}, 409);\n/**\n* Remote Config's routes: the devices' `GET /remote-config` on\n* `handlers.client`, and template management on `handlers.admin`.\n*/\nconst createRemoteConfigEndpoints = (api) => [\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}`,\n\t\taccess: \"client\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst body = JSON.stringify(await api.resolve(readContext(request)));\n\t\t\tconst etag = `\"sha256:${await bodyHash(body)}\"`;\n\t\t\tconst headers = {\n\t\t\t\t\"cache-control\": FETCH_CACHE_CONTROL,\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\tetag,\n\t\t\t\tvary: \"Accept-Encoding\"\n\t\t\t};\n\t\t\tif (request.headers.get(\"if-none-match\") === etag) return new Response(null, {\n\t\t\t\theaders,\n\t\t\t\tstatus: 304\n\t\t\t});\n\t\t\treturn new Response(body, {\n\t\t\t\theaders,\n\t\t\t\tstatus: 200\n\t\t\t});\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/template`,\n\t\taccess: \"admin\",\n\t\thandler: () => run(async () => json(await api.getActive(), 200))\n\t},\n\t{\n\t\tmethod: \"PUT\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/template`,\n\t\taccess: \"admin\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst body = await readJsonBody(request);\n\t\t\treturn publishResponse(await api.publish({\n\t\t\t\ttemplate: body.template,\n\t\t\t\tbaseVersion: body.baseVersion,\n\t\t\t\t...body.description === void 0 ? {} : { description: body.description }\n\t\t\t}));\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions`,\n\t\taccess: \"admin\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst query = new URL(request.url).searchParams;\n\t\t\tconst limit = query.get(\"limit\");\n\t\t\tconst cursor = query.get(\"cursor\");\n\t\t\treturn json(await api.listVersions({\n\t\t\t\t...limit === null ? {} : { limit: Number(limit) },\n\t\t\t\t...cursor === null ? {} : { cursor }\n\t\t\t}), 200);\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions/:version`,\n\t\taccess: \"admin\",\n\t\thandler: (_request, params) => run(async () => {\n\t\t\tconst version = await api.getVersion(versionParam(params));\n\t\t\treturn version === null ? json({ error: \"Version not found\" }, 404) : json(version, 200);\n\t\t})\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions/:version/rollback`,\n\t\taccess: \"admin\",\n\t\thandler: (request, params) => run(async () => {\n\t\t\tconst body = await readJsonBody(request);\n\t\t\tconst result = await api.rollback({\n\t\t\t\tversion: versionParam(params),\n\t\t\t\tbaseVersion: body.baseVersion,\n\t\t\t\t...body.description === void 0 ? {} : { description: body.description }\n\t\t\t});\n\t\t\treturn result.status === \"not_found\" ? json({ error: \"Version not found\" }, 404) : publishResponse(result);\n\t\t})\n\t}\n];\n//#endregion\nexport { createRemoteConfigEndpoints };\n", "import { defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\n/**\n* Remote Config's tables: the active template in one row, which a device's\n* fetch reads by key, and every published version beside it.\n*/\nconst remoteConfigSchema = {\n\t/** One row, `id` `\"active\"`: the template devices receive and its version. */\n\tremote_config_active: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tversion: { type: \"integer\" },\n\t\ttemplate: { type: \"json\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, { key: [\"id\"] }),\n\t/** Each publish and rollback, kept so the Console can show and restore it. */\n\tremote_config_versions: defineTable({\n\t\tversion: { type: \"integer\" },\n\t\ttemplate: { type: \"json\" },\n\t\tdescription: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 256,\n\t\t\trequired: false\n\t\t},\n\t\t/** `PUBLISH`, or `ROLLBACK` for a copy of `rollback_source`. */\n\t\tupdate_type: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\trollback_source: {\n\t\t\ttype: \"integer\",\n\t\t\trequired: false\n\t\t},\n\t\tcreated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"version\"],\n\t\tindexes: { byVersion: {\n\t\t\teq: [],\n\t\t\tsort: [\"version\"]\n\t\t} }\n\t})\n};\n//#endregion\nexport { remoteConfigSchema };\n", "import { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigValidationError, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, resolveRemoteConfigValues, validateRemoteConfigTemplate } from \"./template.mjs\";\nimport { RemoteConfigInputError, createRemoteConfigApi } from \"./api.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { createRemoteConfigEndpoints } from \"./routes.mjs\";\nimport { remoteConfigSchema } from \"./schema.mjs\";\nimport { createRemoteConfigAdminApi } from \"./admin.mjs\";\nimport { definePlugin } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\n/**\n* Remote Config: parameters whose values the server picks per device by\n* conditions, published as versioned templates. Devices fetch their values\n* from `GET /remote-config` with the `remoteConfig()` client plugin; the\n* Console and `hotUpdater.api.remoteConfig` edit, publish, and roll back\n* templates.\n*/\nconst remoteConfig = () => {\n\tconst plugin = definePlugin({\n\t\tid: \"remoteConfig\",\n\t\tnamespace: false,\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: remoteConfigSchema,\n\t\tinit: ({ db, now }) => {\n\t\t\tconst api = createRemoteConfigApi({\n\t\t\t\tdb,\n\t\t\t\tnow\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tapi,\n\t\t\t\tendpoints: createRemoteConfigEndpoints(api)\n\t\t\t};\n\t\t}\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigInputError, RemoteConfigValidationError, createRemoteConfigAdminApi, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, remoteConfig, remoteConfigSchema, resolveRemoteConfigValues, validateRemoteConfigTemplate };\n", "import { createHotUpdater } from \"@hot-updater/server\";\nimport { apiKeys, insights, remoteConfig } from \"@hot-updater/server/plugins\";\nimport { env } from \"cloudflare:workers\";\nimport { Hono } from \"hono\";\n\nimport { d1Database, r2Storage } from \"../../src/worker\";\n\nexport type CloudflareWorkerEnv = {\n DB: {\n batch: D1Database[\"batch\"];\n prepare: D1Database[\"prepare\"];\n };\n BUCKET: R2Bucket;\n BUCKET_NAME: string;\n ACCOUNT_ID: string;\n R2_ACCESS_KEY_ID: string;\n R2_SECRET_ACCESS_KEY: string;\n};\n\nexport const HOT_UPDATER_BASE_PATH = \"/\";\n\nconst hotUpdater = createHotUpdater({\n database: d1Database(env.DB),\n plugins: [insights(), apiKeys(), remoteConfig()],\n storage: r2Storage({\n bucket: env.BUCKET,\n bucketName: env.BUCKET_NAME,\n // Presign download URLs, so devices download from R2.\n accountId: env.ACCOUNT_ID,\n credentials: {\n accessKeyId: env.R2_ACCESS_KEY_ID,\n secretAccessKey: env.R2_SECRET_ACCESS_KEY,\n },\n }),\n});\n\nconst app = new Hono<{ Bindings: CloudflareWorkerEnv }>();\n\napp.mount(HOT_UPDATER_BASE_PATH, (request: Request) =>\n hotUpdater.handlers.client(request),\n);\n\nexport default app;\n", "// src/compose.ts\nvar compose = (middleware, onError, onNotFound) => {\n return (context, next) => {\n let index = -1;\n return dispatch(0);\n async function dispatch(i) {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n let res;\n let isError = false;\n let handler;\n if (middleware[i]) {\n handler = middleware[i][0][0];\n context.req.routeIndex = i;\n } else {\n handler = i === middleware.length && next || void 0;\n }\n if (handler) {\n try {\n res = await handler(context, () => dispatch(i + 1));\n } catch (err) {\n if (err instanceof Error && onError) {\n context.error = err;\n res = await onError(err, context);\n isError = true;\n } else {\n throw err;\n }\n }\n } else {\n if (context.finalized === false && onNotFound) {\n res = await onNotFound(context);\n }\n }\n if (res && (context.finalized === false || isError)) {\n context.res = res;\n }\n return context;\n }\n };\n};\nexport {\n compose\n};\n", "// src/request/constants.ts\nvar GET_MATCH_RESULT = /* @__PURE__ */ Symbol();\nexport {\n GET_MATCH_RESULT\n};\n", "// src/utils/buffer.ts\nimport { sha256 } from \"./crypto.js\";\nvar equal = (a, b) => {\n if (a === b) {\n return true;\n }\n if (a.byteLength !== b.byteLength) {\n return false;\n }\n const va = new DataView(a);\n const vb = new DataView(b);\n let i = va.byteLength;\n while (i--) {\n if (va.getUint8(i) !== vb.getUint8(i)) {\n return false;\n }\n }\n return true;\n};\nvar constantTimeEqualString = (a, b) => {\n const aLen = a.length;\n const bLen = b.length;\n const maxLen = Math.max(aLen, bLen);\n let out = aLen ^ bLen;\n for (let i = 0; i < maxLen; i++) {\n const aChar = i < aLen ? a.charCodeAt(i) : 0;\n const bChar = i < bLen ? b.charCodeAt(i) : 0;\n out |= aChar ^ bChar;\n }\n return out === 0;\n};\nvar timingSafeEqualString = async (a, b, hashFunction) => {\n if (!hashFunction) {\n hashFunction = sha256;\n }\n const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);\n if (sa == null || sb == null || typeof sa !== \"string\" || typeof sb !== \"string\") {\n return false;\n }\n const hashEqual = constantTimeEqualString(sa, sb);\n const originalEqual = constantTimeEqualString(a, b);\n return hashEqual && originalEqual;\n};\nvar timingSafeEqual = async (a, b, hashFunction) => {\n if (typeof a === \"string\" && typeof b === \"string\") {\n return timingSafeEqualString(a, b, hashFunction);\n }\n if (!hashFunction) {\n hashFunction = sha256;\n }\n const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);\n if (!sa || !sb || typeof sa !== \"string\" || typeof sb !== \"string\") {\n return false;\n }\n return timingSafeEqualString(sa, sb);\n};\nvar bufferToString = (buffer) => {\n if (buffer instanceof ArrayBuffer) {\n const enc = new TextDecoder(\"utf-8\");\n return enc.decode(buffer);\n }\n return buffer;\n};\nvar bufferToFormData = (arrayBuffer, contentType) => {\n const response = new Response(arrayBuffer, {\n headers: {\n // Normalize the media type (case-insensitive) while keeping parameters like the boundary\n \"Content-Type\": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())\n }\n });\n return response.formData();\n};\nexport {\n bufferToFormData,\n bufferToString,\n equal,\n timingSafeEqual\n};\n", "// src/utils/body.ts\nimport { bufferToFormData } from \"./buffer.js\";\nvar isRawRequest = (request) => \"headers\" in request;\nvar parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {\n const { all = false, dot = false } = options;\n const headers = isRawRequest(request) ? request.headers : request.raw.headers;\n const contentType = headers.get(\"Content-Type\");\n const mediaType = contentType?.split(\";\")[0].trim().toLowerCase();\n if (mediaType === \"multipart/form-data\" || mediaType === \"application/x-www-form-urlencoded\") {\n return parseFormData(request, { all, dot });\n }\n return {};\n};\nasync function parseFormData(request, options) {\n if (!isRawRequest(request) && request.bodyCache.formData) {\n return convertFormDataToBodyData(\n await request.bodyCache.formData,\n options\n );\n }\n const headers = isRawRequest(request) ? request.headers : request.raw.headers;\n const arrayBuffer = await request.arrayBuffer();\n const formDataPromise = bufferToFormData(arrayBuffer, headers.get(\"Content-Type\") || \"\");\n if (!isRawRequest(request)) {\n request.bodyCache.formData = formDataPromise;\n }\n const formData = await formDataPromise;\n if (formData) {\n return convertFormDataToBodyData(formData, options);\n }\n return {};\n}\nfunction convertFormDataToBodyData(formData, options) {\n const form = /* @__PURE__ */ Object.create(null);\n formData.forEach((value, key) => {\n const shouldParseAllValues = options.all || key.endsWith(\"[]\");\n if (!shouldParseAllValues) {\n form[key] = value;\n } else {\n handleParsingAllValues(form, key, value);\n }\n });\n if (options.dot) {\n Object.entries(form).forEach(([key, value]) => {\n const shouldParseDotValues = key.includes(\".\");\n if (shouldParseDotValues) {\n handleParsingNestedValues(form, key, value);\n delete form[key];\n }\n });\n }\n return form;\n}\nvar handleParsingAllValues = (form, key, value) => {\n if (form[key] !== void 0) {\n if (Array.isArray(form[key])) {\n ;\n form[key].push(value);\n } else {\n form[key] = [form[key], value];\n }\n } else {\n if (!key.endsWith(\"[]\")) {\n form[key] = value;\n } else {\n form[key] = [value];\n }\n }\n};\nvar handleParsingNestedValues = (form, key, value) => {\n if (/(?:^|\\.)__proto__\\./.test(key)) {\n return;\n }\n let nestedForm = form;\n const keys = key.split(\".\");\n keys.forEach((key2, index) => {\n if (index === keys.length - 1) {\n nestedForm[key2] = value;\n } else {\n if (!nestedForm[key2] || typeof nestedForm[key2] !== \"object\" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {\n nestedForm[key2] = /* @__PURE__ */ Object.create(null);\n }\n nestedForm = nestedForm[key2];\n }\n });\n};\nexport {\n parseBody\n};\n", "// src/utils/url.ts\nvar splitPath = (path) => {\n const paths = path.split(\"/\");\n if (paths[0] === \"\") {\n paths.shift();\n }\n return paths;\n};\nvar splitRoutingPath = (routePath) => {\n const { groups, path } = extractGroupsFromPath(routePath);\n const paths = splitPath(path);\n return replaceGroupMarks(paths, groups);\n};\nvar extractGroupsFromPath = (path) => {\n const groups = [];\n path = path.replace(/\\{[^}]+\\}/g, (match, index) => {\n const mark = `@${index}`;\n groups.push([mark, match]);\n return mark;\n });\n return { groups, path };\n};\nvar replaceGroupMarks = (paths, groups) => {\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = paths.length - 1; j >= 0; j--) {\n if (paths[j].includes(mark)) {\n paths[j] = paths[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n return paths;\n};\nvar patternCache = {};\nvar getPattern = (label, next) => {\n if (label === \"*\") {\n return \"*\";\n }\n const match = label.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n if (match) {\n const cacheKey = `${label}#${next}`;\n if (!patternCache[cacheKey]) {\n if (match[2]) {\n patternCache[cacheKey] = next && next[0] !== \":\" && next[0] !== \"*\" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];\n } else {\n patternCache[cacheKey] = [label, match[1], true];\n }\n }\n return patternCache[cacheKey];\n }\n return null;\n};\nvar tryDecode = (str, decoder) => {\n try {\n return decoder(str);\n } catch {\n return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {\n try {\n return decoder(match);\n } catch {\n return match;\n }\n });\n }\n};\nvar tryDecodeURI = (str) => tryDecode(str, decodeURI);\nvar getPath = (request) => {\n const url = request.url;\n const start = url.indexOf(\"/\", url.indexOf(\":\") + 4);\n let i = start;\n for (; i < url.length; i++) {\n const charCode = url.charCodeAt(i);\n if (charCode === 37) {\n const queryIndex = url.indexOf(\"?\", i);\n const hashIndex = url.indexOf(\"#\", i);\n const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);\n const path = url.slice(start, end);\n return tryDecodeURI(path.includes(\"%25\") ? path.replace(/%25/g, \"%2525\") : path);\n } else if (charCode === 63 || charCode === 35) {\n break;\n }\n }\n return url.slice(start, i);\n};\nvar getQueryStrings = (url) => {\n const queryIndex = url.indexOf(\"?\", 8);\n return queryIndex === -1 ? \"\" : \"?\" + url.slice(queryIndex + 1);\n};\nvar getPathNoStrict = (request) => {\n const result = getPath(request);\n return result.length > 1 && result.at(-1) === \"/\" ? result.slice(0, -1) : result;\n};\nvar mergePath = (base, sub, ...rest) => {\n if (rest.length) {\n sub = mergePath(sub, ...rest);\n }\n return `${base?.[0] === \"/\" ? \"\" : \"/\"}${base}${sub === \"/\" ? \"\" : `${base?.at(-1) === \"/\" ? \"\" : \"/\"}${sub?.[0] === \"/\" ? sub.slice(1) : sub}`}`;\n};\nvar checkOptionalParameter = (path) => {\n if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(\":\")) {\n return null;\n }\n const segments = path.split(\"/\");\n const results = [];\n let basePath = \"\";\n segments.forEach((segment) => {\n if (segment !== \"\" && !/\\:/.test(segment)) {\n basePath += \"/\" + segment;\n } else if (/\\:/.test(segment)) {\n if (/\\?/.test(segment)) {\n if (results.length === 0 && basePath === \"\") {\n results.push(\"/\");\n } else {\n results.push(basePath);\n }\n const optionalSegment = segment.replace(\"?\", \"\");\n basePath += \"/\" + optionalSegment;\n results.push(basePath);\n } else {\n basePath += \"/\" + segment;\n }\n }\n });\n return results.filter((v, i, a) => a.indexOf(v) === i);\n};\nvar _decodeURI = (value) => {\n if (!/[%+]/.test(value)) {\n return value;\n }\n if (value.indexOf(\"+\") !== -1) {\n value = value.replace(/\\+/g, \" \");\n }\n return value.indexOf(\"%\") !== -1 ? tryDecode(value, decodeURIComponent_) : value;\n};\nvar _getQueryParam = (url, key, multiple) => {\n let encoded;\n if (!multiple && key && !/[%+]/.test(key)) {\n let keyIndex2 = url.indexOf(\"?\", 8);\n if (keyIndex2 === -1) {\n return void 0;\n }\n if (!url.startsWith(key, keyIndex2 + 1)) {\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n while (keyIndex2 !== -1) {\n const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);\n if (trailingKeyCode === 61) {\n const valueIndex = keyIndex2 + key.length + 2;\n const endIndex = url.indexOf(\"&\", valueIndex);\n return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));\n } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {\n return \"\";\n }\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n encoded = /[%+]/.test(url);\n if (!encoded) {\n return void 0;\n }\n }\n const results = /* @__PURE__ */ Object.create(null);\n encoded ??= /[%+]/.test(url);\n let keyIndex = url.indexOf(\"?\", 8);\n while (keyIndex !== -1) {\n const nextKeyIndex = url.indexOf(\"&\", keyIndex + 1);\n let valueIndex = url.indexOf(\"=\", keyIndex);\n if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {\n valueIndex = -1;\n }\n let name = url.slice(\n keyIndex + 1,\n valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex\n );\n if (encoded) {\n name = _decodeURI(name);\n }\n keyIndex = nextKeyIndex;\n if (name === \"\") {\n continue;\n }\n let value;\n if (valueIndex === -1) {\n value = \"\";\n } else {\n value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);\n if (encoded) {\n value = _decodeURI(value);\n }\n }\n if (multiple) {\n if (!(results[name] && Array.isArray(results[name]))) {\n results[name] = [];\n }\n ;\n results[name].push(value);\n } else {\n results[name] ??= value;\n }\n }\n return key ? results[key] : results;\n};\nvar getQueryParam = _getQueryParam;\nvar getQueryParams = (url, key) => {\n return _getQueryParam(url, key, true);\n};\nvar decodeURIComponent_ = decodeURIComponent;\nexport {\n checkOptionalParameter,\n decodeURIComponent_,\n getPath,\n getPathNoStrict,\n getPattern,\n getQueryParam,\n getQueryParams,\n getQueryStrings,\n mergePath,\n splitPath,\n splitRoutingPath,\n tryDecode,\n tryDecodeURI\n};\n", "// src/request.ts\nimport { HTTPException } from \"./http-exception.js\";\nimport { GET_MATCH_RESULT } from \"./request/constants.js\";\nimport { parseBody } from \"./utils/body.js\";\nimport { decodeURIComponent_, getQueryParam, getQueryParams, tryDecode } from \"./utils/url.js\";\nvar tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);\nvar HonoRequest = class {\n /**\n * `.raw` can get the raw Request object.\n *\n * @see {@link https://hono.dev/docs/api/request#raw}\n *\n * @example\n * ```ts\n * // For Cloudflare Workers\n * app.post('/', async (c) => {\n * const metadata = c.req.raw.cf?.hostMetadata?\n * ...\n * })\n * ```\n */\n raw;\n #validatedData;\n // Short name of validatedData\n #matchResult;\n routeIndex = 0;\n /**\n * `.path` can get the pathname of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#path}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const pathname = c.req.path // `/about/me`\n * })\n * ```\n */\n path;\n bodyCache = {};\n constructor(request, path = \"/\", matchResult = [[]]) {\n this.raw = request;\n this.path = path;\n this.#matchResult = matchResult;\n this.#validatedData = {};\n }\n param(key) {\n return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();\n }\n #getDecodedParam(key) {\n const paramKey = this.#matchResult[0][this.routeIndex][1][key];\n const param = this.#getParamValue(paramKey);\n return param && /\\%/.test(param) ? tryDecodeURIComponent(param) : param;\n }\n #getAllDecodedParams() {\n const decoded = {};\n const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);\n for (const key of keys) {\n const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);\n if (value !== void 0) {\n decoded[key] = /\\%/.test(value) ? tryDecodeURIComponent(value) : value;\n }\n }\n return decoded;\n }\n #getParamValue(paramKey) {\n return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;\n }\n query(key) {\n return getQueryParam(this.url, key);\n }\n queries(key) {\n return getQueryParams(this.url, key);\n }\n header(name) {\n if (name) {\n return this.raw.headers.get(name) ?? void 0;\n }\n const headerData = /* @__PURE__ */ Object.create(null);\n this.raw.headers.forEach((value, key) => {\n headerData[key] = value;\n });\n return headerData;\n }\n async parseBody(options) {\n return parseBody(this, options);\n }\n #cachedBody = (key) => {\n const { bodyCache, raw } = this;\n const cachedBody = bodyCache[key];\n if (cachedBody) {\n return cachedBody;\n }\n const anyCachedKey = Object.keys(bodyCache)[0];\n if (anyCachedKey) {\n return bodyCache[anyCachedKey].then((body) => {\n if (anyCachedKey === \"json\") {\n body = JSON.stringify(body);\n }\n return new Response(body)[key]();\n });\n }\n return bodyCache[key] = raw[key]();\n };\n /**\n * `.json()` can parse Request body of type `application/json`\n *\n * @see {@link https://hono.dev/docs/api/request#json}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.json()\n * })\n * ```\n */\n json() {\n return this.#cachedBody(\"text\").then((text) => JSON.parse(text));\n }\n /**\n * `.text()` can parse Request body of type `text/plain`\n *\n * @see {@link https://hono.dev/docs/api/request#text}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.text()\n * })\n * ```\n */\n text() {\n return this.#cachedBody(\"text\");\n }\n /**\n * `.arrayBuffer()` parse Request body as an `ArrayBuffer`\n *\n * @see {@link https://hono.dev/docs/api/request#arraybuffer}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.arrayBuffer()\n * })\n * ```\n */\n arrayBuffer() {\n return this.#cachedBody(\"arrayBuffer\");\n }\n /**\n * `.bytes()` parses the request body as a `Uint8Array`.\n *\n * @see {@link https://hono.dev/docs/api/request#bytes}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.bytes()\n * })\n * ```\n */\n bytes() {\n return this.#cachedBody(\"arrayBuffer\").then((buffer) => new Uint8Array(buffer));\n }\n /**\n * Parses the request body as a `Blob`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.blob();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#blob\n */\n blob() {\n return this.#cachedBody(\"blob\");\n }\n /**\n * Parses the request body as `FormData`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.formData();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#formdata\n */\n formData() {\n return this.#cachedBody(\"formData\");\n }\n /**\n * Adds validated data to the request.\n *\n * @param target - The target of the validation.\n * @param data - The validated data to add.\n */\n addValidatedData(target, data) {\n this.#validatedData[target] = data;\n }\n valid(target) {\n return this.#validatedData[target];\n }\n /**\n * `.url()` can get the request url strings.\n *\n * @see {@link https://hono.dev/docs/api/request#url}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const url = c.req.url // `http://localhost:8787/about/me`\n * ...\n * })\n * ```\n */\n get url() {\n return this.raw.url;\n }\n /**\n * `.method()` can get the method name of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#method}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const method = c.req.method // `GET`\n * })\n * ```\n */\n get method() {\n return this.raw.method;\n }\n get [GET_MATCH_RESULT]() {\n return this.#matchResult;\n }\n /**\n * `.matchedRoutes()` can return a matched route in the handler\n *\n * @deprecated\n *\n * Use matchedRoutes helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#matchedroutes}\n *\n * @example\n * ```ts\n * app.use('*', async function logger(c, next) {\n * await next()\n * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {\n * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')\n * console.log(\n * method,\n * ' ',\n * path,\n * ' '.repeat(Math.max(10 - path.length, 0)),\n * name,\n * i === c.req.routeIndex ? '<- respond from here' : ''\n * )\n * })\n * })\n * ```\n */\n get matchedRoutes() {\n return this.#matchResult[0].map(([[, route]]) => route);\n }\n /**\n * `routePath()` can retrieve the path registered within the handler\n *\n * @deprecated\n *\n * Use routePath helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#routepath}\n *\n * @example\n * ```ts\n * app.get('/posts/:id', (c) => {\n * return c.json({ path: c.req.routePath })\n * })\n * ```\n */\n get routePath() {\n return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;\n }\n};\nvar cloneRawRequest = async (req) => {\n if (!req.raw.bodyUsed) {\n return req.raw.clone();\n }\n const cacheKey = Object.keys(req.bodyCache)[0];\n if (!cacheKey) {\n throw new HTTPException(500, {\n message: \"Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly.\"\n });\n }\n const body = await req[cacheKey]();\n const headers = req.header();\n if (body instanceof FormData) {\n delete headers[\"content-type\"];\n }\n const requestInit = {\n body,\n cache: req.raw.cache,\n credentials: req.raw.credentials,\n headers,\n integrity: req.raw.integrity,\n keepalive: req.raw.keepalive,\n method: req.method,\n mode: req.raw.mode,\n redirect: req.raw.redirect,\n referrer: req.raw.referrer,\n referrerPolicy: req.raw.referrerPolicy,\n signal: req.raw.signal\n };\n return new Request(req.url, requestInit);\n};\nexport {\n HonoRequest,\n cloneRawRequest\n};\n", "// src/utils/html.ts\nvar HtmlEscapedCallbackPhase = {\n Stringify: 1,\n BeforeStream: 2,\n Stream: 3\n};\nvar raw = (value, callbacks) => {\n const escapedString = new String(value);\n escapedString.isEscaped = true;\n escapedString.callbacks = callbacks;\n return escapedString;\n};\nvar escapeRe = /[&<>'\"]/;\nvar stringBufferToString = async (buffer, callbacks) => {\n let str = \"\";\n callbacks ||= [];\n const resolvedBuffer = await Promise.all(buffer);\n for (let i = resolvedBuffer.length - 1; ; i--) {\n str += resolvedBuffer[i];\n i--;\n if (i < 0) {\n break;\n }\n let r = resolvedBuffer[i];\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n const isEscaped = r.isEscaped;\n r = await (typeof r === \"object\" ? r.toString() : r);\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n if (r.isEscaped ?? isEscaped) {\n str += r;\n } else {\n const buf = [str];\n escapeToBuffer(r, buf);\n str = buf[0];\n }\n }\n return raw(str, callbacks);\n};\nvar escapeToBuffer = (str, buffer) => {\n const match = str.search(escapeRe);\n if (match === -1) {\n buffer[0] += str;\n return;\n }\n let escape;\n let index;\n let lastIndex = 0;\n for (index = match; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n escape = \""\";\n break;\n case 39:\n escape = \"'\";\n break;\n case 38:\n escape = \"&\";\n break;\n case 60:\n escape = \"<\";\n break;\n case 62:\n escape = \">\";\n break;\n default:\n continue;\n }\n buffer[0] += str.substring(lastIndex, index) + escape;\n lastIndex = index + 1;\n }\n buffer[0] += str.substring(lastIndex, index);\n};\nvar resolveCallbackSync = (str) => {\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return str;\n }\n const buffer = [str];\n const context = {};\n callbacks.forEach((c) => c({ phase: HtmlEscapedCallbackPhase.Stringify, buffer, context }));\n return buffer[0];\n};\nvar resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {\n if (typeof str === \"object\" && !(str instanceof String)) {\n if (!(str instanceof Promise)) {\n str = str.toString();\n }\n if (str instanceof Promise) {\n str = await str;\n }\n }\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return Promise.resolve(str);\n }\n if (buffer) {\n buffer[0] += str;\n } else {\n buffer = [str];\n }\n const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(\n (res) => Promise.all(\n res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))\n ).then(() => buffer[0])\n );\n if (preserveCallbacks) {\n return raw(await resStr, callbacks);\n } else {\n return resStr;\n }\n};\nexport {\n HtmlEscapedCallbackPhase,\n escapeToBuffer,\n raw,\n resolveCallback,\n resolveCallbackSync,\n stringBufferToString\n};\n", "// src/context.ts\nimport { HonoRequest } from \"./request.js\";\nimport { HtmlEscapedCallbackPhase, resolveCallback } from \"./utils/html.js\";\nvar TEXT_PLAIN = \"text/plain; charset=UTF-8\";\nvar setDefaultContentType = (contentType, headers) => {\n return {\n \"Content-Type\": contentType,\n ...headers\n };\n};\nvar createResponseInstance = (body, init) => new Response(body, init);\nvar Context = class {\n #rawRequest;\n #req;\n /**\n * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.\n *\n * @see {@link https://hono.dev/docs/api/context#env}\n *\n * @example\n * ```ts\n * // Environment object for Cloudflare Workers\n * app.get('*', async c => {\n * const counter = c.env.COUNTER\n * })\n * ```\n */\n env = {};\n #var;\n finalized = false;\n /**\n * `.error` can get the error object from the middleware if the Handler throws an error.\n *\n * @see {@link https://hono.dev/docs/api/context#error}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * await next()\n * if (c.error) {\n * // do something...\n * }\n * })\n * ```\n */\n error;\n #status;\n #executionCtx;\n #res;\n #layout;\n #renderer;\n #notFoundHandler;\n #preparedHeaders;\n #matchResult;\n #path;\n /**\n * Creates an instance of the Context class.\n *\n * @param req - The Request object.\n * @param options - Optional configuration options for the context.\n */\n constructor(req, options) {\n this.#rawRequest = req;\n if (options) {\n this.#executionCtx = options.executionCtx;\n this.env = options.env;\n this.#notFoundHandler = options.notFoundHandler;\n this.#path = options.path;\n this.#matchResult = options.matchResult;\n }\n }\n /**\n * `.req` is the instance of {@link HonoRequest}.\n */\n get req() {\n this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);\n return this.#req;\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#event}\n * The FetchEvent associated with the current request.\n *\n * @throws Will throw an error if the context does not have a FetchEvent.\n */\n get event() {\n if (this.#executionCtx && \"respondWith\" in this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no FetchEvent\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#executionctx}\n * The ExecutionContext associated with the current request.\n *\n * @throws Will throw an error if the context does not have an ExecutionContext.\n */\n get executionCtx() {\n if (this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no ExecutionContext\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#res}\n * The Response object for the current request.\n */\n get res() {\n return this.#res ||= createResponseInstance(null, {\n headers: this.#preparedHeaders ??= new Headers()\n });\n }\n /**\n * Sets the Response object for the current request.\n *\n * @param _res - The Response object to set.\n */\n set res(_res) {\n if (this.#res && _res) {\n _res = createResponseInstance(_res.body, _res);\n for (const [k, v] of this.#res.headers.entries()) {\n if (k === \"content-type\") {\n continue;\n }\n if (k === \"set-cookie\") {\n const cookies = this.#res.headers.getSetCookie();\n _res.headers.delete(\"set-cookie\");\n for (const cookie of cookies) {\n _res.headers.append(\"set-cookie\", cookie);\n }\n } else {\n _res.headers.set(k, v);\n }\n }\n }\n this.#res = _res;\n this.finalized = true;\n }\n /**\n * `.render()` can create a response within a layout.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * return c.render('Hello!')\n * })\n * ```\n */\n render = (...args) => {\n this.#renderer ??= (content) => this.html(content);\n return this.#renderer(...args);\n };\n /**\n * Sets the layout for the response.\n *\n * @param layout - The layout to set.\n * @returns The layout function.\n */\n setLayout = (layout) => this.#layout = layout;\n /**\n * Gets the current layout for the response.\n *\n * @returns The current layout function.\n */\n getLayout = () => this.#layout;\n /**\n * `.setRenderer()` can set the layout in the custom middleware.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```tsx\n * app.use('*', async (c, next) => {\n * c.setRenderer((content) => {\n * return c.html(\n * <html>\n * <body>\n * <p>{content}</p>\n * </body>\n * </html>\n * )\n * })\n * await next()\n * })\n * ```\n */\n setRenderer = (renderer) => {\n this.#renderer = renderer;\n };\n /**\n * `.header()` can set headers.\n *\n * @see {@link https://hono.dev/docs/api/context#header}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n *\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n header = (name, value, options) => {\n if (this.finalized) {\n this.#res = createResponseInstance(this.#res.body, this.#res);\n }\n const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();\n if (value === void 0) {\n headers.delete(name);\n } else if (options?.append) {\n headers.append(name, value);\n } else {\n headers.set(name, value);\n }\n };\n status = (status) => {\n this.#status = status;\n };\n /**\n * `.set()` can set the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * c.set('message', 'Hono is hot!!')\n * await next()\n * })\n * ```\n */\n set = (key, value) => {\n this.#var ??= /* @__PURE__ */ new Map();\n this.#var.set(key, value);\n };\n /**\n * `.get()` can use the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * const message = c.get('message')\n * return c.text(`The message is \"${message}\"`)\n * })\n * ```\n */\n get = (key) => {\n return this.#var ? this.#var.get(key) : void 0;\n };\n /**\n * `.var` can access the value of a variable.\n *\n * @see {@link https://hono.dev/docs/api/context#var}\n *\n * @example\n * ```ts\n * const result = c.var.client.oneMethod()\n * ```\n */\n // c.var.propName is a read-only\n get var() {\n if (!this.#var) {\n return {};\n }\n return Object.fromEntries(this.#var);\n }\n #newResponse(data, arg, headers) {\n const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();\n if (typeof arg === \"object\" && \"headers\" in arg) {\n const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);\n for (const [key, value] of argHeaders) {\n if (key.toLowerCase() === \"set-cookie\") {\n responseHeaders.append(key, value);\n } else {\n responseHeaders.set(key, value);\n }\n }\n }\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (typeof v === \"string\") {\n responseHeaders.set(k, v);\n } else {\n responseHeaders.delete(k);\n for (const v2 of v) {\n responseHeaders.append(k, v2);\n }\n }\n }\n }\n const status = typeof arg === \"number\" ? arg : arg?.status ?? this.#status;\n return createResponseInstance(data, { status, headers: responseHeaders });\n }\n newResponse = (...args) => this.#newResponse(...args);\n /**\n * `.body()` can return the HTTP response.\n * You can set headers with `.header()` and set HTTP status code with `.status`.\n * This can also be set in `.text()`, `.json()` and so on.\n *\n * @see {@link https://hono.dev/docs/api/context#body}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n * // Set HTTP status code\n * c.status(201)\n *\n * // Return the response body\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n body = (data, arg, headers) => this.#newResponse(data, arg, headers);\n /**\n * `.text()` can render text as `Content-Type:text/plain`.\n *\n * @see {@link https://hono.dev/docs/api/context#text}\n *\n * @example\n * ```ts\n * app.get('/say', (c) => {\n * return c.text('Hello!')\n * })\n * ```\n */\n text = (text, arg, headers) => {\n return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(\n text,\n arg,\n setDefaultContentType(TEXT_PLAIN, headers)\n );\n };\n /**\n * `.json()` can render JSON as `Content-Type:application/json`.\n *\n * @see {@link https://hono.dev/docs/api/context#json}\n *\n * @example\n * ```ts\n * app.get('/api', (c) => {\n * return c.json({ message: 'Hello!' })\n * })\n * ```\n */\n json = (object, arg, headers) => {\n return this.#newResponse(\n JSON.stringify(object),\n arg,\n setDefaultContentType(\"application/json\", headers)\n );\n };\n html = (html, arg, headers) => {\n const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType(\"text/html; charset=UTF-8\", headers));\n return typeof html === \"object\" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);\n };\n /**\n * `.redirect()` can Redirect, default status code is 302.\n *\n * @see {@link https://hono.dev/docs/api/context#redirect}\n *\n * @example\n * ```ts\n * app.get('/redirect', (c) => {\n * return c.redirect('/')\n * })\n * app.get('/redirect-permanently', (c) => {\n * return c.redirect('/', 301)\n * })\n * ```\n */\n redirect = (location, status) => {\n const locationString = String(location);\n this.header(\n \"Location\",\n // Multibyes should be encoded\n // eslint-disable-next-line no-control-regex\n !/[^\\x00-\\xFF]/.test(locationString) ? locationString : encodeURI(locationString)\n );\n return this.newResponse(null, status ?? 302);\n };\n /**\n * `.notFound()` can return the Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/context#notfound}\n *\n * @example\n * ```ts\n * app.get('/notfound', (c) => {\n * return c.notFound()\n * })\n * ```\n */\n notFound = () => {\n this.#notFoundHandler ??= () => createResponseInstance();\n return this.#notFoundHandler(this);\n };\n};\nexport {\n Context,\n TEXT_PLAIN\n};\n", "// src/router.ts\nvar METHOD_NAME_ALL = \"ALL\";\nvar METHOD_NAME_ALL_LOWERCASE = \"all\";\nvar METHODS = [\"get\", \"post\", \"put\", \"delete\", \"options\", \"patch\"];\nvar MESSAGE_MATCHER_IS_ALREADY_BUILT = \"Can not add a route since the matcher is already built.\";\nvar UnsupportedPathError = class extends Error {\n};\nexport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHODS,\n METHOD_NAME_ALL,\n METHOD_NAME_ALL_LOWERCASE,\n UnsupportedPathError\n};\n", "// src/utils/constants.ts\nvar COMPOSED_HANDLER = \"__COMPOSED_HANDLER\";\nexport {\n COMPOSED_HANDLER\n};\n", "// src/hono-base.ts\nimport { compose } from \"./compose.js\";\nimport { Context } from \"./context.js\";\nimport { METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE } from \"./router.js\";\nimport { COMPOSED_HANDLER } from \"./utils/constants.js\";\nimport { getPath, getPathNoStrict, mergePath } from \"./utils/url.js\";\nvar notFoundHandler = (c) => {\n return c.text(\"404 Not Found\", 404);\n};\nvar errorHandler = (err, c) => {\n if (\"getResponse\" in err) {\n const res = err.getResponse();\n return c.newResponse(res.body, res);\n }\n console.error(err);\n return c.text(\"Internal Server Error\", 500);\n};\nvar Hono = class _Hono {\n get;\n post;\n put;\n delete;\n options;\n patch;\n all;\n on;\n use;\n /*\n This class is like an abstract class and does not have a router.\n To use it, inherit the class and implement router in the constructor.\n */\n router;\n getPath;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n _basePath = \"/\";\n #path = \"/\";\n routes = [];\n constructor(options = {}) {\n const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];\n allMethods.forEach((method) => {\n this[method] = (args1, ...args) => {\n if (typeof args1 === \"string\") {\n this.#path = args1;\n } else {\n this.#addRoute(method, this.#path, args1);\n }\n args.forEach((handler) => {\n this.#addRoute(method, this.#path, handler);\n });\n return this;\n };\n });\n this.on = (method, path, ...handlers) => {\n for (const p of [path].flat()) {\n this.#path = p;\n for (const m of [method].flat()) {\n handlers.map((handler) => {\n this.#addRoute(m.toUpperCase(), this.#path, handler);\n });\n }\n }\n return this;\n };\n this.use = (arg1, ...handlers) => {\n if (typeof arg1 === \"string\") {\n this.#path = arg1;\n } else {\n this.#path = \"*\";\n handlers.unshift(arg1);\n }\n handlers.forEach((handler) => {\n this.#addRoute(METHOD_NAME_ALL, this.#path, handler);\n });\n return this;\n };\n const { strict, ...optionsWithoutStrict } = options;\n Object.assign(this, optionsWithoutStrict);\n this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;\n }\n #clone() {\n const clone = new _Hono({\n router: this.router,\n getPath: this.getPath\n });\n clone.errorHandler = this.errorHandler;\n clone.#notFoundHandler = this.#notFoundHandler;\n clone.routes = this.routes;\n return clone;\n }\n #notFoundHandler = notFoundHandler;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n errorHandler = errorHandler;\n /**\n * `.route()` allows grouping other Hono instance in routes.\n *\n * @see {@link https://hono.dev/docs/api/routing#grouping}\n *\n * @param {string} path - base Path\n * @param {Hono} app - other Hono instance\n * @returns {Hono} routed Hono instance\n *\n * @example\n * ```ts\n * const app = new Hono()\n * const app2 = new Hono()\n *\n * app2.get(\"/user\", (c) => c.text(\"user\"))\n * app.route(\"/api\", app2) // GET /api/user\n * ```\n */\n route(path, app) {\n const subApp = this.basePath(path);\n app.routes.map((r) => {\n let handler;\n if (app.errorHandler === errorHandler) {\n handler = r.handler;\n } else {\n handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;\n handler[COMPOSED_HANDLER] = r.handler;\n }\n subApp.#addRoute(r.method, r.path, handler, r.basePath);\n });\n return this;\n }\n /**\n * `.basePath()` allows base paths to be specified.\n *\n * @see {@link https://hono.dev/docs/api/routing#base-path}\n *\n * @param {string} path - base Path\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * const api = new Hono().basePath('/api')\n * ```\n */\n basePath(path) {\n const subApp = this.#clone();\n subApp._basePath = mergePath(this._basePath, path);\n return subApp;\n }\n /**\n * `.onError()` handles an error and returns a customized Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#error-handling}\n *\n * @param {ErrorHandler} handler - request Handler for error\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.onError((err, c) => {\n * console.error(`${err}`)\n * return c.text('Custom Error Message', 500)\n * })\n * ```\n */\n onError = (handler) => {\n this.errorHandler = handler;\n return this;\n };\n /**\n * `.notFound()` allows you to customize a Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#not-found}\n *\n * @param {NotFoundHandler} handler - request handler for not-found\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.notFound((c) => {\n * return c.text('Custom 404 Message', 404)\n * })\n * ```\n */\n notFound = (handler) => {\n this.#notFoundHandler = handler;\n return this;\n };\n /**\n * `.mount()` allows you to mount applications built with other frameworks into your Hono application.\n *\n * @see {@link https://hono.dev/docs/api/hono#mount}\n *\n * @param {string} path - base Path\n * @param {Function} applicationHandler - other Request Handler\n * @param {MountOptions} [options] - options of `.mount()`\n * @returns {Hono} mounted Hono instance\n *\n * @example\n * ```ts\n * import { Router as IttyRouter } from 'itty-router'\n * import { Hono } from 'hono'\n * // Create itty-router application\n * const ittyRouter = IttyRouter()\n * // GET /itty-router/hello\n * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))\n *\n * const app = new Hono()\n * app.mount('/itty-router', ittyRouter.handle)\n * ```\n *\n * @example\n * ```ts\n * const app = new Hono()\n * // Send the request to another application without modification.\n * app.mount('/app', anotherApp, {\n * replaceRequest: (req) => req,\n * })\n * ```\n */\n mount(path, applicationHandler, options) {\n let replaceRequest;\n let optionHandler;\n if (options) {\n if (typeof options === \"function\") {\n optionHandler = options;\n } else {\n optionHandler = options.optionHandler;\n if (options.replaceRequest === false) {\n replaceRequest = (request) => request;\n } else {\n replaceRequest = options.replaceRequest;\n }\n }\n }\n const getOptions = optionHandler ? (c) => {\n const options2 = optionHandler(c);\n return Array.isArray(options2) ? options2 : [options2];\n } : (c) => {\n let executionContext = void 0;\n try {\n executionContext = c.executionCtx;\n } catch {\n }\n return [c.env, executionContext];\n };\n replaceRequest ||= (() => {\n const mergedPath = mergePath(this._basePath, path);\n const pathPrefixLength = mergedPath === \"/\" ? 0 : mergedPath.length;\n return (request) => {\n const url = new URL(request.url);\n url.pathname = this.getPath(request).slice(pathPrefixLength) || \"/\";\n return new Request(url, request);\n };\n })();\n const handler = async (c, next) => {\n const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));\n if (res) {\n return res;\n }\n await next();\n };\n this.#addRoute(METHOD_NAME_ALL, mergePath(path, \"*\"), handler);\n return this;\n }\n #addRoute(method, path, handler, baseRoutePath) {\n method = method.toUpperCase();\n path = mergePath(this._basePath, path);\n const r = {\n basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,\n path,\n method,\n handler\n };\n this.router.add(method, path, [handler, r]);\n this.routes.push(r);\n }\n #handleError(err, c) {\n if (err instanceof Error) {\n return this.errorHandler(err, c);\n }\n throw err;\n }\n #dispatch(request, executionCtx, env, method) {\n if (method === \"HEAD\") {\n return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, \"GET\")))();\n }\n const path = this.getPath(request, { env });\n const matchResult = this.router.match(method, path);\n const c = new Context(request, {\n path,\n matchResult,\n env,\n executionCtx,\n notFoundHandler: this.#notFoundHandler\n });\n if (matchResult[0].length === 1) {\n let res;\n try {\n res = matchResult[0][0][0][0](c, async () => {\n c.res = await this.#notFoundHandler(c);\n });\n } catch (err) {\n return this.#handleError(err, c);\n }\n return res instanceof Promise ? res.then(\n (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))\n ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);\n }\n const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);\n return (async () => {\n try {\n const context = await composed(c);\n if (!context.finalized) {\n throw new Error(\n \"Context is not finalized. Did you forget to return a Response object or `await next()`?\"\n );\n }\n return context.res;\n } catch (err) {\n return this.#handleError(err, c);\n }\n })();\n }\n /**\n * `.fetch()` will be entry point of your app.\n *\n * @see {@link https://hono.dev/docs/api/hono#fetch}\n *\n * @param {Request} request - request Object of request\n * @param {Env} Env - env Object\n * @param {ExecutionContext} - context of execution\n * @returns {Response | Promise<Response>} response of request\n *\n */\n fetch = (request, ...rest) => {\n return this.#dispatch(request, rest[1], rest[0], request.method);\n };\n /**\n * `.request()` is a useful method for testing.\n * You can pass a URL or pathname to send a GET request.\n * app will return a Response object.\n * ```ts\n * test('GET /hello is ok', async () => {\n * const res = await app.request('/hello')\n * expect(res.status).toBe(200)\n * })\n * ```\n * @see https://hono.dev/docs/api/hono#request\n */\n request = (input, requestInit, Env, executionCtx) => {\n if (input instanceof Request) {\n return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);\n }\n input = input.toString();\n return this.fetch(\n new Request(\n /^https?:\\/\\//.test(input) ? input : `http://localhost${mergePath(\"/\", input)}`,\n requestInit\n ),\n Env,\n executionCtx\n );\n };\n /**\n * `.fire()` automatically adds a global fetch event listener.\n * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.\n * @deprecated\n * Use `fire` from `hono/service-worker` instead.\n * ```ts\n * import { Hono } from 'hono'\n * import { fire } from 'hono/service-worker'\n *\n * const app = new Hono()\n * // ...\n * fire(app)\n * ```\n * @see https://hono.dev/docs/api/hono#fire\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API\n * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/\n */\n fire = () => {\n addEventListener(\"fetch\", (event) => {\n event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));\n });\n };\n};\nexport {\n Hono as HonoBase\n};\n", "// src/router/reg-exp-router/matcher.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nvar emptyParam = [];\nfunction match(method, path) {\n const matchers = this.buildAllMatchers();\n const match2 = ((method2, path2) => {\n const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];\n const staticMatch = matcher[2][path2];\n if (staticMatch) {\n return staticMatch;\n }\n const match3 = path2.match(matcher[0]);\n if (!match3) {\n return [[], emptyParam];\n }\n const index = match3.indexOf(\"\", 1);\n return [matcher[1][index], match3];\n });\n this.match = match2;\n return match2(method, path);\n}\nexport {\n emptyParam,\n match\n};\n", "// src/router/reg-exp-router/node.ts\nvar LABEL_REG_EXP_STR = \"[^/]+\";\nvar ONLY_WILDCARD_REG_EXP_STR = \".*\";\nvar TAIL_WILDCARD_REG_EXP_STR = \"(?:|/.*)\";\nvar PATH_ERROR = /* @__PURE__ */ Symbol();\nvar regExpMetaChars = new Set(\".\\\\+*[^]$()\");\nfunction compareKey(a, b) {\n if (a.length === 1) {\n return b.length === 1 ? a < b ? -1 : 1 : -1;\n }\n if (b.length === 1) {\n return 1;\n }\n if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {\n return 1;\n } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {\n return -1;\n }\n if (a === LABEL_REG_EXP_STR) {\n return 1;\n } else if (b === LABEL_REG_EXP_STR) {\n return -1;\n }\n return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;\n}\nvar Node = class _Node {\n #index;\n #varIndex;\n #children = /* @__PURE__ */ Object.create(null);\n insert(tokens, index, paramMap, context, pathErrorCheckOnly) {\n if (tokens.length === 0) {\n if (this.#index !== void 0) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n this.#index = index;\n return;\n }\n const [token, ...restTokens] = tokens;\n const pattern = token === \"*\" ? restTokens.length === 0 ? [\"\", \"\", ONLY_WILDCARD_REG_EXP_STR] : [\"\", \"\", LABEL_REG_EXP_STR] : token === \"/*\" ? [\"\", \"\", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n let node;\n if (pattern) {\n const name = pattern[1];\n let regexpStr = pattern[2] || LABEL_REG_EXP_STR;\n if (name && pattern[2]) {\n if (regexpStr === \".*\") {\n throw PATH_ERROR;\n }\n regexpStr = regexpStr.replace(/^\\((?!\\?:)(?=[^)]+\\)$)/, \"(?:\");\n if (/\\((?!\\?:)/.test(regexpStr)) {\n throw PATH_ERROR;\n }\n }\n node = this.#children[regexpStr];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[regexpStr] = new _Node();\n if (name !== \"\") {\n node.#varIndex = context.varIndex++;\n }\n }\n if (!pathErrorCheckOnly && name !== \"\") {\n paramMap.push([name, node.#varIndex]);\n }\n } else {\n node = this.#children[token];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[token] = new _Node();\n }\n }\n node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);\n }\n buildRegExpStr() {\n const childKeys = Object.keys(this.#children).sort(compareKey);\n const strList = childKeys.map((k) => {\n const c = this.#children[k];\n return (typeof c.#varIndex === \"number\" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\\\${k}` : k) + c.buildRegExpStr();\n });\n if (typeof this.#index === \"number\") {\n strList.unshift(`#${this.#index}`);\n }\n if (strList.length === 0) {\n return \"\";\n }\n if (strList.length === 1) {\n return strList[0];\n }\n return \"(?:\" + strList.join(\"|\") + \")\";\n }\n};\nexport {\n Node,\n PATH_ERROR\n};\n", "// src/router/reg-exp-router/trie.ts\nimport { Node } from \"./node.js\";\nvar Trie = class {\n #context = { varIndex: 0 };\n #root = new Node();\n insert(path, index, pathErrorCheckOnly) {\n const paramAssoc = [];\n const groups = [];\n for (let i = 0; ; ) {\n let replaced = false;\n path = path.replace(/\\{[^}]+\\}/g, (m) => {\n const mark = `@\\\\${i}`;\n groups[i] = [mark, m];\n i++;\n replaced = true;\n return mark;\n });\n if (!replaced) {\n break;\n }\n }\n const tokens = path.match(/(?::[^\\/]+)|(?:\\/\\*$)|./g) || [];\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = tokens.length - 1; j >= 0; j--) {\n if (tokens[j].indexOf(mark) !== -1) {\n tokens[j] = tokens[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);\n return paramAssoc;\n }\n buildRegExp() {\n let regexp = this.#root.buildRegExpStr();\n if (regexp === \"\") {\n return [/^$/, [], []];\n }\n let captureIndex = 0;\n const indexReplacementMap = [];\n const paramReplacementMap = [];\n regexp = regexp.replace(/#(\\d+)|@(\\d+)|\\.\\*\\$/g, (_, handlerIndex, paramIndex) => {\n if (handlerIndex !== void 0) {\n indexReplacementMap[++captureIndex] = Number(handlerIndex);\n return \"$()\";\n }\n if (paramIndex !== void 0) {\n paramReplacementMap[Number(paramIndex)] = ++captureIndex;\n return \"\";\n }\n return \"\";\n });\n return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];\n }\n};\nexport {\n Trie\n};\n", "// src/router/reg-exp-router/router.ts\nimport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHOD_NAME_ALL,\n UnsupportedPathError\n} from \"../../router.js\";\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { match, emptyParam } from \"./matcher.js\";\nimport { PATH_ERROR } from \"./node.js\";\nimport { Trie } from \"./trie.js\";\nvar nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];\nvar wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\nfunction buildWildcardRegExp(path) {\n return wildcardRegExpCache[path] ??= new RegExp(\n path === \"*\" ? \"\" : `^${path.replace(\n /\\/\\*$|([.\\\\+*[^\\]$()])/g,\n (_, metaChar) => metaChar ? `\\\\${metaChar}` : \"(?:|/.*)\"\n )}$`\n );\n}\nfunction clearWildcardRegExpCache() {\n wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\n}\nfunction buildMatcherFromPreprocessedRoutes(routes) {\n const trie = new Trie();\n const handlerData = [];\n if (routes.length === 0) {\n return nullMatcher;\n }\n const routesWithStaticPathFlag = routes.map(\n (route) => [!/\\*|\\/:/.test(route[0]), ...route]\n ).sort(\n ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length\n );\n const staticMap = /* @__PURE__ */ Object.create(null);\n for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {\n const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];\n if (pathErrorCheckOnly) {\n staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];\n } else {\n j++;\n }\n let paramAssoc;\n try {\n paramAssoc = trie.insert(path, j, pathErrorCheckOnly);\n } catch (e) {\n throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;\n }\n if (pathErrorCheckOnly) {\n continue;\n }\n handlerData[j] = handlers.map(([h, paramCount]) => {\n const paramIndexMap = /* @__PURE__ */ Object.create(null);\n paramCount -= 1;\n for (; paramCount >= 0; paramCount--) {\n const [key, value] = paramAssoc[paramCount];\n paramIndexMap[key] = value;\n }\n return [h, paramIndexMap];\n });\n }\n const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();\n for (let i = 0, len = handlerData.length; i < len; i++) {\n for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {\n const map = handlerData[i][j]?.[1];\n if (!map) {\n continue;\n }\n const keys = Object.keys(map);\n for (let k = 0, len3 = keys.length; k < len3; k++) {\n map[keys[k]] = paramReplacementMap[map[keys[k]]];\n }\n }\n }\n const handlerMap = [];\n for (const i in indexReplacementMap) {\n handlerMap[i] = handlerData[indexReplacementMap[i]];\n }\n return [regexp, handlerMap, staticMap];\n}\nfunction findMiddleware(middleware, path) {\n if (!middleware) {\n return void 0;\n }\n for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {\n if (buildWildcardRegExp(k).test(path)) {\n return [...middleware[k]];\n }\n }\n return void 0;\n}\nvar RegExpRouter = class {\n name = \"RegExpRouter\";\n #middleware;\n #routes;\n constructor() {\n this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n }\n add(method, path, handler) {\n const middleware = this.#middleware;\n const routes = this.#routes;\n if (!middleware || !routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n if (!middleware[method]) {\n ;\n [middleware, routes].forEach((handlerMap) => {\n handlerMap[method] = /* @__PURE__ */ Object.create(null);\n Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {\n handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];\n });\n });\n }\n if (path === \"/*\") {\n path = \"*\";\n }\n const paramCount = (path.match(/\\/:/g) || []).length;\n if (/\\*$/.test(path)) {\n const re = buildWildcardRegExp(path);\n if (method === METHOD_NAME_ALL) {\n Object.keys(middleware).forEach((m) => {\n middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n });\n } else {\n middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n }\n Object.keys(middleware).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(middleware[m]).forEach((p) => {\n re.test(p) && middleware[m][p].push([handler, paramCount]);\n });\n }\n });\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(routes[m]).forEach(\n (p) => re.test(p) && routes[m][p].push([handler, paramCount])\n );\n }\n });\n return;\n }\n const paths = checkOptionalParameter(path) || [path];\n for (let i = 0, len = paths.length; i < len; i++) {\n const path2 = paths[i];\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n routes[m][path2] ||= [\n ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []\n ];\n routes[m][path2].push([handler, paramCount - len + i + 1]);\n }\n });\n }\n }\n match = match;\n buildAllMatchers() {\n const matchers = /* @__PURE__ */ Object.create(null);\n Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {\n matchers[method] ||= this.#buildMatcher(method);\n });\n this.#middleware = this.#routes = void 0;\n clearWildcardRegExpCache();\n return matchers;\n }\n #buildMatcher(method) {\n const routes = [];\n let hasOwnRoute = method === METHOD_NAME_ALL;\n [this.#middleware, this.#routes].forEach((r) => {\n const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];\n if (ownRoute.length !== 0) {\n hasOwnRoute ||= true;\n routes.push(...ownRoute);\n } else if (method !== METHOD_NAME_ALL) {\n routes.push(\n ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])\n );\n }\n });\n if (!hasOwnRoute) {\n return null;\n } else {\n return buildMatcherFromPreprocessedRoutes(routes);\n }\n }\n};\nexport {\n RegExpRouter\n};\n", "// src/router/smart-router/router.ts\nimport { MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError } from \"../../router.js\";\nvar SmartRouter = class {\n name = \"SmartRouter\";\n #routers = [];\n #routes = [];\n constructor(init) {\n this.#routers = init.routers;\n }\n add(method, path, handler) {\n if (!this.#routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n this.#routes.push([method, path, handler]);\n }\n match(method, path) {\n if (!this.#routes) {\n throw new Error(\"Fatal error\");\n }\n const routers = this.#routers;\n const routes = this.#routes;\n const len = routers.length;\n let i = 0;\n let res;\n for (; i < len; i++) {\n const router = routers[i];\n try {\n for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {\n router.add(...routes[i2]);\n }\n res = router.match(method, path);\n } catch (e) {\n if (e instanceof UnsupportedPathError) {\n continue;\n }\n throw e;\n }\n this.match = router.match.bind(router);\n this.#routers = [router];\n this.#routes = void 0;\n break;\n }\n if (i === len) {\n throw new Error(\"Fatal error\");\n }\n this.name = `SmartRouter + ${this.activeRouter.name}`;\n return res;\n }\n get activeRouter() {\n if (this.#routes || this.#routers.length !== 1) {\n throw new Error(\"No active router has been determined yet.\");\n }\n return this.#routers[0];\n }\n};\nexport {\n SmartRouter\n};\n", "// src/router/trie-router/node.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nimport { getPattern, splitPath, splitRoutingPath } from \"../../utils/url.js\";\nvar emptyParams = /* @__PURE__ */ Object.create(null);\nvar hasChildren = (children) => {\n for (const _ in children) {\n return true;\n }\n return false;\n};\nvar Node = class _Node {\n #methods;\n #children;\n #patterns;\n #order = 0;\n #params = emptyParams;\n constructor(method, handler, children) {\n this.#children = children || /* @__PURE__ */ Object.create(null);\n this.#methods = [];\n if (method && handler) {\n const m = /* @__PURE__ */ Object.create(null);\n m[method] = { handler, possibleKeys: [], score: 0 };\n this.#methods = [m];\n }\n this.#patterns = [];\n }\n insert(method, path, handler) {\n this.#order = ++this.#order;\n let curNode = this;\n const parts = splitRoutingPath(path);\n const possibleKeys = [];\n for (let i = 0, len = parts.length; i < len; i++) {\n const p = parts[i];\n const nextP = parts[i + 1];\n const pattern = getPattern(p, nextP);\n const key = Array.isArray(pattern) ? pattern[0] : p;\n if (key in curNode.#children) {\n curNode = curNode.#children[key];\n if (pattern) {\n possibleKeys.push(pattern[1]);\n }\n continue;\n }\n curNode.#children[key] = new _Node();\n if (pattern) {\n curNode.#patterns.push(pattern);\n possibleKeys.push(pattern[1]);\n }\n curNode = curNode.#children[key];\n }\n curNode.#methods.push({\n [method]: {\n handler,\n possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),\n score: this.#order\n }\n });\n return curNode;\n }\n #pushHandlerSets(handlerSets, node, method, nodeParams, params) {\n for (let i = 0, len = node.#methods.length; i < len; i++) {\n const m = node.#methods[i];\n const handlerSet = m[method] || m[METHOD_NAME_ALL];\n const processedSet = {};\n if (handlerSet !== void 0) {\n handlerSet.params = /* @__PURE__ */ Object.create(null);\n handlerSets.push(handlerSet);\n if (nodeParams !== emptyParams || params && params !== emptyParams) {\n for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {\n const key = handlerSet.possibleKeys[i2];\n const processed = processedSet[handlerSet.score];\n handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];\n processedSet[handlerSet.score] = true;\n }\n }\n }\n }\n }\n search(method, path) {\n const handlerSets = [];\n this.#params = emptyParams;\n const curNode = this;\n let curNodes = [curNode];\n const parts = splitPath(path);\n const curNodesQueue = [];\n const len = parts.length;\n let partOffsets = null;\n for (let i = 0; i < len; i++) {\n const part = parts[i];\n const isLast = i === len - 1;\n const tempNodes = [];\n for (let j = 0, len2 = curNodes.length; j < len2; j++) {\n const node = curNodes[j];\n const nextNode = node.#children[part];\n if (nextNode) {\n nextNode.#params = node.#params;\n if (isLast) {\n if (nextNode.#children[\"*\"]) {\n this.#pushHandlerSets(handlerSets, nextNode.#children[\"*\"], method, node.#params);\n }\n this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);\n } else {\n tempNodes.push(nextNode);\n }\n }\n for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {\n const pattern = node.#patterns[k];\n const params = node.#params === emptyParams ? {} : { ...node.#params };\n if (pattern === \"*\") {\n const astNode = node.#children[\"*\"];\n if (astNode) {\n this.#pushHandlerSets(handlerSets, astNode, method, node.#params);\n astNode.#params = params;\n tempNodes.push(astNode);\n }\n continue;\n }\n const [key, name, matcher] = pattern;\n if (!part && !(matcher instanceof RegExp)) {\n continue;\n }\n const child = node.#children[key];\n if (matcher instanceof RegExp) {\n if (partOffsets === null) {\n partOffsets = new Array(len);\n let offset = path[0] === \"/\" ? 1 : 0;\n for (let p = 0; p < len; p++) {\n partOffsets[p] = offset;\n offset += parts[p].length + 1;\n }\n }\n const restPathString = path.substring(partOffsets[i]);\n const m = matcher.exec(restPathString);\n if (m) {\n params[name] = m[0];\n this.#pushHandlerSets(handlerSets, child, method, node.#params, params);\n if (m[0].length === restPathString.length && child.#children[\"*\"]) {\n this.#pushHandlerSets(\n handlerSets,\n child.#children[\"*\"],\n method,\n node.#params,\n params\n );\n }\n if (hasChildren(child.#children)) {\n child.#params = params;\n const componentCount = m[0].match(/\\//)?.length ?? 0;\n const targetCurNodes = curNodesQueue[componentCount] ||= [];\n targetCurNodes.push(child);\n }\n continue;\n }\n }\n if (matcher === true || matcher.test(part)) {\n params[name] = part;\n if (isLast) {\n this.#pushHandlerSets(handlerSets, child, method, params, node.#params);\n if (child.#children[\"*\"]) {\n this.#pushHandlerSets(\n handlerSets,\n child.#children[\"*\"],\n method,\n params,\n node.#params\n );\n }\n } else {\n child.#params = params;\n tempNodes.push(child);\n }\n }\n }\n }\n const shifted = curNodesQueue.shift();\n curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;\n }\n if (handlerSets.length > 1) {\n handlerSets.sort((a, b) => {\n return a.score - b.score;\n });\n }\n return [handlerSets.map(({ handler, params }) => [handler, params])];\n }\n};\nexport {\n Node\n};\n", "// src/router/trie-router/router.ts\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { Node } from \"./node.js\";\nvar TrieRouter = class {\n name = \"TrieRouter\";\n #node;\n constructor() {\n this.#node = new Node();\n }\n add(method, path, handler) {\n const results = checkOptionalParameter(path);\n if (results) {\n for (let i = 0, len = results.length; i < len; i++) {\n this.#node.insert(method, results[i], handler);\n }\n return;\n }\n this.#node.insert(method, path, handler);\n }\n match(method, path) {\n return this.#node.search(method, path);\n }\n};\nexport {\n TrieRouter\n};\n", "// src/hono.ts\nimport { HonoBase } from \"./hono-base.js\";\nimport { RegExpRouter } from \"./router/reg-exp-router/index.js\";\nimport { SmartRouter } from \"./router/smart-router/index.js\";\nimport { TrieRouter } from \"./router/trie-router/index.js\";\nvar Hono = class extends HonoBase {\n /**\n * Creates an instance of the Hono class.\n *\n * @param options - Optional configuration options for the Hono instance.\n */\n constructor(options = {}) {\n super(options);\n this.router = options.router ?? new SmartRouter({\n routers: [new RegExpRouter(), new TrieRouter()]\n });\n }\n};\nexport {\n Hono\n};\n", "import {\n createEngineDatabase,\n createSqlAdapter,\n type SqlExecutor,\n type SqlResult,\n type SqlStatement,\n} from \"@hot-updater/plugin-core\";\nimport type { ToolingDatabase } from \"@hot-updater/plugin-core\";\n\n/** A D1 result, from the binding or the REST API. */\nexport interface D1ResultLike {\n readonly results?: readonly unknown[];\n readonly success?: boolean;\n readonly meta?: { readonly changes?: number };\n}\n\nexport class D1ExecutionError extends Error {\n readonly name = \"D1ExecutionError\";\n constructor() {\n super(\"D1 did not successfully execute every requested statement\");\n }\n}\n\nexport const toSqlResult = (result: D1ResultLike): SqlResult => {\n if (result.success === false) throw new D1ExecutionError();\n return {\n rows: (result.results ?? []) as Record<string, unknown>[],\n changes: result.meta?.changes ?? 0,\n };\n};\n\n/** D1 reports SQLite errors in the message; the SQL core classifies codes. */\nconst withSqliteCode = (error: unknown): unknown => {\n const message = error instanceof Error ? error.message : String(error);\n const code = /UNIQUE constraint failed|constraint failed: .*PRIMARY/iu.test(\n message,\n )\n ? \"SQLITE_CONSTRAINT_UNIQUE\"\n : /SQLITE_BUSY|database is locked/iu.test(message)\n ? \"SQLITE_BUSY\"\n : undefined;\n return code === undefined\n ? error\n : Object.assign(new Error(message, { cause: error }), { code });\n};\n\n/**\n * The most ops one write sends. Each statement of a batch is one query, a\n * Worker invocation allows 1,000 queries on the paid plan, and an op takes at\n * most two statements besides the batch's three.\n */\nexport const D1_MAX_OPS = 450;\n\n/**\n * Hot Updater's database on D1: the storage engine through the shared SQL\n * core, fenced by the schema settings. D1 has no interactive transactions,\n * so each write is one atomic batch that evaluates its guards first\n * (`_hu_write`).\n */\nexport const createD1Database = (runner: {\n query(statement: SqlStatement): Promise<SqlResult>;\n batch(statements: readonly SqlStatement[]): Promise<readonly SqlResult[]>;\n}): ToolingDatabase => {\n const executor: SqlExecutor = {\n dialect: \"sqlite\",\n execute: (statement) =>\n runner.query(statement).catch((error: unknown) => {\n throw withSqliteCode(error);\n }),\n batch: (statements) =>\n runner.batch(statements).catch((error: unknown) => {\n throw withSqliteCode(error);\n }),\n transaction: () => {\n throw new Error(\n \"D1 has no interactive transactions; writes are batches.\",\n );\n },\n };\n return createEngineDatabase({\n name: \"d1Database\",\n adapter: createSqlAdapter({ executor, maxOps: D1_MAX_OPS, maxParams: 100 }),\n });\n};\n", "import type { EngineDatabase } from \"@hot-updater/plugin-core\";\n\nimport {\n createD1Database,\n D1ExecutionError,\n type D1ResultLike,\n toSqlResult,\n} from \"../d1Executor\";\n\ntype D1BoundStatement = {\n all: () => Promise<D1ResultLike>;\n};\n\ntype D1PreparedStatement = {\n bind: (...values: readonly unknown[]) => D1BoundStatement;\n};\n\nexport type D1Like = {\n prepare(sql: string): D1PreparedStatement;\n batch(statements: D1BoundStatement[]): Promise<readonly D1ResultLike[]>;\n};\n\n/** Hot Updater's database on a D1 binding, inside a Worker. */\nexport const d1Database = (database: D1Like): EngineDatabase =>\n createD1Database({\n query: async ({ sql, params }) =>\n toSqlResult(\n await database\n .prepare(sql)\n .bind(...params)\n .all(),\n ),\n async batch(statements) {\n const results = await database.batch(\n statements.map(({ sql, params }) =>\n database.prepare(sql).bind(...params),\n ),\n );\n if (results.length !== statements.length) throw new D1ExecutionError();\n return results.map(toSqlResult);\n },\n });\n", "const encoder = new TextEncoder();\n\nconst hex = (bytes: ArrayBuffer) =>\n Array.from(new Uint8Array(bytes), (byte) =>\n byte.toString(16).padStart(2, \"0\"),\n ).join(\"\");\n\nconst hmac = async (key: BufferSource, value: string) =>\n crypto.subtle.sign(\n \"HMAC\",\n await crypto.subtle.importKey(\n \"raw\",\n key,\n { hash: \"SHA-256\", name: \"HMAC\" },\n false,\n [\"sign\"],\n ),\n encoder.encode(value),\n );\n\n/** RFC 3986 encoding, which S3 signs keys and query values in. */\nconst encodeRfc3986 = (value: string) =>\n encodeURIComponent(value).replace(\n /[!'()*]/g,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n\n/** R2's S3-compatible credentials. */\nexport interface R2Credentials {\n readonly accessKeyId: string;\n readonly secretAccessKey: string;\n}\n\n/**\n * A presigned GET URL for an object on R2's S3-compatible API: AWS Signature\n * Version 4 on Web Crypto, in the form `getSignedUrl` from\n * `@aws-sdk/s3-request-presigner` signs, so a Worker presigns without the\n * AWS SDK.\n */\nexport const presignR2GetUrl = async ({\n accountId,\n bucketName,\n credentials,\n expiresInSeconds,\n key,\n signingDate = new Date(),\n}: {\n readonly accountId: string;\n readonly bucketName: string;\n readonly credentials: R2Credentials;\n readonly expiresInSeconds: number;\n /** The object's key, unencoded. */\n readonly key: string;\n readonly signingDate?: Date;\n}): Promise<string> => {\n const host = `${accountId}.r2.cloudflarestorage.com`;\n const path = `/${bucketName}/${key.split(\"/\").map(encodeRfc3986).join(\"/\")}`;\n const amzDate = signingDate.toISOString().replace(/[-:]|\\.\\d{3}/g, \"\");\n const scope = `${amzDate.slice(0, 8)}/auto/s3/aws4_request`;\n // Sorted by name, as the canonical request orders them.\n const query: [string, string][] = [\n [\"X-Amz-Algorithm\", \"AWS4-HMAC-SHA256\"],\n [\"X-Amz-Content-Sha256\", \"UNSIGNED-PAYLOAD\"],\n [\"X-Amz-Credential\", `${credentials.accessKeyId}/${scope}`],\n [\"X-Amz-Date\", amzDate],\n [\"X-Amz-Expires\", String(expiresInSeconds)],\n [\"X-Amz-SignedHeaders\", \"host\"],\n [\"x-id\", \"GetObject\"],\n ];\n const queryString = (entries: [string, string][]) =>\n entries\n .map(([name, value]) => `${encodeRfc3986(name)}=${encodeRfc3986(value)}`)\n .join(\"&\");\n const canonicalRequest = [\n \"GET\",\n path,\n queryString(query),\n `host:${host}\\n`,\n \"host\",\n \"UNSIGNED-PAYLOAD\",\n ].join(\"\\n\");\n const stringToSign = [\n \"AWS4-HMAC-SHA256\",\n amzDate,\n scope,\n hex(\n await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalRequest)),\n ),\n ].join(\"\\n\");\n let signingKey: ArrayBuffer = encoder.encode(\n `AWS4${credentials.secretAccessKey}`,\n ).buffer as ArrayBuffer;\n for (const part of [amzDate.slice(0, 8), \"auto\", \"s3\", \"aws4_request\"]) {\n signingKey = await hmac(signingKey, part);\n }\n const signature = hex(await hmac(signingKey, stringToSign));\n const signed: [string, string][] = [\n ...query.slice(0, 5),\n [\"X-Amz-Signature\", signature],\n ...query.slice(5),\n ];\n return `https://${host}${path}?${queryString(signed)}`;\n};\n", "import {\n createStorageKeyBuilder,\n createStorageAdapter,\n createStorageUri,\n parseStorageUri,\n type StorageAdapterWith,\n} from \"@hot-updater/plugin-core\";\n\nimport { presignR2GetUrl, type R2Credentials } from \"./presignR2Url\";\n\nexport type CloudflareWorkerStorageConfig = {\n readonly bucket: R2Bucket;\n readonly bucketName: string;\n readonly basePath?: string;\n} & (\n | {\n /** The account whose R2 endpoint download URLs name. */\n readonly accountId: string;\n /**\n * R2's S3-compatible credentials, which presign download URLs, as\n * `r2Storage` from `@hot-updater/cloudflare` does: what a server needs\n * to serve downloads.\n */\n readonly credentials: R2Credentials;\n }\n | { readonly accountId?: undefined; readonly credentials?: undefined }\n);\n\n/** Devices download right after the update check that returns the URL. */\nconst PRESIGNED_URL_EXPIRES_IN_SECONDS = 3600;\n\n/**\n * Storage on the Worker's R2 binding. With R2's S3-compatible credentials,\n * its download URLs are presigned and devices download from the bucket;\n * without them, it has no `getDownloadUrl`, as a Console that only reads\n * needs.\n */\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig & {\n readonly credentials: R2Credentials;\n },\n): StorageAdapterWith<\"put\" | \"get\" | \"getDownloadUrl\" | \"exists\" | \"delete\">;\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig,\n): StorageAdapterWith<\"put\" | \"get\" | \"exists\" | \"delete\">;\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig,\n): StorageAdapterWith<\"put\" | \"get\" | \"exists\" | \"delete\"> {\n const getStorageKey = createStorageKeyBuilder(config.basePath);\n\n const parseAndValidate = (storageUri: string) => {\n const parsed = parseStorageUri(storageUri, \"r2\");\n if (parsed.bucket !== config.bucketName) {\n throw new Error(\n `Bucket name mismatch: expected \"${config.bucketName}\", but found \"${parsed.bucket}\".`,\n );\n }\n return parsed;\n };\n\n return createStorageAdapter({\n name: \"r2Storage\",\n protocol: \"r2\",\n async put({ key, body, contentLength, contentType }) {\n const storageKey = getStorageKey(key);\n const uploadOptions = {\n httpMetadata: {\n contentType,\n cacheControl: \"max-age=31536000\",\n },\n };\n if (contentLength === undefined) {\n const bufferedBody = new Uint8Array(\n await new Response(body).arrayBuffer(),\n );\n await config.bucket.put(storageKey, bufferedBody, uploadOptions);\n } else {\n const fixedLengthBody = new FixedLengthStream(contentLength);\n await Promise.all([\n body.pipeTo(fixedLengthBody.writable),\n config.bucket.put(\n storageKey,\n fixedLengthBody.readable,\n uploadOptions,\n ),\n ]);\n }\n return {\n storageUri: createStorageUri({\n protocol: \"r2\",\n bucket: config.bucketName,\n key: storageKey,\n }),\n };\n },\n async get({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n const object = await config.bucket.get(key);\n if (!object) return { response: null };\n const headers = new Headers();\n object.writeHttpMetadata(headers);\n headers.set(\"etag\", object.httpEtag);\n headers.set(\"content-length\", String(object.size));\n return { response: new Response(object.body, { headers }) };\n },\n ...(config.credentials === undefined\n ? {}\n : {\n async getDownloadUrl({ storageUri }: { storageUri: string }) {\n const { key } = parseAndValidate(storageUri);\n return {\n url: await presignR2GetUrl({\n accountId: config.accountId,\n bucketName: config.bucketName,\n credentials: config.credentials,\n expiresInSeconds: PRESIGNED_URL_EXPIRES_IN_SECONDS,\n key,\n }),\n };\n },\n }),\n async exists({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n return { exists: (await config.bucket.head(key)) !== null };\n },\n async delete({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n await config.bucket.delete(key);\n return { deleted: true };\n },\n });\n}\n"],
|
|
5
|
+
"sourcesContent": ["//#region src/contentAddressedAssets.ts\nconst CONTENT_ADDRESSED_ASSET_PREFIX = \"assets\";\nconst SHA256_FILE_HASH_RE = /^[0-9a-f]{64}$/;\nconst isContentAddressedAssetFileHash = (value) => {\n\treturn typeof value === \"string\" && SHA256_FILE_HASH_RE.test(value);\n};\nconst getContentAddressedAssetStoragePath = ({ assetPath, fileHash }) => {\n\tconst extension = assetPath.endsWith(\".br\") ? \".br\" : assetPath.includes(\".\") ? `.${assetPath.split(\".\").pop()}` : \"\";\n\treturn `sha256/${fileHash.slice(0, 2)}/${fileHash}${extension}`;\n};\n//#endregion\nexport { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash };\n", "//#region src/createStorageKeyBuilder.ts\nconst normalizeStorageKeyParts = (values) => {\n\tif (values.some((value) => value.includes(\"\\\\\"))) throw new Error(\"Storage keys must use '/' as the hierarchy separator.\");\n\tconst segments = values.flatMap((value) => value.split(\"/\").filter(Boolean));\n\tif (segments.some((segment) => segment === \".\" || segment === \"..\")) throw new Error(\"Storage key segments must not be '.' or '..'.\");\n\treturn segments;\n};\nconst createStorageKeyBuilder = (basePath) => {\n\tconst baseSegments = normalizeStorageKeyParts([basePath ?? \"\"]);\n\treturn (...args) => [...baseSegments, ...normalizeStorageKeyParts(args)].join(\"/\");\n};\n//#endregion\nexport { createStorageKeyBuilder };\n", "//#region src/parseStorageUri.ts\nconst PROTOCOL_PATTERN = /^[a-z][a-z\\d+.-]*$/;\nconst INVALID_BUCKET_CHARACTER_PATTERN = /[\\s/?#%@:\\\\]/;\nconst assertProtocol = (protocol) => {\n\tif (!PROTOCOL_PATTERN.test(protocol)) throw new Error(`Invalid storage URI protocol: ${protocol}`);\n};\nconst assertBucket = (bucket) => {\n\tif (bucket.length === 0 || INVALID_BUCKET_CHARACTER_PATTERN.test(bucket)) throw new Error(`Invalid storage URI bucket: ${bucket}`);\n};\nconst getKeySegments = (key) => {\n\tif (key.length === 0) throw new Error(\"Invalid storage URI key: key must not be empty\");\n\tconst segments = key.split(\"/\");\n\tif (segments.some((segment) => segment.length === 0 || segment === \".\" || segment === \"..\" || segment.includes(\"\\\\\"))) throw new Error(\"Invalid storage URI key: segments must not be empty, '.', '..' or contain '\\\\'\");\n\treturn segments;\n};\n/**\n* Creates a hierarchical storage identifier in the form\n* `protocol://bucket/slash-separated-encoded-key`.\n*/\nconst createStorageUri = ({ protocol, bucket, key }) => {\n\tassertProtocol(protocol);\n\tassertBucket(bucket);\n\treturn `${protocol}://${bucket}/${getKeySegments(key).map(encodeURIComponent).join(\"/\")}`;\n};\n/**\n* Parses a hierarchical storage identifier and decodes each key segment.\n*\n* Search parameters and fragments are not part of a storage identifier.\n*/\nfunction parseStorageUri(storageUri, expectedProtocol) {\n\tassertProtocol(expectedProtocol);\n\tif (storageUri.includes(\"?\") || storageUri.includes(\"#\")) throw new Error(`Invalid storage URI format: ${storageUri}`);\n\tconst match = /^([a-z][a-z\\d+.-]*):\\/\\/([^/]+)\\/(.*)$/.exec(storageUri);\n\tif (!match) throw new Error(`Invalid storage URI format: ${storageUri}`);\n\tconst [, protocol, bucket, encodedKey] = match;\n\tif (protocol !== expectedProtocol) throw new Error(`Invalid storage URI protocol. Expected ${expectedProtocol}, got ${protocol}`);\n\tassertBucket(bucket);\n\tlet segments;\n\ttry {\n\t\tsegments = getKeySegments(encodedKey).map((segment) => {\n\t\t\tconst decoded = decodeURIComponent(segment);\n\t\t\tif (decoded.includes(\"/\") || decoded.includes(\"\\\\\")) throw new Error(\"encoded hierarchy separator\");\n\t\t\tif (encodeURIComponent(decoded) !== segment) throw new Error(\"non-canonical segment\");\n\t\t\treturn decoded;\n\t\t});\n\t} catch {\n\t\tthrow new Error(`Invalid storage URI format: ${storageUri}`);\n\t}\n\treturn {\n\t\tprotocol,\n\t\tbucket,\n\t\tkey: segments.join(\"/\")\n\t};\n}\n//#endregion\nexport { createStorageUri, parseStorageUri };\n", "import { getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash } from \"./contentAddressedAssets.mjs\";\nimport { createStorageKeyBuilder } from \"./createStorageKeyBuilder.mjs\";\nimport { createStorageUri, parseStorageUri } from \"./parseStorageUri.mjs\";\n//#region src/assetStorageLayout.ts\nconst isBrotliManifestAssetPath = (assetPath) => /(^|\\/)index\\.[^/]+\\.bundle$/.test(assetPath.replace(/\\\\/g, \"/\"));\nconst getManifestAssetDownloadPath = (assetPath) => isBrotliManifestAssetPath(assetPath) ? `${assetPath}.br` : assetPath;\nconst createStorageUriWithRelativePath = ({ baseStorageUri, relativePath }) => {\n\tconst protocol = new URL(baseStorageUri).protocol.replace(\":\", \"\");\n\tconst parsed = parseStorageUri(baseStorageUri, protocol);\n\tconst childKey = createStorageKeyBuilder(void 0)(relativePath);\n\tif (!childKey) throw new Error(\"Relative storage key must not be empty.\");\n\treturn createStorageUri({\n\t\tprotocol: parsed.protocol,\n\t\tbucket: parsed.bucket,\n\t\tkey: createStorageKeyBuilder(parsed.key)(childKey)\n\t});\n};\nconst replaceStorageUriKeySuffix = ({ storageUri, keySuffix, replacement }) => {\n\tconst protocol = new URL(storageUri).protocol.replace(\":\", \"\");\n\tconst parsed = parseStorageUri(storageUri, protocol);\n\tconst normalizedSuffix = createStorageKeyBuilder(void 0)(keySuffix);\n\tconst normalizedReplacement = createStorageKeyBuilder(void 0)(replacement);\n\tif (!normalizedSuffix || !normalizedReplacement) throw new Error(\"Storage URI key suffix and replacement must not be empty.\");\n\tconst keySegments = parsed.key.split(\"/\");\n\tconst suffixSegments = normalizedSuffix.split(\"/\");\n\tconst suffixOffset = keySegments.length - suffixSegments.length;\n\tif (suffixOffset < 0 || suffixSegments.some((segment, index) => keySegments[suffixOffset + index] !== segment)) throw new Error(\"Storage URI key does not end with the expected suffix.\");\n\tconst prefix = keySegments.slice(0, suffixOffset).join(\"/\");\n\treturn createStorageUri({\n\t\tprotocol: parsed.protocol,\n\t\tbucket: parsed.bucket,\n\t\tkey: createStorageKeyBuilder(prefix)(normalizedReplacement)\n\t});\n};\nconst resolveManifestAssetStorageFileHash = ({ downloadFileHash, fileHash }) => isContentAddressedAssetFileHash(downloadFileHash) ? downloadFileHash : fileHash;\nconst getManifestAssetStoragePath = ({ assetPath, downloadFileHash, fileHash }) => getContentAddressedAssetStoragePath({\n\tassetPath,\n\tfileHash: resolveManifestAssetStorageFileHash({\n\t\tdownloadFileHash,\n\t\tfileHash\n\t})\n});\nconst resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, downloadFileHash, fileHash }) => createStorageUriWithRelativePath({\n\tbaseStorageUri: assetBaseStorageUri,\n\trelativePath: getManifestAssetStoragePath({\n\t\tassetPath,\n\t\tdownloadFileHash,\n\t\tfileHash\n\t})\n});\n//#endregion\nexport { createStorageUriWithRelativePath, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, replaceStorageUriKeySuffix, resolveManifestAssetStorageFileHash, resolveManifestAssetStorageUri };\n", "import { replaceStorageUriKeySuffix } from \"./assetStorageLayout.mjs\";\n//#region src/bundleStorageLayout.ts\nconst BUNDLE_STORAGE_PREFIX = \"bundles\";\nconst createBundleStorageKey = (bundleId, ...relativePaths) => [\n\tBUNDLE_STORAGE_PREFIX,\n\tbundleId,\n\t...relativePaths\n].filter(Boolean).join(\"/\");\nconst getBundleArchiveStorageUri = ({ manifestStorageUri, bundleId }) => replaceStorageUriKeySuffix({\n\tstorageUri: manifestStorageUri,\n\tkeySuffix: createBundleStorageKey(bundleId, \"manifest.json\"),\n\treplacement: createBundleStorageKey(bundleId, \"bundle.tar.br\")\n});\nconst createStorageRootUriWithPath = (storageUri, bundleId, relativePath) => {\n\tconst storageUrl = new URL(storageUri);\n\tconst segments = storageUrl.pathname.split(\"/\").filter(Boolean);\n\tconst bundleIndex = segments.lastIndexOf(bundleId);\n\tif (bundleIndex < 1 || segments[bundleIndex - 1] !== \"bundles\") throw new Error(`Storage URI does not contain canonical bundle path: ${BUNDLE_STORAGE_PREFIX}/${bundleId}`);\n\tconst rootSegments = segments.slice(0, bundleIndex - 1);\n\tconst relativeSegments = relativePath.split(\"/\").filter(Boolean).map((segment) => encodeURIComponent(segment));\n\tstorageUrl.pathname = `/${[...rootSegments, ...relativeSegments].join(\"/\")}`;\n\treturn storageUrl.toString();\n};\n//#endregion\nexport { BUNDLE_STORAGE_PREFIX, createBundleStorageKey, createStorageRootUriWithPath, getBundleArchiveStorageUri };\n", "//#region src/databaseErrors.ts\n/** A bundle an operation names is not stored. */\nvar DatabaseBundleNotFoundError = class extends Error {\n\tbundleId;\n\tname = \"DatabaseBundleNotFoundError\";\n\tconstructor(bundleId) {\n\t\tsuper(`Bundle \"${bundleId}\" was not found.`);\n\t\tthis.bundleId = bundleId;\n\t}\n};\n/** A row a delete names is still referenced, such as a bundle a release uses. */\nvar DatabaseRowReferencedError = class extends Error {\n\tname = \"DatabaseRowReferencedError\";\n\tconstructor() {\n\t\tsuper(\"The database row is still referenced.\");\n\t}\n};\n/** Input a database operation refuses before touching storage. */\nvar DatabaseAdapterInputError = class extends Error {\n\tcode;\n\tname = \"DatabaseAdapterInputError\";\n\tconstructor(code) {\n\t\tsuper(`Invalid database adapter input: ${code}`);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { DatabaseAdapterInputError, DatabaseBundleNotFoundError, DatabaseRowReferencedError };\n", "//#region src/createStorageAdapter.ts\nconst createStorageAdapter = (options) => ({ ...options });\nfunction assertStorageOperations(adapter, operations) {\n\tfor (const operation of operations) if (typeof adapter[operation] !== \"function\") throw new Error(`Storage adapter \"${adapter.name}\" does not implement ${operation}.`);\n}\n//#endregion\nexport { assertStorageOperations, createStorageAdapter };\n", "//#region src/databaseJsonValue.ts\nconst isDatabaseJsonValue = (value) => {\n\tconst ancestors = /* @__PURE__ */ new WeakSet();\n\tconst validate = (input) => {\n\t\tif (input === null || typeof input === \"string\" || typeof input === \"boolean\") return true;\n\t\tif (typeof input === \"number\") return Number.isFinite(input);\n\t\tif (typeof input !== \"object\") return false;\n\t\tif (ancestors.has(input)) return false;\n\t\tancestors.add(input);\n\t\ttry {\n\t\t\tif (Array.isArray(input)) {\n\t\t\t\tif (Object.getPrototypeOf(input) !== Array.prototype) return false;\n\t\t\t\tif (Reflect.ownKeys(input).length !== input.length + 1) return false;\n\t\t\t\tfor (let index = 0; index < input.length; index += 1) {\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(input, String(index));\n\t\t\t\t\tif (descriptor === void 0 || !descriptor.enumerable || !(\"value\" in descriptor) || !validate(descriptor.value)) return false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst prototype = Object.getPrototypeOf(input);\n\t\t\tif (prototype !== Object.prototype && prototype !== null) return false;\n\t\t\tfor (const key of Reflect.ownKeys(input)) {\n\t\t\t\tif (typeof key !== \"string\" || key === \"__proto__\") return false;\n\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(input, key);\n\t\t\t\tif (descriptor === void 0 || !descriptor.enumerable || !(\"value\" in descriptor) || !validate(descriptor.value)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t} finally {\n\t\t\tancestors.delete(input);\n\t\t}\n\t};\n\treturn validate(value);\n};\n/**\n* Whether `value` is a plain object of JSON values a store keeps as they\n* are: no cycles, accessors, non-finite numbers, or class instances. A\n* plugin checks a `json` field's value with it before it writes, as\n* Insights does for an event's metadata.\n*/\nconst isDatabaseJsonObject = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value) && isDatabaseJsonValue(value);\nconst isDatabaseMetadataObject = (value) => isDatabaseJsonObject(value) && (!Object.hasOwn(value, \"app_version\") || typeof value[\"app_version\"] === \"string\");\n//#endregion\nexport { isDatabaseJsonObject, isDatabaseJsonValue, isDatabaseMetadataObject };\n", "import { DatabaseAdapterInputError } from \"./databaseErrors.mjs\";\nimport { isDatabaseMetadataObject } from \"./databaseJsonValue.mjs\";\n//#region src/databaseMetadata.ts\nconst bundleMetadataToRow = (metadata) => {\n\tif (metadata === void 0) return {};\n\tif (!isDatabaseMetadataObject(metadata)) throw new DatabaseAdapterInputError(\"invalid-data\");\n\treturn metadata;\n};\n//#endregion\nexport { bundleMetadataToRow };\n", "//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nString.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nString.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nString.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction formatFullVersion(version) {\n\tconst comparable = formatComparableVersion(version);\n\treturn version.build?.length ? `${comparable}+${version.build.join(\".\")}` : comparable;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.js\nconst COERCE_EXACT = safeRegex(COERCE);\nconst COERCE_FULL_EXACT = safeRegex(COERCE_FULL);\nsafeRegex(`^${PRERELEASE}$`);\nsafeRegex(`^${PRERELEASE_LOOSE}$`);\nfunction normalizeFull(version, options = {}) {\n\tconst parsed = tryParse(version, options);\n\treturn parsed ? formatFullVersion(parsed) : null;\n}\nfunction coerce(value, options = {}) {\n\tif (typeof value === \"object\") return value;\n\tconst input = typeof value === \"number\" ? String(value) : value;\n\tlet match = null;\n\tif (options.rtl) {\n\t\tconst expression = safeRegex(options.includePrerelease ? COERCE_FULL : COERCE, \"g\");\n\t\tlet next;\n\t\twhile ((next = expression.exec(input)) && (!match || match.index + match[0].length !== input.length)) {\n\t\t\tif (!match || next.index + next[0].length !== match.index + match[0].length) match = next;\n\t\t\texpression.lastIndex = next.index + next[1].length + next[2].length;\n\t\t}\n\t} else match = (options.includePrerelease ? COERCE_FULL_EXACT : COERCE_EXACT).exec(input);\n\tif (!match) return null;\n\tconst major = match[2];\n\treturn tryParse(`${major}.${match[3] || \"0\"}.${match[4] || \"0\"}${options.includePrerelease && match[5] ? `-${match[5]}` : \"\"}${options.includePrerelease && match[6] ? `+${match[6]}` : \"\"}`, options);\n}\n//#endregion\n//#region src/appVersion.ts\n/**\n* The form of an app version that the device and the server compare:\n* `major.minor.patch` of the first version in `appVersion`, such as `1.4.0`\n* for `v1.4`, or null when it holds none. Prerelease and build parts are\n* dropped.\n*/\nfunction canonicalizeAppVersion(appVersion) {\n\tconst version = coerce(appVersion);\n\treturn version ? normalizeFull(version) : null;\n}\n//#endregion\n//#region src/baseURL.ts\n/** Resolves a functional baseURL and drops trailing slashes. */\nconst resolveBaseURL = async (baseURL) => {\n\tconst resolvedBaseURL = typeof baseURL === \"function\" ? await baseURL() : baseURL;\n\tif (!resolvedBaseURL) throw new Error(\"baseURL function must return a non-empty string\");\n\treturn resolvedBaseURL.replace(/\\/+$/, \"\");\n};\n//#endregion\n//#region src/bundleArtifacts.ts\nconst getManifestStorageUri = (bundle) => bundle.manifestStorageUri;\nconst getManifestFileHash = (bundle) => bundle.manifestFileHash;\nconst getAssetBaseStorageUri = (bundle) => bundle.assetBaseStorageUri;\nconst isBundlePatchArtifact = (value) => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst candidate = value;\n\treturn typeof candidate.baseBundleId === \"string\" && typeof candidate.baseFileHash === \"string\" && typeof candidate.patchFileHash === \"string\" && typeof candidate.patchStorageUri === \"string\";\n};\nconst readBundlePatchArray = (patches) => {\n\tif (!Array.isArray(patches)) return [];\n\treturn patches.filter(isBundlePatchArtifact);\n};\nconst getBundlePatches = (bundle) => {\n\tconst patches = readBundlePatchArray(bundle.patches);\n\tconst seenBaseBundleIds = /* @__PURE__ */ new Set();\n\treturn patches.filter((patch) => {\n\t\tif (seenBaseBundleIds.has(patch.baseBundleId)) return false;\n\t\tseenBaseBundleIds.add(patch.baseBundleId);\n\t\treturn true;\n\t});\n};\nconst getBundlePatch = (bundle, baseBundleId) => {\n\treturn getBundlePatches(bundle).find((patch) => patch.baseBundleId === baseBundleId) ?? null;\n};\nconst getPrimaryPatch = (bundle) => {\n\treturn getBundlePatches(bundle)[0] ?? null;\n};\nconst getPatchBaseBundleId = (bundle) => getPrimaryPatch(bundle)?.baseBundleId ?? null;\nconst getPatchBaseFileHash = (bundle) => getPrimaryPatch(bundle)?.baseFileHash ?? null;\nconst getPatchFileHash = (bundle) => getPrimaryPatch(bundle)?.patchFileHash ?? null;\nconst getPatchStorageUri = (bundle) => getPrimaryPatch(bundle)?.patchStorageUri ?? null;\n//#endregion\n//#region src/clientPlugin.ts\n/** Declares a client plugin; built-in and third-party plugins use the same contract. */\nconst defineClientPlugin = (plugin) => plugin;\n//#endregion\n//#region src/createPluginHost.ts\n/** Storage values stay small, since native reads them on the JS thread. */\nconst MAX_STORAGE_VALUE_LENGTH = 65536;\n/** Where a plugin's key lives in native storage. */\nconst pluginStorageKey = (pluginId, key) => `plugins/${encodeURIComponent(pluginId)}/${key}`;\nconst createPluginHost = (environment) => {\n\tlet config = null;\n\t/** Hooks and API by plugin, so a plugin configured again is not set up twice. */\n\tconst setUpPlugins = /* @__PURE__ */ new WeakMap();\n\tlet activePlugins = [];\n\t/** What plugins read and wrote, so a read follows a write before native does. */\n\tconst storageValues = /* @__PURE__ */ new Map();\n\tconst reportHookError = (message, error) => {\n\t\tconst report = new Error(`[HotUpdater] ${message}`, { cause: error });\n\t\ttry {\n\t\t\tif (config?.onError) {\n\t\t\t\tconfig.onError(report);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {}\n\t\tconsole.warn(report.message, error);\n\t};\n\tconst fetchFromServer = async (path, init = {}) => {\n\t\tif (config === null) throw new Error(\"[HotUpdater] Plugins can fetch only after HotUpdater.init.\");\n\t\tif (/^[a-z][a-z\\d+.-]*:/i.test(path) || path.startsWith(\"//\")) throw new TypeError(\"[HotUpdater] Plugin fetch takes a path relative to baseURL.\");\n\t\tconst { requestHeaders, requestTimeout } = config;\n\t\tconst url = `${await resolveBaseURL(config.baseURL)}/${path.replace(/^\\/+/, \"\")}`;\n\t\tconst headers = new Headers(requestHeaders);\n\t\tnew Headers(init.headers).forEach((value, name) => {\n\t\t\theaders.set(name, value);\n\t\t});\n\t\tconst controller = new AbortController();\n\t\tconst callerSignal = init.signal;\n\t\tconst abortFromCaller = () => controller.abort();\n\t\tif (callerSignal?.aborted) controller.abort();\n\t\tcallerSignal?.addEventListener(\"abort\", abortFromCaller);\n\t\tlet timedOut = false;\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, requestTimeout ?? 5e3);\n\t\ttry {\n\t\t\treturn await environment.fetch(url, {\n\t\t\t\t...init,\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (!callerSignal?.aborted && (timedOut || error instanceof Error && error.name === \"AbortError\")) throw new Error(\"Request timed out\");\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tcallerSignal?.removeEventListener(\"abort\", abortFromCaller);\n\t\t}\n\t};\n\tconst createStorage = (pluginId) => {\n\t\tconst scopedKey = (key) => {\n\t\t\tif (typeof key !== \"string\" || key.length === 0) throw new TypeError(\"[HotUpdater] Plugin storage keys are non-empty strings.\");\n\t\t\treturn pluginStorageKey(pluginId, key);\n\t\t};\n\t\treturn {\n\t\t\tget: (key) => {\n\t\t\t\tconst storageKey = scopedKey(key);\n\t\t\t\tconst cached = storageValues.get(storageKey);\n\t\t\t\tif (cached !== void 0) return cached;\n\t\t\t\tconst value = environment.getStorageItem(storageKey);\n\t\t\t\tstorageValues.set(storageKey, value);\n\t\t\t\treturn value;\n\t\t\t},\n\t\t\tset: (key, value) => {\n\t\t\t\tconst storageKey = scopedKey(key);\n\t\t\t\tif (value !== null && typeof value !== \"string\") throw new TypeError(\"[HotUpdater] Plugin storage values are strings or null.\");\n\t\t\t\tif (value !== null && value.length > MAX_STORAGE_VALUE_LENGTH) throw new RangeError(\"[HotUpdater] Plugin storage values are at most 64 KB.\");\n\t\t\t\tenvironment.setStorageItem(storageKey, value);\n\t\t\t\tstorageValues.set(storageKey, value);\n\t\t\t}\n\t\t};\n\t};\n\tconst createContext = (pluginId) => ({\n\t\tfetch: fetchFromServer,\n\t\tget installId() {\n\t\t\treturn environment.getInstallId();\n\t\t},\n\t\tplatform: environment.platform,\n\t\tget appVersion() {\n\t\t\treturn environment.getAppVersion();\n\t\t},\n\t\tget sdkVersion() {\n\t\t\treturn environment.sdkVersion;\n\t\t},\n\t\tget minBundleId() {\n\t\t\treturn environment.getMinBundleId();\n\t\t},\n\t\tisDebugBuild: environment.isDebugBuild,\n\t\tgetBundleId: () => environment.getBundleId(),\n\t\tgetChannel: () => environment.getChannel(),\n\t\tgetCohort: () => environment.getCohort(),\n\t\tgetFingerprintHash: () => environment.getFingerprintHash(),\n\t\tstorage: createStorage(pluginId),\n\t\tnow: () => environment.now()\n\t});\n\tconst setUpPlugin = (plugin) => {\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = plugin.setup(createContext(plugin.id));\n\t\t} catch (error) {\n\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in setup`, error);\n\t\t\treturn {\n\t\t\t\thooks: {},\n\t\t\t\tapi: void 0\n\t\t\t};\n\t\t}\n\t\tif (result === void 0 || result === null) return {\n\t\t\thooks: {},\n\t\t\tapi: void 0\n\t\t};\n\t\tconst unknownKeys = Object.keys(result).filter((key) => key !== \"hooks\" && key !== \"api\");\n\t\tif (unknownKeys.length > 0) reportHookError(`Plugin \"${plugin.id}\" setup returned ${unknownKeys.map((key) => `\"${key}\"`).join(\", \")}; setup returns { hooks, api }`, /* @__PURE__ */ new TypeError(\"Unexpected setup result\"));\n\t\treturn {\n\t\t\thooks: result.hooks ?? {},\n\t\t\tapi: result.api\n\t\t};\n\t};\n\tconst configurePlugins = (plugins, nextConfig) => {\n\t\tconst ids = /* @__PURE__ */ new Set();\n\t\tfor (const plugin of plugins ?? []) {\n\t\t\tif (typeof plugin.id !== \"string\" || plugin.id.length === 0) throw new Error(\"[HotUpdater] A plugin id must be a non-empty string.\");\n\t\t\tif (ids.has(plugin.id)) throw new Error(`[HotUpdater] Two plugins use the id \"${plugin.id}\". Plugin ids must be unique.`);\n\t\t\tids.add(plugin.id);\n\t\t}\n\t\tconfig = nextConfig;\n\t\tconst apis = [];\n\t\tactivePlugins = (plugins ?? []).map((plugin) => {\n\t\t\tlet setUp = setUpPlugins.get(plugin);\n\t\t\tif (setUp === void 0) {\n\t\t\t\tsetUp = setUpPlugin(plugin);\n\t\t\t\tsetUpPlugins.set(plugin, setUp);\n\t\t\t}\n\t\t\tif (setUp.api !== void 0) apis.push([plugin.id, setUp.api]);\n\t\t\treturn {\n\t\t\t\tplugin,\n\t\t\t\thooks: setUp.hooks\n\t\t\t};\n\t\t});\n\t\treturn Object.freeze(Object.fromEntries(apis));\n\t};\n\tconst hasPluginHook = (name) => activePlugins.some(({ hooks }) => typeof hooks[name] === \"function\");\n\tconst buildPluginEvent = (name, createPayload) => {\n\t\tif (!hasPluginHook(name)) return null;\n\t\ttry {\n\t\t\treturn createPayload();\n\t\t} catch (error) {\n\t\t\treportHookError(`Failed to build the ${name} event for plugins`, error);\n\t\t\treturn null;\n\t\t}\n\t};\n\tconst dispatchPluginHook = (name, payload) => {\n\t\tconst settlements = [];\n\t\tfor (const { plugin, hooks } of activePlugins) {\n\t\t\tconst hook = hooks[name];\n\t\t\tif (typeof hook !== \"function\") continue;\n\t\t\ttry {\n\t\t\t\tconst result = hook.call(hooks, payload);\n\t\t\t\tif (result !== null && typeof result === \"object\" && typeof result.then === \"function\") settlements.push(Promise.resolve(result).then(() => void 0, (error) => {\n\t\t\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in ${name}`, error);\n\t\t\t\t}));\n\t\t\t} catch (error) {\n\t\t\t\treportHookError(`Plugin \"${plugin.id}\" failed in ${name}`, error);\n\t\t\t}\n\t\t}\n\t\treturn settlements;\n\t};\n\tconst emitPluginHook = (name, createPayload) => {\n\t\tconst payload = buildPluginEvent(name, createPayload);\n\t\tif (payload !== null) dispatchPluginHook(name, payload);\n\t};\n\treturn {\n\t\tconfigurePlugins,\n\t\thasPluginHook,\n\t\tbuildPluginEvent,\n\t\tdispatchPluginHook,\n\t\temitPluginHook\n\t};\n};\n//#endregion\n//#region src/rollout.ts\nconst NUMERIC_COHORT_SIZE = 1e3;\nconst DEFAULT_ROLLOUT_COHORT_COUNT = NUMERIC_COHORT_SIZE;\nconst MAX_COHORT_LENGTH = 64;\nconst INVALID_COHORT_ERROR_MESSAGE = `Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.`;\nconst CUSTOM_COHORT_PATTERN = /^[a-z0-9-]+$/;\nfunction parseNumericCohortValue(cohort) {\n\tif (!/^\\d+$/.test(cohort)) return null;\n\tconst parsed = Number.parseInt(cohort, 10);\n\tif (Number.isNaN(parsed) || parsed < 1 || parsed > 1e3) return null;\n\treturn parsed;\n}\nfunction positiveMod(value, modulus) {\n\treturn (value % modulus + modulus) % modulus;\n}\nfunction hashString(value) {\n\tlet hash = 0;\n\tfor (let i = 0; i < value.length; i++) {\n\t\tconst char = value.charCodeAt(i);\n\t\thash = (hash << 5) - hash + char;\n\t\thash |= 0;\n\t}\n\treturn hash;\n}\nfunction gcd(a, b) {\n\tlet x = Math.abs(a);\n\tlet y = Math.abs(b);\n\twhile (y !== 0) {\n\t\tconst next = x % y;\n\t\tx = y;\n\t\ty = next;\n\t}\n\treturn x;\n}\nfunction modularInverse(value, modulus) {\n\tlet t = 0;\n\tlet newT = 1;\n\tlet r = modulus;\n\tlet newR = positiveMod(value, modulus);\n\twhile (newR !== 0) {\n\t\tconst quotient = Math.floor(r / newR);\n\t\t[t, newT] = [newT, t - quotient * newT];\n\t\t[r, newR] = [newR, r - quotient * newR];\n\t}\n\tif (r > 1) throw new Error(`No modular inverse for ${value} mod ${modulus}`);\n\treturn positiveMod(t, modulus);\n}\nfunction getRolloutShuffleParameters(bundleId) {\n\tlet multiplier = positiveMod(hashString(`${bundleId}:multiplier`), 997);\n\tif (multiplier === 0) multiplier = 1;\n\twhile (gcd(multiplier, NUMERIC_COHORT_SIZE) !== 1) {\n\t\tmultiplier = positiveMod(multiplier + 1, NUMERIC_COHORT_SIZE);\n\t\tif (multiplier === 0) multiplier = 1;\n\t}\n\tconst offset = positiveMod(hashString(`${bundleId}:offset`), NUMERIC_COHORT_SIZE);\n\treturn {\n\t\tmultiplier,\n\t\toffset,\n\t\tinverseMultiplier: modularInverse(multiplier, NUMERIC_COHORT_SIZE)\n\t};\n}\nfunction normalizeRolloutCohortCount(rolloutCohortCount) {\n\tif (rolloutCohortCount === null || rolloutCohortCount === void 0) return DEFAULT_ROLLOUT_COHORT_COUNT;\n\tif (rolloutCohortCount <= 0) return 0;\n\tif (rolloutCohortCount >= 1e3) return NUMERIC_COHORT_SIZE;\n\treturn Math.floor(rolloutCohortCount);\n}\nfunction normalizeCohortValue(cohort) {\n\tconst normalized = cohort.trim().toLowerCase();\n\tconst numericCohort = parseNumericCohortValue(normalized);\n\tif (numericCohort !== null) return String(numericCohort);\n\treturn normalized;\n}\nfunction getNumericCohortValue(cohort) {\n\treturn parseNumericCohortValue(normalizeCohortValue(cohort));\n}\nfunction isNumericCohort(cohort) {\n\treturn getNumericCohortValue(cohort) !== null;\n}\nfunction isCustomCohort(cohort) {\n\tconst normalized = normalizeCohortValue(cohort);\n\treturn normalized.length > 0 && normalized.length <= 64 && !/^\\d+$/.test(normalized) && CUSTOM_COHORT_PATTERN.test(normalized);\n}\nfunction isValidCohort(cohort) {\n\tconst normalized = normalizeCohortValue(cohort);\n\treturn isNumericCohort(normalized) || isCustomCohort(normalized);\n}\nfunction getDefaultNumericCohort(identifier) {\n\tconst cohortValue = positiveMod(hashString(identifier), NUMERIC_COHORT_SIZE) + 1;\n\treturn String(cohortValue);\n}\nfunction getNumericCohortRolloutPosition(bundleId, cohortValue) {\n\tif (cohortValue < 1 || cohortValue > 1e3) throw new Error(`Invalid numeric cohort: ${cohortValue}`);\n\tconst { offset, inverseMultiplier } = getRolloutShuffleParameters(bundleId);\n\treturn positiveMod(inverseMultiplier * (cohortValue - 1 - offset), NUMERIC_COHORT_SIZE);\n}\nfunction getRolledOutNumericCohorts(bundleId, rolloutCohortCount) {\n\tconst normalizedRolloutCount = normalizeRolloutCohortCount(rolloutCohortCount);\n\tif (normalizedRolloutCount <= 0) return [];\n\tif (normalizedRolloutCount >= 1e3) return Array.from({ length: NUMERIC_COHORT_SIZE }, (_, index) => index + 1);\n\tconst { multiplier, offset } = getRolloutShuffleParameters(bundleId);\n\treturn Array.from({ length: normalizedRolloutCount }, (_, position) => positiveMod(multiplier * position + offset, NUMERIC_COHORT_SIZE)).map((zeroBasedCohort) => zeroBasedCohort + 1).sort((left, right) => left - right);\n}\nfunction isCohortEligibleForUpdate(bundleId, cohort, rolloutCohortCount, targetCohorts) {\n\tconst normalizedCohort = cohort === null || cohort === void 0 ? void 0 : normalizeCohortValue(cohort);\n\tconst normalizedTargetCohorts = targetCohorts?.map((targetCohort) => normalizeCohortValue(targetCohort)) ?? [];\n\tif (normalizedCohort !== void 0 && normalizedTargetCohorts.includes(normalizedCohort)) return true;\n\tconst normalizedRolloutCount = normalizeRolloutCohortCount(rolloutCohortCount);\n\tif (normalizedRolloutCount <= 0) return false;\n\tif (normalizedCohort === void 0) return normalizedRolloutCount >= NUMERIC_COHORT_SIZE;\n\tconst numericCohort = getNumericCohortValue(normalizedCohort);\n\tif (numericCohort === null) return false;\n\tif (normalizedRolloutCount >= 1e3) return true;\n\treturn getNumericCohortRolloutPosition(bundleId, numericCohort) < normalizedRolloutCount;\n}\n//#endregion\n//#region src/releaseCatalog.ts\nconst RELEASE_CATALOG_SCHEMA_VERSION = 1;\nconst RELEASE_CATALOG_FALLBACK_POLICY = \"BUILTIN_IF_ACTIVE_INELIGIBLE\";\nconst MAX_CRASHED_BUNDLES = 10;\nconst MAX_TARGET_COHORTS_PER_RELEASE = 100;\nconst MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE = 512;\nconst MAX_COMPILED_CATALOG_BYTES = 262144;\nconst hashSelectionContext = (value) => {\n\tlet first = 2166136261;\n\tlet second = 2654435769;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst code = value.charCodeAt(index);\n\t\tfirst = Math.imul(first ^ code, 16777619);\n\t\tsecond = Math.imul(second ^ code, 2246822507);\n\t}\n\treturn `v1:${(first >>> 0).toString(16).padStart(8, \"0\")}${(second >>> 0).toString(16).padStart(8, \"0\")}`;\n};\nfunction createReleaseSelectionContextHash(input) {\n\tconst crashedBundleIds = [...new Set(input.crashedBundleIds)].sort().slice(0, 10);\n\tconst canonical = JSON.stringify({\n\t\tactiveBundleId: input.activeBundleId ?? null,\n\t\tactiveReleaseId: input.activeReleaseId ?? null,\n\t\tcohort: normalizeCohortValue(input.cohort ?? \"\"),\n\t\tcrashedBundleIds,\n\t\tminimumReleaseId: input.minimumReleaseId,\n\t\tselectorSchemaVersion: 1,\n\t\tstrategy: input.strategy,\n\t\tstrategyValue: input.strategyValue\n\t});\n\treturn hashSelectionContext(canonical);\n}\nfunction isReleaseEligibleForCohort(release, cohort) {\n\tif (isCohortEligibleForUpdate(release.releaseId, cohort, release.rolloutCohortCount, release.targetCohorts)) return true;\n\treturn cohort !== null && cohort !== void 0 && isCustomCohort(normalizeCohortValue(cohort)) && normalizeRolloutCohortCount(release.rolloutCohortCount) === 1e3;\n}\nfunction selectDesiredRelease(catalog, input) {\n\tconst crashedBundleIds = new Set(input.crashedBundleIds);\n\tconst activeReleaseId = input.activeReleaseId ?? null;\n\tconst hasActiveBundle = input.currentBundleId !== input.builtInBundleId;\n\tconst isSafeBundleRelease = (release) => release.bundleId !== null && !crashedBundleIds.has(release.bundleId) && release.bundleId >= input.minimumReleaseId;\n\tconst runningReleaseId = input.runningReleaseId === void 0 ? activeReleaseId : input.runningReleaseId;\n\tconst isNewerThanRunning = (release) => runningReleaseId !== null ? release.releaseId > runningReleaseId : release.bundleId !== null && release.bundleId > input.currentBundleId;\n\tconst passesForcedRelease = (selected) => [selected, ...catalog.rollbackReleases].some((passed) => passed.shouldForceUpdate && passed.bundleId !== null && passed.bundleId >= input.minimumReleaseId && passed.bundleId !== input.currentBundleId && passed.releaseId <= selected.releaseId && isNewerThanRunning(passed) && isReleaseEligibleForCohort(passed, input.cohort));\n\tconst desiredBundle = (release, status) => ({\n\t\tbundleId: release.bundleId,\n\t\tkind: \"BUNDLE\",\n\t\trelease,\n\t\treleaseId: release.releaseId,\n\t\tshouldForceUpdate: status === \"ROLLBACK\" || passesForcedRelease(release),\n\t\tstatus\n\t});\n\tfor (const release of catalog.releases) {\n\t\tif (!isReleaseEligibleForCohort(release, input.cohort)) continue;\n\t\tif (activeReleaseId !== null && release.releaseId <= activeReleaseId || activeReleaseId === null && hasActiveBundle && (release.bundleId === null || release.bundleId <= input.currentBundleId)) continue;\n\t\tif (isSafeBundleRelease(release)) return desiredBundle(release, \"UPDATE\");\n\t}\n\tif (activeReleaseId !== null || hasActiveBundle) {\n\t\tconst { rollbackReleases } = catalog;\n\t\tconst current = rollbackReleases.find((release) => release.releaseId === activeReleaseId || activeReleaseId === null && release.bundleId === input.currentBundleId);\n\t\tif (current !== void 0 && isSafeBundleRelease(current) && isReleaseEligibleForCohort(current, input.cohort)) return desiredBundle(current, \"UPDATE\");\n\t\tconst rollback = rollbackReleases.find((release) => isSafeBundleRelease(release) && (activeReleaseId !== null ? release.releaseId < activeReleaseId : release.bundleId < input.currentBundleId));\n\t\tif (rollback !== void 0 && isSafeBundleRelease(rollback)) return desiredBundle(rollback, \"ROLLBACK\");\n\t\tif (input.currentBundleId <= input.minimumReleaseId) return null;\n\t}\n\tif (catalog.fallbackPolicy !== \"BUILTIN_IF_ACTIVE_INELIGIBLE\") return null;\n\treturn {\n\t\tbundleId: input.builtInBundleId,\n\t\tkind: \"BUILTIN\",\n\t\trelease: null,\n\t\treleaseId: null,\n\t\tshouldForceUpdate: true,\n\t\tstatus: \"ROLLBACK\"\n\t};\n}\nfunction assessCatalogAcceptance(incoming, highestSeen) {\n\tif (highestSeen === null) return {\n\t\taccepted: true,\n\t\tshouldAdvanceHighWater: true\n\t};\n\tif (incoming.generation < highestSeen.generation) return {\n\t\taccepted: false,\n\t\treason: \"STALE_GENERATION\"\n\t};\n\tif (incoming.generation === highestSeen.generation && incoming.catalogHash !== highestSeen.catalogHash) return {\n\t\taccepted: false,\n\t\treason: \"GENERATION_HASH_MISMATCH\"\n\t};\n\treturn {\n\t\taccepted: true,\n\t\tshouldAdvanceHighWater: incoming.generation > highestSeen.generation\n\t};\n}\nfunction authorizeReleaseTransition(input) {\n\tconst { active, desired, explicitScopeSwitch } = input;\n\tif (active === null || active.scopeKey === null || active.generation === null) return {\n\t\tauthorized: true,\n\t\treason: \"FIRST_AUTHENTICATED_SELECTION\"\n\t};\n\tif (desired.catalogId !== active.catalogId || desired.scopeKey !== active.scopeKey) {\n\t\tif (!explicitScopeSwitch) return {\n\t\t\tauthorized: false,\n\t\t\treason: \"UNSOLICITED_SCOPE\"\n\t\t};\n\t\tif (desired.releaseId === null || desired.kind === \"BUILTIN\") return {\n\t\t\tauthorized: false,\n\t\t\treason: \"EMPTY_TARGET_SCOPE\"\n\t\t};\n\t\treturn {\n\t\t\tauthorized: true,\n\t\t\treason: \"EXPLICIT_SCOPE_SWITCH\"\n\t\t};\n\t}\n\tif (desired.generation === null || desired.generation < active.generation) return {\n\t\tauthorized: false,\n\t\treason: \"STALE_GENERATION\"\n\t};\n\tif (desired.generation > active.generation) return {\n\t\tauthorized: true,\n\t\treason: \"NEWER_POLICY\"\n\t};\n\tif (desired.selectionContextHash !== active.selectionContextHash) return {\n\t\tauthorized: true,\n\t\treason: \"CONTEXT_RESELECTION\"\n\t};\n\treturn {\n\t\tauthorized: false,\n\t\treason: \"BACKWARD_NOT_AUTHORIZED\"\n\t};\n}\n//#endregion\n//#region src/releaseCatalogScope.ts\nconst BASE64URL_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\nconst MAX_CATALOG_SEGMENT_LENGTH = 255;\nfunction assertCatalogSegment(value, name) {\n\tif (value.length === 0 || value.length > MAX_CATALOG_SEGMENT_LENGTH || !/^[A-Za-z0-9._~-]+$/.test(value)) throw new Error(`${name} must be 1-${MAX_CATALOG_SEGMENT_LENGTH} URL-safe ASCII characters`);\n}\nfunction encodeUtf8(value) {\n\tconst bytes = [];\n\tfor (const codePointText of value) {\n\t\tconst codePoint = codePointText.codePointAt(0);\n\t\tif (codePoint <= 127) bytes.push(codePoint);\n\t\telse if (codePoint <= 2047) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);\n\t\telse if (codePoint <= 65535) bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);\n\t\telse bytes.push(240 | codePoint >> 18, 128 | codePoint >> 12 & 63, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);\n\t}\n\treturn bytes;\n}\nfunction decodeUtf8(bytes) {\n\tlet result = \"\";\n\tfor (let index = 0; index < bytes.length;) {\n\t\tconst first = bytes[index++];\n\t\tlet codePoint;\n\t\tlet continuationCount;\n\t\tif (first <= 127) {\n\t\t\tcodePoint = first;\n\t\t\tcontinuationCount = 0;\n\t\t} else if ((first & 224) === 192) {\n\t\t\tcodePoint = first & 31;\n\t\t\tcontinuationCount = 1;\n\t\t} else if ((first & 240) === 224) {\n\t\t\tcodePoint = first & 15;\n\t\t\tcontinuationCount = 2;\n\t\t} else if ((first & 248) === 240) {\n\t\t\tcodePoint = first & 7;\n\t\t\tcontinuationCount = 3;\n\t\t} else throw new Error(\"Invalid UTF-8 channel key\");\n\t\tfor (let offset = 0; offset < continuationCount; offset += 1) {\n\t\t\tconst continuation = bytes[index++];\n\t\t\tif (continuation === void 0 || (continuation & 192) !== 128) throw new Error(\"Invalid UTF-8 channel key\");\n\t\t\tcodePoint = codePoint << 6 | continuation & 63;\n\t\t}\n\t\tif (codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343 || continuationCount === 1 && codePoint < 128 || continuationCount === 2 && codePoint < 2048 || continuationCount === 3 && codePoint < 65536) throw new Error(\"Invalid UTF-8 channel key\");\n\t\tresult += String.fromCodePoint(codePoint);\n\t}\n\treturn result;\n}\nfunction base64UrlEncode(bytes) {\n\tlet result = \"\";\n\tfor (let index = 0; index < bytes.length; index += 3) {\n\t\tconst first = bytes[index];\n\t\tconst second = bytes[index + 1];\n\t\tconst third = bytes[index + 2];\n\t\tconst value = first << 16 | (second ?? 0) << 8 | (third ?? 0);\n\t\tresult += BASE64URL_ALPHABET[value >> 18 & 63];\n\t\tresult += BASE64URL_ALPHABET[value >> 12 & 63];\n\t\tif (second !== void 0) result += BASE64URL_ALPHABET[value >> 6 & 63];\n\t\tif (third !== void 0) result += BASE64URL_ALPHABET[value & 63];\n\t}\n\treturn result;\n}\nfunction base64UrlDecode(value) {\n\tif (!/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1) throw new Error(\"Invalid channel key\");\n\tconst bytes = [];\n\tfor (let index = 0; index < value.length; index += 4) {\n\t\tconst chunk = value.slice(index, index + 4);\n\t\tconst encoded = [...chunk].map((character) => BASE64URL_ALPHABET.indexOf(character));\n\t\tif (encoded.some((part) => part < 0)) throw new Error(\"Invalid channel key\");\n\t\tconst bits = encoded[0] << 18 | encoded[1] << 12 | (encoded[2] ?? 0) << 6 | (encoded[3] ?? 0);\n\t\tbytes.push(bits >> 16 & 255);\n\t\tif (chunk.length >= 3) bytes.push(bits >> 8 & 255);\n\t\tif (chunk.length === 4) bytes.push(bits & 255);\n\t}\n\treturn bytes;\n}\nfunction normalizeChannelName(channel) {\n\treturn channel.trim().normalize(\"NFC\");\n}\nfunction assertCanonicalChannelName(channel) {\n\tconst normalized = normalizeChannelName(channel);\n\tif (normalized.length === 0 || normalized !== channel) throw new Error(\"Channel name must be non-empty, trimmed, and NFC-normalized\");\n\tlet codePointCount = 0;\n\tfor (const _codePoint of normalized) {\n\t\tcodePointCount += 1;\n\t\tif (codePointCount > 255) throw new Error(\"Channel name must not exceed 255 characters\");\n\t}\n}\nfunction encodeChannelKey(channel) {\n\tassertCanonicalChannelName(channel);\n\treturn base64UrlEncode(encodeUtf8(channel));\n}\nfunction decodeChannelKey(channelKey) {\n\tconst channel = decodeUtf8(base64UrlDecode(channelKey));\n\tassertCanonicalChannelName(channel);\n\tif (encodeChannelKey(channel) !== channelKey) throw new Error(\"Channel key is not canonically encoded\");\n\treturn channel;\n}\nfunction createReleaseCatalogScopeKey(input) {\n\tdecodeChannelKey(input.channelKey);\n\tif (input.strategy === \"APP_VERSION\") return `v1:app-version:${input.platform}:${input.channelKey}`;\n\tassertCatalogSegment(input.fingerprintHash, \"Fingerprint hash\");\n\treturn `v1:fingerprint:${input.platform}:${input.channelKey}:${input.fingerprintHash}`;\n}\nfunction parseReleaseCatalogScopeKey(scopeKey) {\n\tconst segments = scopeKey.split(\":\");\n\tconst [version, strategy, platform, channelKey] = segments;\n\tif (version !== \"v1\" || platform !== \"ios\" && platform !== \"android\" || channelKey === void 0) throw new Error(\"Invalid release catalog scope key\");\n\tconst input = strategy === \"app-version\" && segments.length === 4 ? {\n\t\tchannelKey,\n\t\tplatform,\n\t\tstrategy: \"APP_VERSION\"\n\t} : strategy === \"fingerprint\" && segments.length === 5 && segments[4] !== void 0 ? {\n\t\tchannelKey,\n\t\tfingerprintHash: segments[4],\n\t\tplatform,\n\t\tstrategy: \"FINGERPRINT\"\n\t} : (() => {\n\t\tthrow new Error(\"Invalid release catalog scope key\");\n\t})();\n\tif (createReleaseCatalogScopeKey(input) !== scopeKey) throw new Error(\"Release catalog scope key is not canonical\");\n\treturn input;\n}\n//#endregion\n//#region src/uuid.ts\nconst NIL_UUID = \"00000000-0000-0000-0000-000000000000\";\nconst UUID_V7_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst isUUIDv7 = (value) => typeof value === \"string\" && UUID_V7_PATTERN.test(value);\n//#endregion\n//#region src/releaseCatalogWire.ts\n/** The largest release catalog response body a client accepts, in UTF-8 bytes. */\nconst MAX_RELEASE_CATALOG_WIRE_BYTES = 528384;\n/** The length of `value` in UTF-8 bytes, without an encoder the device may lack. */\nconst getUtf8ByteLength = (value) => {\n\tlet bytes = 0;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst code = value.charCodeAt(index);\n\t\tif (code <= 127) bytes += 1;\n\t\telse if (code <= 2047) bytes += 2;\n\t\telse if (code >= 55296 && code <= 56319 && index + 1 < value.length && value.charCodeAt(index + 1) >= 56320 && value.charCodeAt(index + 1) <= 57343) {\n\t\t\tbytes += 4;\n\t\t\tindex += 1;\n\t\t} else bytes += 3;\n\t}\n\treturn bytes;\n};\nconst isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\nconst isValidReleaseDescriptor = (value) => {\n\tif (value === null || typeof value !== \"object\") return false;\n\tconst descriptor = value;\n\treturn isUUIDv7(descriptor.releaseId) && descriptor.kind === \"BUNDLE\" && typeof descriptor.bundleId === \"string\" && Number.isSafeInteger(descriptor.rolloutCohortCount) && descriptor.rolloutCohortCount >= 0 && descriptor.rolloutCohortCount <= 1e3 && isStringArray(descriptor.targetCohorts) && descriptor.targetCohorts.length <= 100 && typeof descriptor.shouldForceUpdate === \"boolean\" && (descriptor.message === null || typeof descriptor.message === \"string\");\n};\n/** Whether the catalog is the expected scope's. */\nconst hasExpectedReleaseCatalogScope = (catalog, expected) => {\n\ttry {\n\t\tconst parsed = parseReleaseCatalogScopeKey(catalog.scopeKey);\n\t\treturn parsed.channelKey === expected.channelKey && parsed.platform === expected.platform && parsed.strategy === expected.strategy && (parsed.strategy === \"APP_VERSION\" || expected.strategy === \"FINGERPRINT\" && parsed.fingerprintHash === expected.fingerprintHash);\n\t} catch {\n\t\treturn false;\n\t}\n};\n/**\n* Parses a release catalog response body as a client accepts it: within the\n* wire limit, in the schema's shape, for the expected scope, and within the\n* cohort limits. Any other body is null. The device's update client and\n* doctor's server checks both run this, so they accept the same catalogs.\n*/\nconst parseReleaseCatalog = (body, expectedScope) => {\n\tif (getUtf8ByteLength(body) > MAX_RELEASE_CATALOG_WIRE_BYTES) return null;\n\ttry {\n\t\tconst catalog = JSON.parse(body);\n\t\tif (catalog.schemaVersion !== 1 || typeof catalog.catalogId !== \"string\" || catalog.catalogId.length === 0 || typeof catalog.scopeKey !== \"string\" || !Number.isSafeInteger(catalog.generation) || (catalog.generation ?? 0) < 1 || typeof catalog.catalogHash !== \"string\" || !/^sha256:[0-9a-f]{64}$/.test(catalog.catalogHash) || catalog.fallbackPolicy !== \"BUILTIN_IF_ACTIVE_INELIGIBLE\" || !Array.isArray(catalog.releases) || !catalog.releases.every(isValidReleaseDescriptor) || !Array.isArray(catalog.rollbackReleases) || !catalog.rollbackReleases.every(isValidReleaseDescriptor)) return null;\n\t\tif (!hasExpectedReleaseCatalogScope(catalog, expectedScope)) return null;\n\t\tif (new Set([...catalog.releases, ...catalog.rollbackReleases].flatMap((release) => release.targetCohorts)).size > 512) return null;\n\t\treturn catalog;\n\t} catch {\n\t\treturn null;\n\t}\n};\n//#endregion\n//#region src/types.ts\nconst ARTIFACT_PROTOCOL_VERSION = 1;\n//#endregion\nexport { ARTIFACT_PROTOCOL_VERSION, DEFAULT_ROLLOUT_COHORT_COUNT, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, MAX_COMPILED_CATALOG_BYTES, MAX_CRASHED_BUNDLES, MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE, MAX_RELEASE_CATALOG_WIRE_BYTES, MAX_TARGET_COHORTS_PER_RELEASE, NIL_UUID, NUMERIC_COHORT_SIZE, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, assertCanonicalChannelName, assessCatalogAcceptance, authorizeReleaseTransition, canonicalizeAppVersion, createPluginHost, createReleaseCatalogScopeKey, createReleaseSelectionContextHash, decodeChannelKey, defineClientPlugin, encodeChannelKey, getAssetBaseStorageUri, getBundlePatch, getBundlePatches, getDefaultNumericCohort, getManifestFileHash, getManifestStorageUri, getNumericCohortRolloutPosition, getNumericCohortValue, getPatchBaseBundleId, getPatchBaseFileHash, getPatchFileHash, getPatchStorageUri, getRolledOutNumericCohorts, getUtf8ByteLength, hasExpectedReleaseCatalogScope, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isReleaseEligibleForCohort, isUUIDv7, isValidCohort, normalizeChannelName, normalizeCohortValue, normalizeRolloutCohortCount, parseReleaseCatalog, parseReleaseCatalogScopeKey, pluginStorageKey, resolveBaseURL, selectDesiredRelease };\n", "import { bundleMetadataToRow } from \"./databaseMetadata.mjs\";\nimport { getAssetBaseStorageUri, getBundlePatches, getManifestFileHash, getManifestStorageUri } from \"@hot-updater/protocol\";\n//#region src/databaseRows.ts\nconst releaseToRow = (release, scopeKey) => ({\n\tid: release.id,\n\trevision: release.revision,\n\tscope_key: scopeKey,\n\tchannel_id: release.channelId,\n\tplatform: release.platform,\n\tkind: release.kind,\n\tbundle_id: release.bundleId,\n\tstrategy: release.strategy,\n\ttarget_app_version: release.targetAppVersion,\n\tfingerprint_hash: release.fingerprintHash,\n\tenabled: release.enabled,\n\tshould_force_update: release.shouldForceUpdate,\n\tmessage: release.message,\n\trollout_cohort_count: release.rolloutCohortCount,\n\ttarget_cohorts: release.targetCohorts,\n\toperation: release.operation,\n\tsource_release_id: release.sourceReleaseId,\n\tcreated_at_ms: release.createdAtMs,\n\tupdated_at_ms: release.updatedAtMs\n});\nconst releaseRowToRelease = (row) => ({\n\tid: row.id,\n\trevision: row.revision,\n\tchannelId: row.channel_id,\n\tplatform: row.platform,\n\tkind: row.kind,\n\tbundleId: row.bundle_id,\n\tstrategy: row.strategy,\n\ttargetAppVersion: row.target_app_version,\n\tfingerprintHash: row.fingerprint_hash,\n\tenabled: row.enabled,\n\tshouldForceUpdate: row.should_force_update,\n\tmessage: row.message,\n\trolloutCohortCount: row.rollout_cohort_count,\n\ttargetCohorts: row.target_cohorts,\n\toperation: row.operation,\n\tsourceReleaseId: row.source_release_id,\n\tcreatedAtMs: row.created_at_ms,\n\tupdatedAtMs: row.updated_at_ms\n});\nconst BundleRowHydrationErrorReason = {\n\tduplicatePatchId: \"duplicate_patch_id\",\n\torphanPatchOwner: \"orphan_patch_owner\",\n\torphanPatchBase: \"orphan_patch_base\"\n};\nvar BundleRowHydrationError = class extends Error {\n\tname = \"BundleRowHydrationError\";\n\treason;\n\tpatchId;\n\tbundleId;\n\tconstructor({ reason, patchId, bundleId }) {\n\t\tsuper(`Cannot hydrate bundle rows: ${reason} for patch \"${patchId}\" and bundle \"${bundleId}\".`);\n\t\tthis.reason = reason;\n\t\tthis.patchId = patchId;\n\t\tthis.bundleId = bundleId;\n\t}\n};\nconst bundleToRow = (bundle) => {\n\tconst metadata = bundleMetadataToRow(bundle.metadata);\n\treturn {\n\t\tid: bundle.id,\n\t\tplatform: bundle.platform,\n\t\tgit_commit_hash: bundle.gitCommitHash,\n\t\tmetadata,\n\t\tmanifest_storage_uri: getManifestStorageUri(bundle),\n\t\tmanifest_file_hash: getManifestFileHash(bundle),\n\t\tasset_base_storage_uri: getAssetBaseStorageUri(bundle)\n\t};\n};\nconst bundleToPatchRows = (bundle) => getBundlePatches(bundle).map((patch, orderIndex) => ({\n\tid: `${bundle.id}:${patch.baseBundleId}`,\n\tbundle_id: bundle.id,\n\tbase_bundle_id: patch.baseBundleId,\n\tbase_file_hash: patch.baseFileHash,\n\tpatch_file_hash: patch.patchFileHash,\n\tpatch_storage_uri: patch.patchStorageUri,\n\tbyte_size: patch.byteSize,\n\torder_index: orderIndex\n}));\nconst comparePatchRows = (left, right) => left.order_index - right.order_index || left.id.localeCompare(right.id);\nconst patchRowToArtifact = (row) => ({\n\tbaseBundleId: row.base_bundle_id,\n\tbaseFileHash: row.base_file_hash,\n\tbyteSize: row.byte_size,\n\tpatchFileHash: row.patch_file_hash,\n\tpatchStorageUri: row.patch_storage_uri\n});\nconst rowToBundle = (row, patchRows = []) => {\n\tconst patches = patchRows.slice().sort(comparePatchRows).map(patchRowToArtifact);\n\treturn {\n\t\tid: row.id,\n\t\tplatform: row.platform,\n\t\tgitCommitHash: row.git_commit_hash,\n\t\tmetadata: row.metadata,\n\t\tmanifestStorageUri: row.manifest_storage_uri,\n\t\tmanifestFileHash: row.manifest_file_hash,\n\t\tassetBaseStorageUri: row.asset_base_storage_uri,\n\t\tpatches\n\t};\n};\nconst rowsToBundles = (bundleRows, patchRows, referencedBundleRows) => {\n\tconst ownerIds = new Set(bundleRows.map(({ id }) => id));\n\tconst baseIds = new Set(ownerIds);\n\tfor (const row of referencedBundleRows) baseIds.add(row.id);\n\tconst patchIds = /* @__PURE__ */ new Set();\n\tconst patchesByOwner = /* @__PURE__ */ new Map();\n\tfor (const patch of patchRows) {\n\t\tif (patchIds.has(patch.id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.duplicatePatchId,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.bundle_id\n\t\t});\n\t\tpatchIds.add(patch.id);\n\t\tif (!ownerIds.has(patch.bundle_id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.orphanPatchOwner,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.bundle_id\n\t\t});\n\t\tif (!baseIds.has(patch.base_bundle_id)) throw new BundleRowHydrationError({\n\t\t\treason: BundleRowHydrationErrorReason.orphanPatchBase,\n\t\t\tpatchId: patch.id,\n\t\t\tbundleId: patch.base_bundle_id\n\t\t});\n\t\tconst ownerPatches = patchesByOwner.get(patch.bundle_id) ?? [];\n\t\townerPatches.push(patch);\n\t\tpatchesByOwner.set(patch.bundle_id, ownerPatches);\n\t}\n\treturn bundleRows.map((row) => rowToBundle(row, patchesByOwner.get(row.id) ?? []));\n};\n//#endregion\nexport { BundleRowHydrationError, BundleRowHydrationErrorReason, bundleToPatchRows, bundleToRow, releaseRowToRelease, releaseToRow, rowToBundle, rowsToBundles };\n", "import { isUUIDv7, isUUIDv7 as isUUIDv7$1 } from \"@hot-updater/protocol\";\n//#region src/uuidv7.ts\nconst extractTimestampFromUUIDv7 = (uuid) => {\n\tif (!isUUIDv7(uuid)) throw new TypeError(\"Expected a canonical lowercase UUIDv7\");\n\tconst timestampHex = uuid.split(\"-\").join(\"\").slice(0, 12);\n\treturn Number.parseInt(timestampHex, 16);\n};\nfunction createUUIDv7FromTimestampHex(timestampHex) {\n\tconst randomBytes = /* @__PURE__ */ new Uint8Array(10);\n\tcrypto.getRandomValues(randomBytes);\n\tconst randomHex = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\tconst randA = randomHex.slice(0, 3);\n\tconst randBHex = randomHex.slice(3, 19);\n\tconst versionAndRandA = `7${randA}`;\n\tconst variantAndFirstRandB = (128 | parseInt(randBHex.slice(0, 2), 16) & 63).toString(16).padStart(2, \"0\");\n\treturn [\n\t\ttimestampHex.slice(0, 8),\n\t\ttimestampHex.slice(8, 12),\n\t\tversionAndRandA,\n\t\tvariantAndFirstRandB + randBHex.slice(2, 4),\n\t\trandBHex.slice(4, 16)\n\t].join(\"-\");\n}\nconst createUUIDv7 = () => createUUIDv7FromTimestampHex(Date.now().toString(16).padStart(12, \"0\"));\nconst createUUIDv7After = (floor, nowMs = Date.now()) => {\n\tconst timestamp = Math.max(nowMs, floor === null ? 0 : extractTimestampFromUUIDv7(floor) + 1);\n\tif (!Number.isSafeInteger(timestamp) || timestamp < 0 || timestamp >= 2 ** 48) throw new RangeError(\"UUIDv7 timestamp is out of range\");\n\treturn createUUIDv7FromTimestampHex(timestamp.toString(16).padStart(12, \"0\"));\n};\nconst createUUIDv7WithSameTimestamp = (originalUuid) => {\n\treturn createUUIDv7FromTimestampHex(originalUuid.split(\"-\").join(\"\").slice(0, 12));\n};\n//#endregion\nexport { createUUIDv7, createUUIDv7After, createUUIDv7WithSameTimestamp, extractTimestampFromUUIDv7, isUUIDv7$1 as isUUIDv7 };\n", "//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst GREATER_LESS_THAN = \"((?:<|>)?=?)\";\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nconst XRANGE_PLAIN = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nconst XRANGE_PLAIN_LOOSE = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nconst LONE_TILDE = \"(?:~>?)\";\nconst LONE_CARET = String.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nconst NUMERIC = /^\\d+$/;\nfunction compareIdentifiers(left, right) {\n\tif (typeof left === \"number\" && typeof right === \"number\") return left === right ? 0 : left < right ? -1 : 1;\n\tconst leftNumeric = NUMERIC.test(String(left));\n\tconst rightNumeric = NUMERIC.test(String(right));\n\tconst normalizedLeft = leftNumeric ? Number(left) : left;\n\tconst normalizedRight = rightNumeric ? Number(right) : right;\n\treturn normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;\n}\nfunction compareMainParsed(left, right) {\n\treturn left.major === right.major ? left.minor === right.minor ? left.patch === right.patch ? 0 : left.patch < right.patch ? -1 : 1 : left.minor < right.minor ? -1 : 1 : left.major < right.major ? -1 : 1;\n}\nfunction comparePrereleaseParsed(left, right) {\n\tconst leftPrerelease = left.prerelease;\n\tconst rightPrerelease = right.prerelease;\n\tif (leftPrerelease?.length && !rightPrerelease?.length) return -1;\n\tif (!leftPrerelease?.length && rightPrerelease?.length) return 1;\n\tif (!leftPrerelease?.length && !rightPrerelease?.length) return 0;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = leftPrerelease?.[index];\n\t\tconst rightIdentifier = rightPrerelease?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compareParsed(left, right) {\n\treturn compareMainParsed(left, right) || comparePrereleaseParsed(left, right);\n}\nfunction compare(left, right, options = {}) {\n\treturn compareParsed(parse(left, options), parse(right, options));\n}\n//#endregion\nexport { LOOSE_PLAIN as A, BUILD as C, GREATER_LESS_THAN as D, FULL_PLAIN as E, safeRegex as F, PRERELEASE_LOOSE as M, XRANGE_PLAIN as N, LONE_CARET as O, XRANGE_PLAIN_LOOSE as P, tryParse as S, COERCE_FULL as T, compareIdentifiers as _, compareParsed as a, compareMainParsed as i, PRERELEASE as j, LONE_TILDE as k, compare as t, COERCE as w, parse as x, formatComparableVersion as y };\n", "import { A as LOOSE_PLAIN, D as GREATER_LESS_THAN, E as FULL_PLAIN, F as safeRegex, a as compareParsed, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.js\nconst STRICT_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${FULL_PLAIN})$|^$`);\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction formatComparator(comparator) {\n\treturn comparator.version ? `${comparator.operator}${formatComparableVersion(comparator.version)}` : \"\";\n}\nfunction parseComparator(comparator, options = {}) {\n\tif (typeof comparator !== \"string\") return comparator;\n\tconst normalized = comparator.trim().replaceAll(/\\s+/g, \" \");\n\tconst match = normalized.match(options.loose ? LOOSE_COMPARATOR : STRICT_COMPARATOR);\n\tif (!match) throw new TypeError(`Invalid comparator: ${normalized}`);\n\tconst operator = match[1] === \"=\" ? \"\" : match[1] || \"\";\n\tconst version = match[2] ? parse(match[2], options) : null;\n\treturn {\n\t\toperator,\n\t\toptions,\n\t\tvalue: version ? `${operator}${formatComparableVersion(version)}` : \"\",\n\t\tversion\n\t};\n}\nfunction testParsedComparator(comparator, version) {\n\tif (!comparator.version) return true;\n\tconst comparison = compareParsed(version, comparator.version);\n\tswitch (comparator.operator) {\n\t\tcase \"\": return comparison === 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t}\n}\nfunction comparatorAllowsPrerelease(comparator, version) {\n\tconst allowed = comparator.version;\n\treturn allowed !== null && !!allowed.prerelease?.length && allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch;\n}\nfunction testComparatorSet(set, version, options) {\n\tif (set.some((comparator) => !testParsedComparator(comparator, version))) return false;\n\treturn !version.prerelease?.length || !!options.includePrerelease || set.some((comparator) => comparatorAllowsPrerelease(comparator, version));\n}\n//#endregion\nexport { testParsedComparator as a, formatComparator as o, testComparatorSet as r, parseComparator as s, comparatorAllowsPrerelease as t };\n", "import { A as LOOSE_PLAIN, C as BUILD, D as GREATER_LESS_THAN, F as safeRegex, N as XRANGE_PLAIN, O as LONE_CARET, P as XRANGE_PLAIN_LOOSE, S as tryParse, k as LONE_TILDE } from \"./comparison-DenM3wCn.mjs\";\nimport { o as formatComparator, r as testComparatorSet, s as parseComparator } from \"./set-CC5YeoYX.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.js\nfunction formatRange(range) {\n\treturn range.sets.map((set) => set.map(formatComparator).join(\" \")).join(\"||\");\n}\nconst BUILD_STRIP = new RegExp(BUILD, \"g\");\nconst BUILD_SAFE = safeRegex(BUILD);\nconst STRICT_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN})\\s+-\\s+(${XRANGE_PLAIN})\\s*$`);\nconst LOOSE_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN_LOOSE})\\s+-\\s+(${XRANGE_PLAIN_LOOSE})\\s*$`);\nconst COMPARATOR_TRIM = safeRegex(String.raw`(\\s*)${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN}|${XRANGE_PLAIN})`, \"g\");\nconst TILDE_TRIM = safeRegex(String.raw`(\\s*)${LONE_TILDE}\\s+`, \"g\");\nconst CARET_TRIM = safeRegex(String.raw`(\\s*)${LONE_CARET}\\s+`, \"g\");\nconst STRICT_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN}$`);\nconst LOOSE_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN}$`);\nconst LOOSE_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN}$`);\nconst LOOSE_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN_LOOSE}$`);\nconst STAR = safeRegex(String.raw`(<|>)?=?\\s*\\*`);\nconst GTE_ZERO = /^\\s*>=\\s*0\\.0\\.0\\s*$/;\nconst GTE_ZERO_PRERELEASE = /^\\s*>=\\s*0\\.0\\.0-0\\s*$/;\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction isWildcard(value) {\n\treturn !value || String(value).toLowerCase() === \"x\" || String(value) === \"*\";\n}\nfunction hasInvalidWildcardOrder(major, minor, patch) {\n\treturn isWildcard(major) && !isWildcard(minor) || isWildcard(minor) && Boolean(patch) && !isWildcard(patch);\n}\nfunction replaceTilde(comparator, options) {\n\tconst expression = options.loose ? LOOSE_TILDE : STRICT_TILDE;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn prerelease ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;\n\t});\n}\nfunction replaceTildes(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceTilde(part, options)).join(\" \");\n}\nfunction replaceCaret(comparator, options) {\n\tconst expression = options.loose ? LOOSE_CARET : STRICT_CARET;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return major === \"0\" ? `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (prerelease) return major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch}-${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\treturn major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;\n\t});\n}\nfunction replaceCarets(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceCaret(part, options)).join(\" \");\n}\nfunction replaceXRange(comparator, options) {\n\tconst expression = options.loose ? LOOSE_XRANGE : STRICT_XRANGE;\n\treturn comparator.trim().replace(expression, (match, rawOperator, rawMajor, rawMinor, rawPatch) => {\n\t\tlet operator = rawOperator;\n\t\tlet major = rawMajor;\n\t\tlet minor = rawMinor;\n\t\tlet patch = rawPatch;\n\t\tif (hasInvalidWildcardOrder(String(major), minor === void 0 ? void 0 : String(minor), patch === void 0 ? void 0 : String(patch))) return comparator;\n\t\tconst wildcardMajor = isWildcard(major);\n\t\tconst wildcardMinor = wildcardMajor || isWildcard(minor);\n\t\tconst wildcardPatch = wildcardMinor || isWildcard(patch);\n\t\tif (operator === \"=\" && wildcardPatch) operator = \"\";\n\t\tif (wildcardMajor) return operator === \">\" || operator === \"<\" ? \"<0.0.0-0\" : \"*\";\n\t\tlet prerelease = options.includePrerelease ? \"-0\" : \"\";\n\t\tif (operator && wildcardPatch) {\n\t\t\tif (wildcardMinor) minor = 0;\n\t\t\tpatch = 0;\n\t\t\tif (operator === \">\") {\n\t\t\t\toperator = \">=\";\n\t\t\t\tif (wildcardMinor) {\n\t\t\t\t\tmajor = Number(major) + 1;\n\t\t\t\t\tminor = 0;\n\t\t\t\t} else minor = Number(minor) + 1;\n\t\t\t} else if (operator === \"<=\") {\n\t\t\t\toperator = \"<\";\n\t\t\t\tif (wildcardMinor) major = Number(major) + 1;\n\t\t\t\telse minor = Number(minor) + 1;\n\t\t\t}\n\t\t\tif (operator === \"<\") prerelease = \"-0\";\n\t\t\treturn `${operator}${major}.${minor}.${patch}${prerelease}`;\n\t\t}\n\t\tif (wildcardMinor) return `>=${major}.0.0${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (wildcardPatch) return `>=${major}.${minor}.0${prerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn match;\n\t});\n}\nfunction replaceXRanges(comparator, options) {\n\treturn comparator.split(/\\s+/).map((part) => replaceXRange(part, options)).join(\" \");\n}\nfunction replaceHyphenRange(range, options) {\n\tconst expression = options.loose ? LOOSE_HYPHEN : STRICT_HYPHEN;\n\treturn range.replace(expression, (_match, rawFrom, fromMajor, fromMinor, fromPatch, fromPrerelease, _fromBuild, rawTo, toMajor, toMinor, toPatch, toPrerelease) => {\n\t\tlet from = rawFrom;\n\t\tlet to = rawTo;\n\t\tif (isWildcard(fromMajor)) from = \"\";\n\t\telse if (isWildcard(fromMinor)) from = `>=${fromMajor}.0.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (isWildcard(fromPatch)) from = `>=${fromMajor}.${fromMinor}.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (fromPrerelease) from = `>=${from}`;\n\t\telse from = `>=${from}${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\tif (isWildcard(toMajor)) to = \"\";\n\t\telse if (isWildcard(toMinor)) to = `<${Number(toMajor) + 1}.0.0-0`;\n\t\telse if (isWildcard(toPatch)) to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;\n\t\telse if (toPrerelease) to = `<=${toMajor}.${toMinor}.${toPatch}-${toPrerelease}`;\n\t\telse if (options.includePrerelease) to = `<${toMajor}.${toMinor}.${Number(toPatch) + 1}-0`;\n\t\telse to = `<=${to}`;\n\t\treturn `${from} ${to}`.trim();\n\t});\n}\nfunction expandComparator(comparator, options) {\n\treturn replaceXRanges(replaceTildes(replaceCarets(comparator.replace(BUILD_SAFE, \"\"), options), options), options).trim().replace(STAR, \"\");\n}\nfunction parseSimpleRange(input, options) {\n\tlet parts = replaceHyphenRange(input.replace(BUILD_STRIP, \"\"), options).replace(COMPARATOR_TRIM, \"$1$2$3\").replace(TILDE_TRIM, \"$1~\").replace(CARET_TRIM, \"$1^\").split(\" \").map((part) => expandComparator(part, options)).join(\" \").split(/\\s+/).map((part) => part.trim().replace(options.includePrerelease ? GTE_ZERO_PRERELEASE : GTE_ZERO, \"\"));\n\tif (options.loose) parts = parts.filter((part) => LOOSE_COMPARATOR.test(part));\n\tconst unique = /* @__PURE__ */ new Map();\n\tfor (const comparator of parts.map((part) => parseComparator(part, options))) {\n\t\tif (comparator.value === \"<0.0.0-0\") return [comparator];\n\t\tunique.set(comparator.value, comparator);\n\t}\n\tif (unique.size > 1) unique.delete(\"\");\n\treturn [...unique.values()];\n}\nfunction parseRange(range, options = {}) {\n\tif (typeof range !== \"string\") return range;\n\tconst parsedOptions = { ...options };\n\tconst normalizedRange = range.trim().replaceAll(/\\s+/g, \" \");\n\tlet sets = normalizedRange.split(\"||\").map((part) => parseSimpleRange(part.trim(), parsedOptions)).filter((set) => set.length);\n\tif (!sets.length) throw new TypeError(`Range contains no valid comparator sets: ${normalizedRange}`);\n\tif (sets.length > 1) {\n\t\tconst first = sets[0];\n\t\tsets = sets.filter((set) => set[0]?.value !== \"<0.0.0-0\");\n\t\tif (!sets.length) sets = [first];\n\t\telse if (sets.length > 1) {\n\t\t\tconst any = sets.find((set) => set.length === 1 && set[0]?.value === \"\");\n\t\t\tif (any) sets = [any];\n\t\t}\n\t}\n\treturn {\n\t\toptions: parsedOptions,\n\t\tsets\n\t};\n}\nfunction tryParseRange(range, options = {}) {\n\ttry {\n\t\treturn parseRange(range, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nfunction testParsedRange(range, version) {\n\treturn range.sets.some((set) => testComparatorSet(set, version, range.options));\n}\nfunction testRangeVersion(range, version) {\n\tconst parsed = tryParse(version, range.options);\n\treturn parsed ? testParsedRange(range, parsed) : false;\n}\nfunction normalizeRange(range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? formatRange(parsed) || \"*\" : null;\n}\nfunction satisfies(version, range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? testRangeVersion(parsed, version) : false;\n}\n//#endregion\nexport { satisfies as f, tryParseRange as h, normalizeRange as l, parseRange as m };\n", "import { F as safeRegex, M as PRERELEASE_LOOSE, S as tryParse, T as COERCE_FULL, j as PRERELEASE, w as COERCE, y as formatComparableVersion } from \"./comparison-DenM3wCn.mjs\";\n//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.js\nconst COERCE_EXACT = safeRegex(COERCE);\nconst COERCE_FULL_EXACT = safeRegex(COERCE_FULL);\nsafeRegex(`^${PRERELEASE}$`);\nsafeRegex(`^${PRERELEASE_LOOSE}$`);\nfunction normalize(version, options = {}) {\n\tconst parsed = tryParse(version, options);\n\treturn parsed ? formatComparableVersion(parsed) : null;\n}\nfunction coerce(value, options = {}) {\n\tif (typeof value === \"object\") return value;\n\tconst input = typeof value === \"number\" ? String(value) : value;\n\tlet match = null;\n\tif (options.rtl) {\n\t\tconst source = options.includePrerelease ? COERCE_FULL : COERCE;\n\t\tconst expression = safeRegex(source, \"g\");\n\t\tlet next;\n\t\twhile ((next = expression.exec(input)) && (!match || match.index + match[0].length !== input.length)) {\n\t\t\tif (!match || next.index + next[0].length !== match.index + match[0].length) match = next;\n\t\t\texpression.lastIndex = next.index + next[1].length + next[2].length;\n\t\t}\n\t} else match = (options.includePrerelease ? COERCE_FULL_EXACT : COERCE_EXACT).exec(input);\n\tif (!match) return null;\n\tconst major = match[2];\n\tconst minor = match[3] || \"0\";\n\tconst patch = match[4] || \"0\";\n\tconst prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : \"\";\n\tconst build = options.includePrerelease && match[6] ? `+${match[6]}` : \"\";\n\treturn tryParse(`${major}.${minor}.${patch}${prerelease}${build}`, options);\n}\n//#endregion\nexport { coerce as n, normalize as p };\n", "import { t as compare } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs\";\nimport { f as satisfies, m as parseRange } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { p as normalize } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs\";\nimport { isUUIDv7 as isUUIDv7$1 } from \"./uuidv7.mjs\";\nimport { MAX_COMPILED_CATALOG_BYTES, MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE, MAX_TARGET_COHORTS_PER_RELEASE, NUMERIC_COHORT_SIZE, RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, canonicalizeAppVersion, canonicalizeAppVersion as canonicalizeAppVersion$1, getNumericCohortValue, getRolledOutNumericCohorts, isCustomCohort, normalizeCohortValue, normalizeRolloutCohortCount } from \"@hot-updater/protocol\";\n//#region src/releaseCatalogCompiler.ts\nvar ReleaseCatalogCompilationError = class extends Error {\n\tcode;\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.name = \"ReleaseCatalogCompilationError\";\n\t\tthis.code = code;\n\t}\n};\nfunction compareBounds(left, right) {\n\treturn compare(left, right);\n}\nfunction strongerLower(current, candidate) {\n\tif (current === null) return candidate;\n\tconst compared = compareBounds(candidate.version, current.version);\n\tif (compared > 0) return candidate;\n\tif (compared < 0) return current;\n\treturn {\n\t\tversion: current.version,\n\t\tinclusive: current.inclusive && candidate.inclusive\n\t};\n}\nfunction strongerUpper(current, candidate) {\n\tif (current === null) return candidate;\n\tconst compared = compareBounds(candidate.version, current.version);\n\tif (compared < 0) return candidate;\n\tif (compared > 0) return current;\n\treturn {\n\t\tversion: current.version,\n\t\tinclusive: current.inclusive && candidate.inclusive\n\t};\n}\nfunction comparatorVersion(comparator) {\n\tconst version = comparator.version && normalize(comparator.version);\n\tif (version === null) throw new ReleaseCatalogCompilationError(\"INVALID_TARGET_RANGE\", `Invalid comparator: ${comparator.value}`);\n\treturn version;\n}\nfunction comparatorSetToInterval(comparators) {\n\tlet lower = null;\n\tlet upper = null;\n\tfor (const comparator of comparators) {\n\t\tif (comparator.version === null) continue;\n\t\tconst version = comparatorVersion(comparator);\n\t\tif (comparator.operator === \"\") {\n\t\t\tlower = strongerLower(lower, {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion\n\t\t\t});\n\t\t\tupper = strongerUpper(upper, {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion\n\t\t\t});\n\t\t} else if (comparator.operator === \">\") lower = strongerLower(lower, {\n\t\t\tinclusive: false,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \">=\") lower = strongerLower(lower, {\n\t\t\tinclusive: true,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \"<\") upper = strongerUpper(upper, {\n\t\t\tinclusive: false,\n\t\t\tversion\n\t\t});\n\t\telse if (comparator.operator === \"<=\") upper = strongerUpper(upper, {\n\t\t\tinclusive: true,\n\t\t\tversion\n\t\t});\n\t}\n\tif (lower !== null && upper !== null) {\n\t\tconst compared = compareBounds(lower.version, upper.version);\n\t\tif (compared > 0 || compared === 0 && (!lower.inclusive || !upper.inclusive)) return null;\n\t}\n\treturn {\n\t\tlower,\n\t\tupper\n\t};\n}\nfunction rangeToIntervals(range) {\n\ttry {\n\t\treturn parseRange(range).sets.flatMap((comparators) => {\n\t\t\tconst interval = comparatorSetToInterval(comparators);\n\t\t\treturn interval === null ? [] : [interval];\n\t\t});\n\t} catch {\n\t\tthrow new ReleaseCatalogCompilationError(\"INVALID_TARGET_RANGE\", `Invalid target app-version range: ${range}`);\n\t}\n}\nfunction releaseDescriptor(release) {\n\treturn {\n\t\treleaseId: release.id,\n\t\tkind: release.kind,\n\t\tbundleId: release.bundleId,\n\t\trolloutCohortCount: release.rolloutCohortCount,\n\t\ttargetCohorts: [...new Set(release.targetCohorts)].sort(),\n\t\tshouldForceUpdate: release.shouldForceUpdate,\n\t\tmessage: release.message\n\t};\n}\nfunction validateReleases(releases, strategy) {\n\tconst enabled = releases.filter((release) => release.enabled).sort((left, right) => right.id.localeCompare(left.id));\n\tconst seenIds = /* @__PURE__ */ new Set();\n\tfor (const release of enabled) {\n\t\tif (!isUUIDv7$1(release.id)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} must use a canonical lowercase UUIDv7 ID`);\n\t\tif (seenIds.has(release.id)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Duplicate Release ID: ${release.id}`);\n\t\tseenIds.add(release.id);\n\t\tif (release.strategy !== strategy) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has the wrong strategy`);\n\t\tif (release.bundleId === null) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has no Bundle`);\n\t\tif (release.targetCohorts.length > MAX_TARGET_COHORTS_PER_RELEASE) throw new ReleaseCatalogCompilationError(\"TARGET_COHORT_LIMIT\", `Release ${release.id} exceeds ${MAX_TARGET_COHORTS_PER_RELEASE} target cohorts`);\n\t\tif (strategy === \"APP_VERSION\" && (release.targetAppVersion === null || release.fingerprintHash !== null)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has an invalid app-version target`);\n\t\tif (strategy === \"FINGERPRINT\" && (release.fingerprintHash === null || release.targetAppVersion !== null)) throw new ReleaseCatalogCompilationError(\"INVALID_RELEASE\", `Release ${release.id} has an invalid fingerprint target`);\n\t}\n\treturn enabled;\n}\nfunction collectFrontierReleaseIds(releases) {\n\tif (releases.every((release) => normalizeRolloutCohortCount(release.rolloutCohortCount) >= NUMERIC_COHORT_SIZE)) {\n\t\tconst retained = /* @__PURE__ */ new Set();\n\t\tconst bundleIds = /* @__PURE__ */ new Set();\n\t\tfor (const release of releases) {\n\t\t\tif (release.bundleId !== null && !bundleIds.has(release.bundleId)) {\n\t\t\t\tbundleIds.add(release.bundleId);\n\t\t\t\tretained.add(release.id);\n\t\t\t}\n\t\t\tif (bundleIds.size >= 11) break;\n\t\t}\n\t\treturn retained;\n\t}\n\tconst explicitTargetCohorts = new Set(releases.flatMap((release) => release.targetCohorts));\n\tconst cohortStates = [\n\t\tvoid 0,\n\t\t...Array.from({ length: 1e3 }, (_, index) => String(index + 1)),\n\t\t...[...explicitTargetCohorts].sort(),\n\t\t\"release-catalog-non-targeted-cohort\"\n\t].map((cohort) => {\n\t\tconst normalized = cohort === void 0 ? void 0 : normalizeCohortValue(cohort);\n\t\treturn {\n\t\t\tisCustom: normalized !== void 0 && isCustomCohort(normalized),\n\t\t\tnormalized,\n\t\t\tnumeric: normalized === void 0 ? null : getNumericCohortValue(normalized),\n\t\t\tbundleIds: /* @__PURE__ */ new Set(),\n\t\t\tcomplete: false\n\t\t};\n\t});\n\tconst stateIndexesByCohort = /* @__PURE__ */ new Map();\n\tconst fullRolloutStateIndexes = [];\n\tfor (const [index, state] of cohortStates.entries()) {\n\t\tif (state.normalized !== void 0) {\n\t\t\tconst indexes = stateIndexesByCohort.get(state.normalized) ?? [];\n\t\t\tindexes.push(index);\n\t\t\tstateIndexesByCohort.set(state.normalized, indexes);\n\t\t}\n\t\tif (state.normalized === void 0 || state.numeric !== null || state.isCustom) fullRolloutStateIndexes.push(index);\n\t}\n\tconst retained = /* @__PURE__ */ new Set();\n\tlet incompleteStateCount = cohortStates.length;\n\tfor (const release of releases) {\n\t\tconst rolloutCohortCount = normalizeRolloutCohortCount(release.rolloutCohortCount);\n\t\tconst eligibleStateIndexes = /* @__PURE__ */ new Set();\n\t\tif (rolloutCohortCount >= NUMERIC_COHORT_SIZE) for (const index of fullRolloutStateIndexes) eligibleStateIndexes.add(index);\n\t\telse if (rolloutCohortCount > 0) for (const numericCohort of getRolledOutNumericCohorts(release.id, rolloutCohortCount)) for (const index of stateIndexesByCohort.get(String(numericCohort)) ?? []) eligibleStateIndexes.add(index);\n\t\tfor (const targetCohort of new Set(release.targetCohorts.map(normalizeCohortValue))) for (const index of stateIndexesByCohort.get(targetCohort) ?? []) eligibleStateIndexes.add(index);\n\t\tfor (const index of eligibleStateIndexes) {\n\t\t\tconst state = cohortStates[index];\n\t\t\tif (state.complete) continue;\n\t\t\tif (release.bundleId !== null && !state.bundleIds.has(release.bundleId)) {\n\t\t\t\tstate.bundleIds.add(release.bundleId);\n\t\t\t\tretained.add(release.id);\n\t\t\t}\n\t\t\tif (state.bundleIds.size >= 11) {\n\t\t\t\tstate.complete = true;\n\t\t\t\tincompleteStateCount -= 1;\n\t\t\t}\n\t\t}\n\t\tif (incompleteStateCount === 0) break;\n\t}\n\treturn retained;\n}\nfunction intervalContainsSegment(interval, segment) {\n\tif (interval.lower !== null) {\n\t\tif (segment.lower === null) return false;\n\t\tconst compared = compareBounds(segment.lower.version, interval.lower.version);\n\t\tif (compared < 0 || compared === 0 && segment.lower.inclusive && !interval.lower.inclusive) return false;\n\t}\n\tif (interval.upper !== null) {\n\t\tif (segment.upper === null) return false;\n\t\tconst compared = compareBounds(segment.upper.version, interval.upper.version);\n\t\tif (compared > 0 || compared === 0 && segment.upper.inclusive && !interval.upper.inclusive) return false;\n\t}\n\treturn true;\n}\nfunction atomicVersionSegments(intervals) {\n\tconst endpoints = [...new Set(intervals.flatMap((interval) => [interval.lower?.version, interval.upper?.version].filter((version) => version !== void 0)))].sort(compareBounds);\n\tif (endpoints.length === 0) return [{\n\t\tlower: null,\n\t\tupper: null\n\t}];\n\tconst segments = [{\n\t\tlower: null,\n\t\tupper: {\n\t\t\tinclusive: false,\n\t\t\tversion: endpoints[0]\n\t\t}\n\t}];\n\tfor (let index = 0; index < endpoints.length; index += 1) {\n\t\tconst endpoint = endpoints[index];\n\t\tsegments.push({\n\t\t\tlower: {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion: endpoint\n\t\t\t},\n\t\t\tupper: {\n\t\t\t\tinclusive: true,\n\t\t\t\tversion: endpoint\n\t\t\t}\n\t\t});\n\t\tconst next = endpoints[index + 1];\n\t\tif (next !== void 0) segments.push({\n\t\t\tlower: {\n\t\t\t\tinclusive: false,\n\t\t\t\tversion: endpoint\n\t\t\t},\n\t\t\tupper: {\n\t\t\t\tinclusive: false,\n\t\t\t\tversion: next\n\t\t\t}\n\t\t});\n\t}\n\tsegments.push({\n\t\tlower: {\n\t\t\tinclusive: false,\n\t\t\tversion: endpoints.at(-1)\n\t\t},\n\t\tupper: null\n\t});\n\treturn segments;\n}\nfunction sameIndexes(left, right) {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\nfunction mergeSegments(segments) {\n\tconst merged = [];\n\tfor (const segment of segments) {\n\t\tconst previous = merged.at(-1);\n\t\tif (previous && sameIndexes(previous.releaseIndexes, segment.releaseIndexes) && sameIndexes(previous.rollbackReleaseIndexes, segment.rollbackReleaseIndexes)) merged[merged.length - 1] = {\n\t\t\t...previous,\n\t\t\tupper: segment.upper\n\t\t};\n\t\telse merged.push(segment);\n\t}\n\treturn merged;\n}\nfunction compileAppVersion(releases) {\n\tconst ranges = /* @__PURE__ */ new Map();\n\tfor (const release of releases) ranges.set(release.id, rangeToIntervals(release.targetAppVersion));\n\tconst segmentReleases = atomicVersionSegments([...ranges.values()].flat()).map((segment) => {\n\t\tconst applicable = releases.filter((release) => ranges.get(release.id).some((range) => intervalContainsSegment(range, segment)));\n\t\treturn {\n\t\t\trollbackIds: new Set(applicable.map(({ id }) => id)),\n\t\t\tsegment,\n\t\t\tretainedIds: collectFrontierReleaseIds(applicable)\n\t\t};\n\t});\n\tconst retainedIds = new Set(segmentReleases.flatMap(({ retainedIds, rollbackIds }) => [...retainedIds, ...rollbackIds]));\n\tconst retainedReleases = releases.filter((release) => retainedIds.has(release.id));\n\tconst descriptorIndex = new Map(retainedReleases.map((release, index) => [release.id, index]));\n\tconst segments = mergeSegments(segmentReleases.map(({ segment, retainedIds, rollbackIds }) => ({\n\t\t...segment,\n\t\treleaseIndexes: releases.filter((release) => retainedIds.has(release.id)).map((release) => descriptorIndex.get(release.id)).filter((index) => index !== void 0),\n\t\trollbackReleaseIndexes: releases.filter((release) => rollbackIds.has(release.id)).map((release) => descriptorIndex.get(release.id)).filter((index) => index !== void 0)\n\t}))).filter((segment) => segment.releaseIndexes.length > 0 || segment.rollbackReleaseIndexes.length > 0);\n\treturn {\n\t\tenvelope: {\n\t\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\t\tsegments,\n\t\t\tstrategy: \"APP_VERSION\"\n\t\t},\n\t\tretainedReleases\n\t};\n}\nfunction compileFingerprint(releases) {\n\tconst retainedIds = collectFrontierReleaseIds(releases);\n\tconst retainedReleases = releases;\n\treturn {\n\t\tenvelope: {\n\t\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\t\treleaseIndexes: retainedReleases.map((release, index) => retainedIds.has(release.id) ? index : -1).filter((index) => index >= 0),\n\t\t\trollbackReleaseIndexes: retainedReleases.map((_, index) => index),\n\t\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\t\tstrategy: \"FINGERPRINT\"\n\t\t},\n\t\tretainedReleases\n\t};\n}\nasync function sha256(value) {\n\tconst digest = await globalThis.crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(value));\n\treturn `sha256:${[...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\nfunction canonicalStringify(value) {\n\tif (value === null || typeof value !== \"object\") return JSON.stringify(value);\n\tif (Array.isArray(value)) return `[${value.map(canonicalStringify).join(\",\")}]`;\n\tconst record = value;\n\treturn `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalStringify(record[key])}`).join(\",\")}}`;\n}\nasync function compileReleaseCatalog(input) {\n\tconst releases = validateReleases(input.releases, input.strategy);\n\tconst targetCohorts = new Set(releases.flatMap((release) => release.targetCohorts));\n\tif (targetCohorts.size > MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE) throw new ReleaseCatalogCompilationError(\"DISTINCT_TARGET_COHORT_LIMIT\", `Scope exceeds ${MAX_DISTINCT_TARGET_COHORTS_PER_SCOPE} distinct target cohorts`);\n\tconst { envelope, retainedReleases } = input.strategy === \"APP_VERSION\" ? compileAppVersion(releases) : compileFingerprint(releases);\n\tconst payload = {\n\t\t...envelope,\n\t\treleaseDescriptors: retainedReleases.map(releaseDescriptor)\n\t};\n\tconst canonicalPayload = canonicalStringify(payload);\n\tconst byteSize = new TextEncoder().encode(canonicalPayload).byteLength;\n\tif (byteSize > MAX_COMPILED_CATALOG_BYTES) throw new ReleaseCatalogCompilationError(\"CATALOG_OVERSIZE\", `Compiled Release catalog is ${byteSize} bytes; maximum is ${MAX_COMPILED_CATALOG_BYTES}`);\n\treturn {\n\t\tbyteSize,\n\t\tcanonicalPayload,\n\t\tcatalogHash: await sha256(canonicalPayload),\n\t\tdiagnostics: {\n\t\t\tbyteSize,\n\t\t\tdescriptorCount: payload.releaseDescriptors.length,\n\t\t\tdistinctTargetCohortCount: targetCohorts.size,\n\t\t\treleaseCount: releases.length,\n\t\t\tsegmentCount: payload.strategy === \"APP_VERSION\" ? payload.segments.length : 1\n\t\t},\n\t\tpayload\n\t};\n}\nfunction versionInSegment(version, segment) {\n\tif (segment.lower !== null) {\n\t\tconst compared = compareBounds(version, segment.lower.version);\n\t\tif (compared < 0 || compared === 0 && !segment.lower.inclusive) return false;\n\t}\n\tif (segment.upper !== null) {\n\t\tconst compared = compareBounds(version, segment.upper.version);\n\t\tif (compared > 0 || compared === 0 && !segment.upper.inclusive) return false;\n\t}\n\treturn true;\n}\nfunction projectCompiledCatalog(catalog, appVersion) {\n\tlet indexes;\n\tif (catalog.strategy === \"FINGERPRINT\") indexes = catalog.releaseIndexes;\n\telse {\n\t\tconst canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);\n\t\tif (!canonicalVersion) return [];\n\t\tindexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.releaseIndexes ?? [];\n\t}\n\treturn indexes.map((index) => catalog.releaseDescriptors[index]);\n}\nfunction projectCompiledRollbackCatalog(catalog, appVersion) {\n\tlet indexes;\n\tif (catalog.strategy === \"FINGERPRINT\") indexes = catalog.rollbackReleaseIndexes;\n\telse {\n\t\tconst canonicalVersion = appVersion && canonicalizeAppVersion(appVersion);\n\t\tif (!canonicalVersion) return [];\n\t\tindexes = catalog.segments.find((segment) => versionInSegment(canonicalVersion, segment))?.rollbackReleaseIndexes ?? [];\n\t}\n\treturn indexes.map((index) => catalog.releaseDescriptors[index]);\n}\nfunction referenceCompatibleReleases(releases, appVersion) {\n\tconst canonicalVersion = canonicalizeAppVersion(appVersion);\n\tif (!canonicalVersion) return [];\n\treturn releases.filter((release) => release.enabled && release.targetAppVersion !== null && satisfies(canonicalVersion, release.targetAppVersion));\n}\n//#endregion\nexport { ReleaseCatalogCompilationError, canonicalizeAppVersion$1 as canonicalizeAppVersion, compileReleaseCatalog, projectCompiledCatalog, projectCompiledRollbackCatalog, referenceCompatibleReleases };\n", "//#region src/releaseManagement.ts\nvar ReleaseManagementError = class extends Error {\n\tcode;\n\tname = \"ReleaseManagementError\";\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { ReleaseManagementError };\n", "//#region src/releaseCatalogMutation.ts\nvar ReleaseCatalogMutationError = class extends Error {\n\tcode;\n\tname = \"ReleaseCatalogMutationError\";\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\n//#endregion\nexport { ReleaseCatalogMutationError };\n", "import { f as satisfies } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { n as coerce } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs\";\n//#region src/semverSatisfies.ts\nconst semverSatisfies = (targetAppVersion, currentVersion) => {\n\tconst currentCoerce = coerce(currentVersion);\n\tif (!currentCoerce) return false;\n\treturn satisfies(currentCoerce, targetAppVersion);\n};\n//#endregion\nexport { semverSatisfies };\n", "//#region src/serverPlugin/definePlugin.ts\n/** Declares a plugin; Hot Updater's own plugins and third-party ones use the same contract. */\nconst definePlugin = (plugin) => plugin;\n//#endregion\nexport { definePlugin };\n", "//#region src/serverPlugin/schema.ts\nconst defineTable = (fields, options) => ({\n\tkind: \"table\",\n\tfields,\n\tkey: options.key,\n\tderived: options.derived ?? {},\n\tindexes: options.indexes ?? {},\n\t...options.retention === void 0 ? {} : { retention: options.retention }\n});\nconst defineAggregate = (fields, options) => ({\n\tkind: \"aggregate\",\n\tfields,\n\tkey: options.key,\n\tcounters: options.counters ?? [],\n\tgauges: options.gauges ?? [],\n\tdistinct: options.distinct ?? [],\n\tshards: options.shards ?? 1,\n\tindexes: options.indexes ?? {},\n\t...options.batched ? { batched: true } : {},\n\t...options.retention === void 0 ? {} : { retention: options.retention }\n});\n//#endregion\nexport { defineAggregate, defineTable };\n", "//#region src/serverPlugin/errors.ts\nvar DatabaseConstraintError = class extends Error {\n\treason;\n\tmodel;\n\tname = \"DatabaseConstraintError\";\n\tconstructor(reason, model) {\n\t\tsuper(`${model}: ${reason}`);\n\t\tthis.reason = reason;\n\t\tthis.model = model;\n\t}\n};\n/** The retry budget ran out; ingestion answers 503 with Retry-After. */\nvar DatabaseConflictError = class extends Error {\n\tname = \"DatabaseConflictError\";\n};\n/** The write may or may not have committed; it is reported, never rerun. */\nvar DatabaseAmbiguousCommitError = class extends Error {\n\tname = \"DatabaseAmbiguousCommitError\";\n};\nvar DatabaseTransactionError = class extends Error {\n\tname = \"DatabaseTransactionError\";\n};\n/** A read that does not fit its model, such as an unknown index, a missing `where` field, or an out-of-range limit. */\nvar DatabaseQueryError = class extends Error {\n\tname = \"DatabaseQueryError\";\n};\n/** A malformed cursor, or one from a read with another model, index, filter, order, or range. */\nvar DatabaseCursorError = class extends Error {\n\tname = \"DatabaseCursorError\";\n};\n//#endregion\nexport { DatabaseAmbiguousCommitError, DatabaseConflictError, DatabaseConstraintError, DatabaseCursorError, DatabaseQueryError, DatabaseTransactionError };\n", "import { DatabaseConflictError } from \"./errors.mjs\";\n//#region src/serverPlugin/busy.ts\n/** Error names the AWS SDKs give a throttled request, as their retry strategy classifies them. */\nconst THROTTLING_NAMES = /* @__PURE__ */ new Set([\n\t\"ProvisionedThroughputExceededException\",\n\t\"RequestLimitExceeded\",\n\t\"RequestThrottled\",\n\t\"RequestThrottledException\",\n\t\"SlowDown\",\n\t\"ThrottledException\",\n\t\"Throttling\",\n\t\"ThrottlingException\",\n\t\"TooManyRequestsException\"\n]);\n/** gRPC's RESOURCE_EXHAUSTED, the status Firestore throttles a request with. */\nconst RESOURCE_EXHAUSTED = 8;\n/**\n* Whether the database is busy rather than broken, so the same request can\n* succeed later: a transaction ran out of retries, or the backend throttled\n* a request. Writes already retry transient failures, throttled ones\n* included, until the budget runs out. A throttled read throws the backend's\n* own error, so it is recognized by what the backends call it: a name the\n* AWS SDKs retry as throttling, HTTP 429, or gRPC's RESOURCE_EXHAUSTED.\n*/\nconst isDatabaseBusyError = (error) => {\n\tif (error instanceof DatabaseConflictError) return true;\n\tif (typeof error !== \"object\" || error === null) return false;\n\tconst { name, code, message, status, statusCode, $metadata } = error;\n\treturn typeof name === \"string\" && THROTTLING_NAMES.has(name) || [\n\t\tstatus,\n\t\tstatusCode,\n\t\t$metadata?.httpStatusCode\n\t].includes(429) || code === RESOURCE_EXHAUSTED && typeof message === \"string\" && message.includes(\"RESOURCE_EXHAUSTED\");\n};\n//#endregion\nexport { isDatabaseBusyError };\n", "//#region src/database/distinct.ts\n/**\n* HyperLogLog sketches, the storage engine's `distinct` aggregate metric: a\n* sketch is 1,024 registers stored as a 1,024-character string, so adding a\n* value, merging sketches, and counting one never need the values back.\n*/\nconst PRECISION = 10;\nconst REGISTER_COUNT = 1024;\nconst MAX_RANK = 55;\nconst hash = (value) => {\n\tlet result = 14695981039346656037n;\n\tfor (const byte of new TextEncoder().encode(value)) {\n\t\tresult ^= BigInt(byte);\n\t\tresult = BigInt.asUintN(64, result * 1099511628211n);\n\t}\n\treturn result;\n};\nconst OFFSET = 33;\nconst decode = (summary) => {\n\tif (!summary) return new Uint8Array(REGISTER_COUNT);\n\tif (summary.length !== REGISTER_COUNT) throw new Error(\"Invalid distinct sketch\");\n\tconst registers = new Uint8Array(REGISTER_COUNT);\n\tfor (let index = 0; index < REGISTER_COUNT; index += 1) {\n\t\tconst value = summary.charCodeAt(index) - OFFSET;\n\t\tif (!Number.isInteger(value) || value < 0 || value > MAX_RANK) throw new Error(\"Invalid distinct sketch\");\n\t\tregisters[index] = value;\n\t}\n\treturn registers;\n};\nconst encode = (registers) => Array.from(registers, (value) => String.fromCharCode(value + OFFSET)).join(\"\");\nconst distinctRegister = (identity) => {\n\tconst value = hash(identity);\n\tconst index = Number(value & BigInt(1023));\n\tlet remainder = value >> BigInt(PRECISION);\n\tlet rank = 1;\n\twhile ((remainder & 1n) === 0n && rank < MAX_RANK) {\n\t\trank += 1;\n\t\tremainder >>= 1n;\n\t}\n\treturn {\n\t\tindex,\n\t\trank,\n\t\tcharacter: String.fromCharCode(rank + OFFSET)\n\t};\n};\n/**\n* The sketch with `identity` added; a missing sketch is the empty one. A\n* plugin passes it as a `distinct` column's change to `tx.aggregate`.\n*/\nconst addDistinct = (summary, identity) => {\n\tconst registers = decode(summary);\n\tconst { index, rank } = distinctRegister(identity);\n\tregisters[index] = Math.max(registers[index], rank);\n\treturn encode(registers);\n};\n/**\n* The union of sketches, register by register: how a plugin combines a\n* `distinct` column across the aggregate rows it reads.\n*/\nconst mergeDistinct = (summaries) => {\n\tconst merged = new Uint8Array(REGISTER_COUNT);\n\tfor (const summary of summaries) {\n\t\tconst registers = decode(summary);\n\t\tfor (let index = 0; index < REGISTER_COUNT; index += 1) merged[index] = Math.max(merged[index], registers[index]);\n\t}\n\treturn encode(merged);\n};\n/**\n* The estimated number of distinct values a sketch holds: how a plugin\n* reads a `distinct` column.\n*/\nconst countDistinct = (summary) => {\n\tconst registers = decode(summary);\n\tlet inverseSum = 0;\n\tlet empty = 0;\n\tfor (const register of registers) {\n\t\tinverseSum += 2 ** -register;\n\t\tif (register === 0) empty += 1;\n\t}\n\tconst raw = .7213 / 1.0010537109375 * REGISTER_COUNT ** 2 / inverseSum;\n\tconst estimate = raw <= 2.5 * REGISTER_COUNT && empty > 0 ? REGISTER_COUNT * Math.log(REGISTER_COUNT / empty) : raw;\n\treturn Math.max(0, Math.round(estimate));\n};\n//#endregion\nexport { addDistinct, countDistinct, distinctRegister, mergeDistinct };\n", "//#region src/serverPlugin/configError.ts\n/** A misconfigured `createHotUpdater` call, reported at startup. */\nvar HotUpdaterConfigError = class extends Error {\n\tname = \"HotUpdaterConfigError\";\n};\n//#endregion\nexport { HotUpdaterConfigError };\n", "import { l as normalizeRange } from \"./node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs\";\nimport { createReleaseCatalogScopeKey, encodeChannelKey, parseReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/baseCandidateKey.ts\n/**\n* A new bundle's base-candidate key, which `findBaseBundleIds` on core's API\n* and on a plugin's `ctx.core` takes: the Release Catalog scope its devices\n* update from, and for an app version its normalized range; null for a\n* target without a valid range. The CLI's deploy produces it this way.\n*/\nconst targetBaseCandidateKey = (target) => {\n\tconst channelKey = encodeChannelKey(target.channel);\n\tif (target.fingerprintHash) return JSON.stringify([createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tfingerprintHash: target.fingerprintHash,\n\t\tplatform: target.platform,\n\t\tstrategy: \"FINGERPRINT\"\n\t})]);\n\tconst range = target.appVersion === null ? null : normalizeRange(target.appVersion);\n\treturn range === null ? null : JSON.stringify([createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tplatform: target.platform,\n\t\tstrategy: \"APP_VERSION\"\n\t}), range]);\n};\n/**\n* The scope and range a base-candidate key names, null for any other\n* string: what an implementation of `findBaseBundleIds` reads the key with.\n*/\nconst parseBaseCandidateKey = (key) => {\n\ttry {\n\t\tconst parsed = JSON.parse(key);\n\t\tif (!Array.isArray(parsed) || typeof parsed[0] !== \"string\") return null;\n\t\tconst [scopeKey, text] = parsed;\n\t\tconst { strategy } = parseReleaseCatalogScopeKey(scopeKey);\n\t\tif (strategy === \"FINGERPRINT\") return parsed.length === 1 ? {\n\t\t\tscopeKey,\n\t\t\trange: null\n\t\t} : null;\n\t\tconst range = parsed.length === 2 && typeof text === \"string\" ? normalizeRange(text) : null;\n\t\treturn range === null ? null : {\n\t\t\tscopeKey,\n\t\t\trange\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n};\n//#endregion\nexport { parseBaseCandidateKey, targetBaseCandidateKey };\n", "//#region src/database/adapter.ts\n/**\n* The version column every stored row carries, which a guarded write\n* compares and bumps. An adapter that is neither SQL nor key-value, such as\n* the MongoDB adapter, stores and checks it itself.\n*/\nconst DATABASE_VERSION_COLUMN = \"_v\";\nvar DatabaseSchemaError = class extends Error {\n\tname = \"DatabaseSchemaError\";\n};\n/**\n* The column `name` of `table`, or a `DatabaseSchemaError`: how an adapter\n* that is neither SQL nor key-value, such as the MongoDB adapter, reads a\n* column's type.\n*/\nconst findPhysicalColumn = (table, name) => {\n\tconst column = table.columns.find((candidate) => candidate.name === name);\n\tif (column === void 0) throw new DatabaseSchemaError(`${table.name} has no column ${name}.`);\n\treturn column;\n};\n/**\n* The index `name` of `table`, or a `DatabaseSchemaError`: how an adapter\n* that is neither SQL nor key-value, such as the MongoDB adapter, resolves a\n* query's `index`.\n*/\nconst findPhysicalIndex = (table, name) => {\n\tconst index = table.indexes.find((candidate) => candidate.name === name);\n\tif (index === void 0) throw new DatabaseSchemaError(`${table.name} has no index ${name}.`);\n\treturn index;\n};\n/**\n* The columns that order an index read and close its cursors: the sort\n* columns, then the key columns that neither `eq` nor `sort` fixes.\n*/\nconst indexOrderColumns = (table, index) => [...index.sort, ...table.key.filter((column) => !index.sort.includes(column) && !index.eq.includes(column))];\n/**\n* When a row of a table with retention expires, in epoch milliseconds, or\n* undefined when the table keeps its rows or the row's time is null.\n*/\nconst expiresAt = (table, row) => {\n\tconst time = table.retention && row[table.retention.column];\n\treturn typeof time === \"number\" ? time + table.retention.ms : void 0;\n};\n/**\n* The primary key of a row, in key-column order: what `get` takes for it.\n* An adapter that is neither SQL nor key-value, such as the MongoDB adapter,\n* addresses rows by it.\n*/\nconst rowKey = (table, row) => table.key.map((column) => {\n\tconst value = row[column];\n\tif (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") throw new DatabaseSchemaError(`${table.name}.${column} is a key column and must be a string, number, or boolean.`);\n\treturn value;\n});\n//#endregion\nexport { DATABASE_VERSION_COLUMN, DatabaseSchemaError, expiresAt, findPhysicalColumn, findPhysicalIndex, indexOrderColumns, rowKey };\n", "import { findPhysicalColumn, indexOrderColumns } from \"./adapter.mjs\";\n//#region src/database/values.ts\nvar DatabaseValueError = class extends Error {\n\tname = \"DatabaseValueError\";\n};\n/**\n* Compares strings in UTF-8 byte order, which is Unicode code point order:\n* the order the engine sorts string keys in. A plugin that merges rows from\n* several reads, as Insights does, keeps that order with it.\n*/\nconst compareUtf8 = (left, right) => {\n\tlet leftIndex = 0;\n\tlet rightIndex = 0;\n\twhile (leftIndex < left.length && rightIndex < right.length) {\n\t\tconst leftPoint = left.codePointAt(leftIndex);\n\t\tconst rightPoint = right.codePointAt(rightIndex);\n\t\tif (leftPoint !== rightPoint) return leftPoint < rightPoint ? -1 : 1;\n\t\tleftIndex += leftPoint > 65535 ? 2 : 1;\n\t\trightIndex += rightPoint > 65535 ? 2 : 1;\n\t}\n\tconst leftDone = leftIndex >= left.length;\n\treturn leftDone === rightIndex >= right.length ? 0 : leftDone ? -1 : 1;\n};\n/** Orders strings by UTF-8 bytes, numbers numerically, and false before true. */\nconst compareKeyValues = (left, right) => {\n\tif (typeof left === \"string\" && typeof right === \"string\") return compareUtf8(left, right);\n\tif (typeof left === \"number\" && typeof right === \"number\") return left < right ? -1 : left > right ? 1 : 0;\n\tif (typeof left === \"boolean\" && typeof right === \"boolean\") return Number(left) - Number(right);\n\tthrow new DatabaseValueError(`Cannot compare ${typeof left} with ${typeof right}.`);\n};\n/** Compares tuples element by element; a shorter equal prefix sorts first. */\nconst compareTuples = (left, right) => {\n\tfor (let index = 0; index < Math.min(left.length, right.length); index += 1) {\n\t\tconst result = compareKeyValues(left[index], right[index]);\n\t\tif (result !== 0) return result;\n\t}\n\treturn left.length - right.length;\n};\n/** JSON text with object keys sorted, so a value compares equal after a store reorders map keys. */\nconst canonicalJson = (value) => JSON.stringify(value ?? null, (_, inner) => inner !== null && typeof inner === \"object\" && !Array.isArray(inner) ? Object.fromEntries(Object.entries(inner).sort(([left], [right]) => compareUtf8(left, right))) : inner);\nconst isKeyValue = (value) => typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value);\n/** Every `eq` tuple a row is indexed under; none when an index field is null. */\nconst indexEntries = (table, index, row) => {\n\tif (index.sort.some((column) => !isKeyValue(row[column]))) return [];\n\tlet entries = [[]];\n\tfor (const column of index.eq) {\n\t\tconst value = row[column];\n\t\tconst values = findPhysicalColumn(table, column).multi ? Array.isArray(value) ? value.filter(isKeyValue) : [] : isKeyValue(value) ? [value] : [];\n\t\tif (values.length === 0) return [];\n\t\tentries = entries.flatMap((entry) => [...new Set(values)].map((item) => [...entry, item]));\n\t}\n\treturn entries;\n};\n/** The row's position in an index read, following `indexOrderColumns`. */\nconst indexOrderTuple = (table, index, row) => indexOrderColumns(table, index).map((column) => {\n\tconst value = row[column];\n\tif (!isKeyValue(value)) throw new DatabaseValueError(`${table.name}.${column} is not orderable for index ${index.name}.`);\n\treturn value;\n});\nconst satisfiesBound = (tuple, bound, side) => {\n\tif (bound === void 0) return true;\n\tconst result = compareTuples(tuple.slice(0, bound.values.length), bound.values);\n\tif (result === 0) return bound.inclusive;\n\treturn side === \"lower\" ? result > 0 : result < 0;\n};\n/** Whether a stored row belongs to the result range of a query. */\nconst matchesQuery = (table, index, request, row) => indexEntries(table, index, row).some((entry) => compareTuples(entry, request.eq) === 0) && satisfiesBound(indexOrderTuple(table, index, row), request.lower, \"lower\") && satisfiesBound(indexOrderTuple(table, index, row), request.upper, \"upper\");\nconst INTEGER_TEXT = /^-?\\d+$/u;\nconst NUMBER_TEXT = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/iu;\nconst toNumber = (raw, integer) => {\n\tconst text = typeof raw === \"bigint\" ? raw.toString() : typeof raw === \"string\" ? raw : typeof raw === \"object\" && raw !== null && \"toString\" in raw ? String(raw) : void 0;\n\tconst value = typeof raw === \"number\" ? raw : text !== void 0 && (integer ? INTEGER_TEXT : NUMBER_TEXT).test(text) ? Number(text) : NaN;\n\tif (integer ? !Number.isSafeInteger(value) : !Number.isFinite(value)) throw new DatabaseValueError(`Expected a ${integer ? \"safe integer\" : \"finite number\"}.`);\n\treturn value;\n};\nconst toBoolean = (raw) => {\n\tif (raw === true || raw === 1 || raw === 1n || raw === \"1\" || raw === \"t\") return true;\n\tif (raw === false || raw === 0 || raw === 0n || raw === \"0\" || raw === \"f\") return false;\n\tif (raw === \"true\" || raw === \"false\") return raw === \"true\";\n\tthrow new DatabaseValueError(\"Expected a boolean.\");\n};\nconst toScalar = (column, raw) => {\n\tswitch (column.type) {\n\t\tcase \"string\":\n\t\t\tif (typeof raw !== \"string\") throw new DatabaseValueError(`Expected a string in ${column.name}.`);\n\t\t\treturn raw;\n\t\tcase \"integer\":\n\t\tcase \"number\": return toNumber(raw, column.type === \"integer\");\n\t\tcase \"boolean\": return toBoolean(raw);\n\t\tcase \"json\": return raw;\n\t}\n};\n/** Converts a backend value (int8 text, BigInt, Decimal, 0/1, JSON text) to a stored value. */\nconst normalizeStoredValue = (column, raw, options) => {\n\tif (raw === null || raw === void 0) return null;\n\tconst parsed = options.jsonText && (column.multi || column.type === \"json\") && typeof raw === \"string\" ? JSON.parse(raw) : raw;\n\tif (!column.multi) return toScalar(column, parsed);\n\tif (!Array.isArray(parsed) || parsed.length > 16) throw new DatabaseValueError(`Expected at most 16 values in ${column.name}.`);\n\treturn parsed.map((item) => toScalar(column, item));\n};\n/** Converts every column of a backend row; unknown backend columns are dropped. */\nconst normalizeStoredRow = (table, raw, options) => Object.fromEntries(table.columns.map((column) => [column.name, normalizeStoredValue(column, raw[column.name], options)]));\n//#endregion\nexport { DatabaseValueError, canonicalJson, compareKeyValues, compareTuples, compareUtf8, indexEntries, indexOrderTuple, isKeyValue, matchesQuery, normalizeStoredRow, normalizeStoredValue };\n", "import { findPhysicalIndex, rowKey } from \"./adapter.mjs\";\nimport { compareTuples, indexOrderTuple, isKeyValue, matchesQuery } from \"./values.mjs\";\n//#region src/database/verifyAdapter.ts\n/** What `verifyAdapter` throws when an adapter call breaks the adapter contract. */\nvar DatabaseAdapterContractError = class extends Error {\n\tname = \"DatabaseAdapterContractError\";\n};\nconst EMPTY = {\n\tgets: 0,\n\tkeys: 0,\n\tqueries: 0,\n\trows: 0\n};\nconst createReadMeter = () => {\n\tconst tables = /* @__PURE__ */ new Map();\n\tconst add = (table, count) => {\n\t\tconst current = tables.get(table) ?? EMPTY;\n\t\ttables.set(table, {\n\t\t\tgets: current.gets + (count.gets ?? 0),\n\t\t\tkeys: current.keys + (count.keys ?? 0),\n\t\t\tqueries: current.queries + (count.queries ?? 0),\n\t\t\trows: current.rows + (count.rows ?? 0)\n\t\t});\n\t};\n\treturn {\n\t\tadd,\n\t\tmeter: {\n\t\t\ttotal: () => [...tables.values()].reduce((sum, count) => ({\n\t\t\t\tgets: sum.gets + count.gets,\n\t\t\t\tkeys: sum.keys + count.keys,\n\t\t\t\tqueries: sum.queries + count.queries,\n\t\t\t\trows: sum.rows + count.rows\n\t\t\t}), EMPTY),\n\t\t\tbyTable: (table) => tables.get(table) ?? EMPTY,\n\t\t\treset: () => tables.clear()\n\t\t}\n\t};\n};\nconst fail = (message) => {\n\tthrow new DatabaseAdapterContractError(message);\n};\nconst sameKey = (left, right) => left.length === right.length && compareTuples(left, right) === 0;\nconst verifyRequest = (table, request) => {\n\tconst index = findPhysicalIndex(table, request.index);\n\tif (!Number.isSafeInteger(request.limit) || request.limit < 1 || request.limit > 500) fail(`query limit must be 1\u2013500.`);\n\tif (request.eq.length !== index.eq.length || !request.eq.every(isKeyValue)) fail(`query on ${table.name}.${index.name} must bind every eq column.`);\n\treturn index;\n};\nconst verifyRows = (table, request, rows) => {\n\tconst index = findPhysicalIndex(table, request.index);\n\tif (rows.length > request.limit) fail(`${table.name}.${index.name} returned more than ${request.limit} rows.`);\n\tlet previous;\n\tfor (const row of rows) {\n\t\tif (!matchesQuery(table, index, request, row)) fail(`${table.name}.${index.name} returned a row outside the request.`);\n\t\tconst tuple = indexOrderTuple(table, index, row);\n\t\tif (previous !== void 0) {\n\t\t\tconst order = compareTuples(previous, tuple);\n\t\t\tif (request.order === \"asc\" ? order >= 0 : order <= 0) fail(`${table.name}.${index.name} returned rows out of order.`);\n\t\t}\n\t\tprevious = tuple;\n\t}\n\treturn previous;\n};\nconst verifyWrite = (adapter, ops) => {\n\tif (ops.length === 0) fail(\"write needs at least one op.\");\n\tconst seen = /* @__PURE__ */ new Set();\n\tfor (const op of ops) {\n\t\tconst key = op.type === \"insert\" ? rowKey(op.table, op.row) : op.key;\n\t\tconst id = JSON.stringify([op.table.name, key]);\n\t\tif (seen.has(id)) fail(`write touches ${op.table.name} ${id} twice.`);\n\t\tseen.add(id);\n\t\tif (op.type === \"insert\" && typeof op.row[\"_v\"] !== \"number\") fail(`insert into ${op.table.name} must set _v.`);\n\t\tif (op.type === \"patch\" && Object.keys(op.set).some((column) => column === \"_v\" || op.table.key.includes(column))) fail(`patch of ${op.table.name} may not set key columns or _v.`);\n\t}\n\tif (!adapter.fits(ops)) fail(\"write does not fit in one atomic write.\");\n};\n/** Wraps an adapter to check the contract at its boundary and count reads. */\nconst verifyAdapter = (adapter, options = {}) => {\n\tconst { add, meter } = createReadMeter();\n\treturn {\n\t\t...adapter,\n\t\tid: adapter.id,\n\t\treads: meter,\n\t\tfits: (ops) => adapter.fits(ops),\n\t\tasync get(table, keys) {\n\t\t\tconst rows = await adapter.get(table, keys);\n\t\t\tadd(table.name, {\n\t\t\t\tgets: 1,\n\t\t\t\tkeys: keys.length\n\t\t\t});\n\t\t\tif (rows.length !== keys.length) fail(`${table.name} get returned ${rows.length} rows for ${keys.length} keys.`);\n\t\t\trows.forEach((row, position) => {\n\t\t\t\tif (row !== null && !sameKey(rowKey(table, row), keys[position])) fail(`${table.name} get returned a row for another key.`);\n\t\t\t});\n\t\t\treturn rows;\n\t\t},\n\t\tasync query(table, request) {\n\t\t\tconst index = verifyRequest(table, request);\n\t\t\tconst rows = await adapter.query(table, request);\n\t\t\tadd(table.name, {\n\t\t\t\tqueries: 1,\n\t\t\t\trows: rows.length\n\t\t\t});\n\t\t\tconst last = verifyRows(table, request, rows);\n\t\t\tif (options.probeShortPages && last !== void 0 && rows.length < request.limit) {\n\t\t\t\tconst bound = {\n\t\t\t\t\tvalues: last,\n\t\t\t\t\tinclusive: false\n\t\t\t\t};\n\t\t\t\tif ((await adapter.query(table, {\n\t\t\t\t\t...request,\n\t\t\t\t\tlimit: 1,\n\t\t\t\t\t...request.order === \"asc\" ? { lower: bound } : { upper: bound }\n\t\t\t\t})).length > 0) fail(`${table.name}.${index.name} returned a short page before the range ended.`);\n\t\t\t}\n\t\t\treturn rows;\n\t\t},\n\t\t...adapter.prune && { async prune(table, before, limit) {\n\t\t\tif (table.retention === void 0) fail(`${table.name} has no retention to prune by.`);\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1) fail(\"prune limit must be a positive integer.\");\n\t\t\tconst deleted = await adapter.prune(table, before, limit);\n\t\t\tif (!Number.isSafeInteger(deleted) || deleted < 0 || deleted > limit) fail(`${table.name} prune reported ${deleted} rows for ${limit}.`);\n\t\t\treturn deleted;\n\t\t} },\n\t\tasync write(ops) {\n\t\t\tverifyWrite(adapter, ops);\n\t\t\tconst result = await adapter.write(ops);\n\t\t\tif (!result.ok && \"failedOp\" in result) {\n\t\t\t\tif (!Number.isSafeInteger(result.failedOp) || result.failedOp < 0 || result.failedOp >= ops.length) fail(`write reported failedOp ${result.failedOp} for ${ops.length} ops.`);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n};\n//#endregion\nexport { DatabaseAdapterContractError, verifyAdapter };\n", "//#region src/engine/database/fence.ts\n/**\n* The settings rows migrations write, last, and the fence reads; retention\n* passes keep their lease here too. Tooling that creates the tables creates\n* this one with them: an ORM's schema generator, a provider's setup, and an\n* access policy that names the tables a server reads.\n*/\nconst SETTINGS_TABLE = {\n\tname: \"private_hot_updater_settings\",\n\tcolumns: [\n\t\t{\n\t\t\tname: \"key\",\n\t\t\ttype: \"string\",\n\t\t\tnullable: false,\n\t\t\tmaxLength: 255\n\t\t},\n\t\t{\n\t\t\tname: \"value\",\n\t\t\ttype: \"string\",\n\t\t\tnullable: false,\n\t\t\tmaxLength: 255\n\t\t},\n\t\t{\n\t\t\tname: \"_v\",\n\t\t\ttype: \"integer\",\n\t\t\tnullable: false,\n\t\t\tdefault: 0\n\t\t}\n\t],\n\tkey: [\"key\"],\n\tindexes: []\n};\n/** The engine's storage-layout generation; it changes only with a migration. */\nconst ENGINE_SCHEMA_KEY = \"schema.engine\";\nconst CORE_SCHEMA_KEY = \"schema.core\";\nconst stored = ({ key, expected, found }) => `\"${key}\" is ${found === null ? \"missing\" : `\"${found}\"`}; expected \"${expected}\"`;\nconst settingMessage = (adapterName, { key, expected, found }) => `Hot Updater schema setting \"${key}\" for ${adapterName} is ${found === null ? \"missing\" : `\"${found}\"`}; expected \"${expected}\". Run \\`hot-updater db migrate\\`.`;\n/** The plugin a `schema.<id>` setting belongs to; undefined for core's and the engine's. */\nconst pluginOf = ({ key }) => key.startsWith(\"schema.\") && key !== \"schema.engine\" && key !== CORE_SCHEMA_KEY ? key.slice(7) : void 0;\nconst listed = (items) => items.length < 2 ? items.join(\"\") : `${items.slice(0, -1).join(\", \")} and ${items.at(-1)}`;\n/** How to create plugins' tables when the fence was given no fix. */\nconst PLUGIN_TABLES_FIX = \"Run `hot-updater db migrate`. A managed server runs only its provider's plugins, and rerunning `hot-updater init --provider <provider>` applies the provider's migrations. Run `hot-updater db` commands in the server's project: they load the server file named on the command line, or src/hotUpdater.* or src/db.*, and don't read hot-updater.config.ts.\";\nconst pluginsMessage = (adapterName, plugins, settings, fix) => `The tables of ${plugins.length === 1 ? \"plugin\" : \"plugins\"} ${listed(plugins.map((id) => `\"${id}\"`))} are not migrated on ${adapterName}: schema ${settings.length === 1 ? \"setting\" : \"settings\"} ${settings.map(stored).join(\", and \")}. ${fix}`;\n/** The database needs `hot-updater db migrate`, or a new database; the handler answers 503. */\nvar HotUpdaterSchemaMigrationRequiredError = class extends Error {\n\tadapterName;\n\tcurrentVersion;\n\tsetting;\n\t/** Every setting the fence found missing or different; `setting` is the first. */\n\tsettings;\n\t/**\n\t* The ids of the plugins whose `schema.<id>` setting is among them: the\n\t* plugins whose tables a migration has yet to create or change.\n\t*/\n\tplugins;\n\tconstructor(adapterName, currentVersion, setting, options) {\n\t\tconst settings = options?.settings ?? (setting === void 0 ? [] : [setting]);\n\t\tconst plugins = settings.flatMap((mismatch) => pluginOf(mismatch) ?? []);\n\t\tsuper(setting === void 0 ? currentVersion === void 0 ? `Hot Updater database schema is not initialized for ${adapterName}. Run \\`hot-updater db migrate\\` before using this adapter.` : `Hot Updater v1 cannot migrate schema ${currentVersion} in place. Create a new empty database and run \\`hot-updater db migrate\\`.` : plugins.length > 0 && plugins.length === settings.length ? pluginsMessage(adapterName, plugins, settings, options?.fix ?? PLUGIN_TABLES_FIX) : settingMessage(adapterName, setting), options?.cause === void 0 ? void 0 : { cause: options.cause });\n\t\tthis.adapterName = adapterName;\n\t\tthis.currentVersion = currentVersion;\n\t\tthis.setting = setting;\n\t\tthis.name = \"HotUpdaterSchemaMigrationRequiredError\";\n\t\tthis.settings = settings;\n\t\tthis.plugins = plugins;\n\t}\n};\n/** Driver codes for a table or column the database lacks. */\nconst MISSING_SCHEMA_CODES = /* @__PURE__ */ new Set([\n\t\"42P01\",\n\t\"42703\",\n\t\"ER_NO_SUCH_TABLE\",\n\t\"ER_BAD_FIELD_ERROR\"\n]);\nconst MISSING_SCHEMA_MESSAGE = /no such (?:table|column)|(?:relation|column) .+ does not exist|table .+ doesn't exist|unknown column/iu;\n/**\n* Whether a read failed because a table or column is missing, so the\n* database needs migrations. ORMs may wrap the driver's error in `cause`.\n*/\nconst isMissingSchemaError = (error) => {\n\tfor (let depth = 0; error instanceof Object && depth < 8; depth += 1) {\n\t\tconst { code, message, cause } = error;\n\t\tif (MISSING_SCHEMA_CODES.has(String(code)) || typeof message === \"string\" && MISSING_SCHEMA_MESSAGE.test(message)) return true;\n\t\terror = cause;\n\t}\n\treturn false;\n};\nconst readSettings = (adapter, keys) => adapter.get(SETTINGS_TABLE, keys.map((key) => [key]));\n/**\n* Throws unless every expected setting is stored with its value: one batch\n* read. The error lists every setting missing or different; `fix` says how\n* to create the plugins' tables on this database.\n*/\nconst checkSchemaFence = async (adapter, adapterName, expected, fix) => {\n\tconst keys = Object.keys(expected);\n\tlet rows;\n\ttry {\n\t\trows = await readSettings(adapter, keys);\n\t} catch (cause) {\n\t\tif (!isMissingSchemaError(cause)) throw cause;\n\t\tthrow new HotUpdaterSchemaMigrationRequiredError(adapterName, void 0, {\n\t\t\tkey: ENGINE_SCHEMA_KEY,\n\t\t\texpected: \"1\",\n\t\t\tfound: null\n\t\t}, { cause });\n\t}\n\tconst settings = keys.flatMap((key, position) => {\n\t\tconst found = rows[position]?.value;\n\t\treturn found === expected[key] ? [] : [{\n\t\t\tkey,\n\t\t\texpected: expected[key],\n\t\t\tfound: typeof found === \"string\" ? found : null\n\t\t}];\n\t});\n\tconst [first] = settings;\n\tif (first !== void 0) throw new HotUpdaterSchemaMigrationRequiredError(adapterName, void 0, first, {\n\t\tsettings,\n\t\t...fix === void 0 ? {} : { fix }\n\t});\n};\n/** The database name a fenced adapter carries, so a server can fence its plugins' rows too. */\nconst FENCED = Symbol.for(\"@hot-updater/server/schema-fence\");\n/** The database name an adapter behind the schema fence reports under. */\nconst fencedName = (adapter) => adapter[FENCED];\n/**\n* The adapter behind the schema fence: a process's first read or write\n* checks the settings first. Success is kept; a failure is checked again on\n* the next call.\n*/\nconst withSchemaFence = (adapter, adapterName, expected, fix) => {\n\tlet ready;\n\tconst fence = () => {\n\t\tready ??= checkSchemaFence(adapter, adapterName, expected, fix).catch((error) => {\n\t\t\tready = void 0;\n\t\t\tthrow error;\n\t\t});\n\t\treturn ready;\n\t};\n\treturn {\n\t\t...adapter,\n\t\t[FENCED]: adapterName,\n\t\tget: (table, keys) => fence().then(() => adapter.get(table, keys)),\n\t\tquery: (table, request) => fence().then(() => adapter.query(table, request)),\n\t\twrite: (ops) => fence().then(() => adapter.write(ops)),\n\t\t...adapter.prune && { prune: (table, before, limit) => fence().then(() => adapter.prune(table, before, limit)) }\n\t};\n};\n//#endregion\nexport { ENGINE_SCHEMA_KEY, HotUpdaterSchemaMigrationRequiredError, SETTINGS_TABLE, checkSchemaFence, fencedName, isMissingSchemaError, readSettings, withSchemaFence };\n", "//#region src/engine/database/readMeter.ts\nconst METER = Symbol.for(\"@hot-updater/plugin-core/read-meter\");\nconst NO_READS = {\n\tgets: 0,\n\tkeys: 0,\n\tqueries: 0,\n\trows: 0\n};\n/** The meter `meterReads` gave `database`, if it did. */\nconst readMeterOf = (database) => typeof database === \"object\" && database !== null ? database[METER] : void 0;\n/**\n* `database` with read metering, for adapter cost analysis: pass it to\n* `createHotUpdater` or `createEngine`, then `measureReads` reports what a\n* call read at the adapter and at the engine. It works on any database on\n* the storage engine, a provider's included, and every engine on it reports\n* to the same meter.\n*/\nconst meterReads = (database) => {\n\tlet adapterReads = NO_READS;\n\tconst engines = /* @__PURE__ */ new Set();\n\tconst add = (count) => {\n\t\tadapterReads = {\n\t\t\tgets: adapterReads.gets + (count.gets ?? 0),\n\t\t\tkeys: adapterReads.keys + (count.keys ?? 0),\n\t\t\tqueries: adapterReads.queries + (count.queries ?? 0),\n\t\t\trows: adapterReads.rows + (count.rows ?? 0)\n\t\t};\n\t};\n\tconst meter = {\n\t\twrap: (adapter) => Object.assign(Object.create(adapter), {\n\t\t\tasync get(...args) {\n\t\t\t\tconst rows = await adapter.get(...args);\n\t\t\t\tadd({\n\t\t\t\t\tgets: 1,\n\t\t\t\t\tkeys: args[1].length\n\t\t\t\t});\n\t\t\t\treturn rows;\n\t\t\t},\n\t\t\tasync query(...args) {\n\t\t\t\tconst rows = await adapter.query(...args);\n\t\t\t\tadd({\n\t\t\t\t\tqueries: 1,\n\t\t\t\t\trows: rows.length\n\t\t\t\t});\n\t\t\t\treturn rows;\n\t\t\t}\n\t\t}),\n\t\tattach: (counter) => {\n\t\t\tengines.add(counter);\n\t\t}\n\t};\n\treturn {\n\t\t...database,\n\t\t[METER]: meter,\n\t\tasync measureReads(read) {\n\t\t\tadapterReads = NO_READS;\n\t\t\tfor (const engine of engines) engine.reset();\n\t\t\tconst result = await read();\n\t\t\tlet engine = {\n\t\t\t\tcalls: 0,\n\t\t\t\trows: 0\n\t\t\t};\n\t\t\tfor (const counter of engines) {\n\t\t\t\tconst total = counter.total();\n\t\t\t\tengine = {\n\t\t\t\t\tcalls: engine.calls + total.calls,\n\t\t\t\t\trows: engine.rows + total.rows\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult,\n\t\t\t\tadapter: adapterReads,\n\t\t\t\tengine\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { meterReads, readMeterOf };\n", "import { SETTINGS_TABLE, readSettings } from \"../database/fence.mjs\";\n//#region src/engine/db/schemaSettings.ts\nconst storedSettings = async (adapter, keys) => {\n\tconst rows = await readSettings(adapter, keys);\n\treturn new Map(keys.map((key, position) => [key, rows[position] ?? null]));\n};\n/** Writes the settings rows after every table exists. */\nconst writeSchemaSettings = async (adapter, adapterName, settings) => {\n\tconst stored = await storedSettings(adapter, Object.keys(settings));\n\tconst ops = Object.entries(settings).flatMap(([key, value]) => {\n\t\tconst row = stored.get(key);\n\t\tif (row === null || row === void 0) return [{\n\t\t\ttype: \"insert\",\n\t\t\ttable: SETTINGS_TABLE,\n\t\t\trow: {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\t_v: 0\n\t\t\t}\n\t\t}];\n\t\tif (row.value === value) return [];\n\t\treturn [{\n\t\t\ttype: \"patch\",\n\t\t\ttable: SETTINGS_TABLE,\n\t\t\tkey: [key],\n\t\t\tset: { value },\n\t\t\tguard: { v: Number(row._v) },\n\t\t\tprevious: row\n\t\t}];\n\t});\n\tif (ops.length === 0) return;\n\tif (!(await adapter.write(ops)).ok) throw new Error(`${adapterName}: the schema settings changed during the migration; run it again.`);\n};\n/** Creates or updates every table, then writes the settings rows last. */\nconst migrateSchema = async (adapter, adapterName, tables, settings) => {\n\tif (adapter.migrations === void 0) throw new Error(`${adapterName} creates its tables with its own tooling; write only the settings rows.`);\n\tawait adapter.migrations.apply([...tables, SETTINGS_TABLE]);\n\tawait writeSchemaSettings(adapter, adapterName, settings);\n};\n//#endregion\nexport { migrateSchema, writeSchemaSettings };\n", "import { DatabaseSchemaError, findPhysicalColumn, indexOrderColumns } from \"../../../database/adapter.mjs\";\n//#region src/engine/database/sql/sqlSchema.ts\n/**\n* Quotes an identifier: backticks on MySQL, double quotes elsewhere. An ORM\n* schema generator, or an executor that issues statements of its own, quotes\n* names as the SQL core does with it, as the Prisma adapter's do.\n*/\nconst quoteSql = (dialect, name) => dialect === \"mysql\" ? `\\`${name.replaceAll(\"`\", \"``\")}\\`` : `\"${name.replaceAll(\"\\\"\", \"\\\"\\\"\")}\"`;\nconst isMultiIndex = (table, index) => index.eq.some((column) => findPhysicalColumn(table, column).multi);\n/** Keeps an identifier within PostgreSQL's 63 and MySQL's 64 characters. */\nconst shortSqlName = (name) => {\n\tif (name.length <= 60) return name;\n\tlet hash = 2166136261;\n\tfor (const char of name) hash = Math.imul(hash ^ char.charCodeAt(0), 16777619) >>> 0;\n\treturn `${name.slice(0, 51)}_${hash.toString(36)}`;\n};\n/** The column type; `entry` types one value of a multi-valued column in its index table. */\nconst columnType = (dialect, column, indexed, entry = false) => {\n\tif (column.multi && !entry || column.type === \"json\") return {\n\t\tpostgresql: \"jsonb\",\n\t\tmysql: \"json\",\n\t\tsqlite: \"TEXT\"\n\t}[dialect];\n\tif (column.type === \"string\") {\n\t\tconst length = column.maxLength ?? (indexed ? 255 : void 0);\n\t\tif (dialect === \"sqlite\") return \"TEXT\";\n\t\tif (dialect === \"postgresql\") return `${column.maxLength ? `varchar(${column.maxLength})` : \"text\"} COLLATE \"C\"`;\n\t\tconst charset = column.ascii ? \"ascii COLLATE ascii_bin\" : \"utf8mb4 COLLATE utf8mb4_0900_bin\";\n\t\treturn `${length ? `varchar(${length})` : \"longtext\"} CHARACTER SET ${charset}`;\n\t}\n\tif (column.type === \"integer\") return dialect === \"sqlite\" ? \"INTEGER\" : \"bigint\";\n\tif (column.type === \"number\") return {\n\t\tpostgresql: \"double precision\",\n\t\tmysql: \"double\",\n\t\tsqlite: \"REAL\"\n\t}[dialect];\n\treturn dialect === \"sqlite\" ? \"INTEGER\" : \"boolean\";\n};\n/** InnoDB's limit on the bytes of one key or index. */\nconst MYSQL_KEY_BYTES = 3072;\n/** Refuses a MySQL key or index over InnoDB's limit before any DDL runs. */\nconst checkMysqlKey = (table, name, columns) => {\n\tconst bytes = columns.reduce((sum, column) => {\n\t\tconst { type, maxLength, ascii } = findPhysicalColumn(table, column);\n\t\tif (type === \"string\") return sum + (maxLength ?? 255) * (ascii ? 1 : 4);\n\t\treturn sum + (type === \"boolean\" ? 1 : 8);\n\t}, 0);\n\tif (bytes > MYSQL_KEY_BYTES) throw new DatabaseSchemaError(`${table.name} ${name} needs ${bytes} bytes on MySQL, over its ${MYSQL_KEY_BYTES}; shorten its strings or mark ASCII ones ascii.`);\n};\n/**\n* Each table as the DDL creates it, for the DDL below and for ORM schema\n* generators, such as the Drizzle and Prisma adapters': binary collation, one index per declared index, and an index\n* table `<table>__<index>` for each index over a multi-valued field, keyed by\n* every column it holds.\n*/\nconst sqlTableShapes = (dialect, tables, tablePrefix = \"\") => tables.map((table) => {\n\tconst name = tablePrefix + table.name;\n\tconst indexed = /* @__PURE__ */ new Set([...table.key, ...table.indexes.flatMap(({ eq, sort }) => [...eq, ...sort])]);\n\tif (dialect === \"mysql\") checkMysqlKey(table, \"key\", table.key);\n\tconst indexes = table.indexes.flatMap((index) => {\n\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\tif (dialect === \"mysql\") checkMysqlKey(table, `index ${index.name}`, columns);\n\t\tif (isMultiIndex(table, index)) {\n\t\t\tconst entries = columns.map((column) => ({\n\t\t\t\tname: column,\n\t\t\t\ttype: columnType(dialect, findPhysicalColumn(table, column), true, true),\n\t\t\t\tnotNull: true\n\t\t\t}));\n\t\t\treturn [{\n\t\t\t\tkind: \"table\",\n\t\t\t\ttable: {\n\t\t\t\t\tname: `${name}__${index.name}`,\n\t\t\t\t\tcolumns: entries,\n\t\t\t\t\tkey: columns,\n\t\t\t\t\tindexes: []\n\t\t\t\t}\n\t\t\t}];\n\t\t}\n\t\tif (!index.unique && columns.join() === table.key.join()) return [];\n\t\treturn [{\n\t\t\tkind: \"index\",\n\t\t\tname: shortSqlName(`${name}_${index.name}`),\n\t\t\tunique: index.unique === true,\n\t\t\tcolumns: index.unique ? index.eq : columns\n\t\t}];\n\t});\n\tconst retention = table.retention && retentionOrder(table);\n\tif (retention && !retention.indexed) indexes.push({\n\t\tkind: \"index\",\n\t\tname: shortSqlName(`${name}__retention`),\n\t\tunique: false,\n\t\tcolumns: retention.columns\n\t});\n\treturn {\n\t\tname,\n\t\tcolumns: table.columns.map((column) => ({\n\t\t\tname: column.name,\n\t\t\ttype: columnType(dialect, column, indexed.has(column.name)),\n\t\t\tnotNull: !column.nullable,\n\t\t\t...column.default === void 0 ? {} : { default: column.default }\n\t\t})),\n\t\tkey: table.key,\n\t\tindexes\n\t};\n});\n/** DDL for the tables' shapes: each table, then its indexes and index tables. */\nconst createTableStatements = (dialect, tables, tablePrefix = \"\") => {\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst list = (columns) => columns.map(quote).join(\", \");\n\tconst render = (shape) => {\n\t\tconst definitions = shape.columns.map((column) => `${quote(column.name)} ${column.type}${column.notNull ? \" NOT NULL\" : \"\"}${column.default === void 0 ? \"\" : ` DEFAULT ${column.default}`}`);\n\t\tdefinitions.push(`PRIMARY KEY (${list(shape.key)})`);\n\t\tconst after = [];\n\t\tfor (const index of shape.indexes) if (index.kind === \"table\") after.push(...render(index.table));\n\t\telse if (dialect === \"mysql\") definitions.push(`${index.unique ? \"UNIQUE \" : \"\"}INDEX ${quote(index.name)} (${list(index.columns)})`);\n\t\telse after.push(`CREATE ${index.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${quote(index.name)} ON ${quote(shape.name)} (${list(index.columns)})`);\n\t\treturn [`CREATE TABLE IF NOT EXISTS ${quote(shape.name)} (${definitions.join(\", \")})`, ...after];\n\t};\n\treturn sqlTableShapes(dialect, tables, tablePrefix).flatMap(render);\n};\n/**\n* The order a prune walks a table's expired rows in, which ends with the\n* key so it is total: the columns of the first index that leads with the\n* retention column, or the key when it does, or else the column and the\n* key, which then need an index of their own (`indexed` false).\n*/\nconst retentionOrder = (table) => {\n\tconst { column } = table.retention;\n\tfor (const index of table.indexes) {\n\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\tif (!index.unique && !isMultiIndex(table, index) && columns[0] === column) return {\n\t\t\tcolumns,\n\t\t\tindexed: true\n\t\t};\n\t}\n\tif (table.key[0] === column) return {\n\t\tcolumns: table.key,\n\t\tindexed: true\n\t};\n\treturn {\n\t\tcolumns: [column, ...table.key.filter((field) => field !== column)],\n\t\tindexed: false\n\t};\n};\n/**\n* The statements that delete up to `limit` expired rows of a table with\n* retention, oldest first in {@link retentionOrder}: its multi-valued index\n* entries, then the rows, which a concurrent write that moved the retention\n* column past `before` keeps. `before` renders the bound each time it\n* appears. MySQL deletes with ORDER BY and LIMIT. Elsewhere the cutoff is\n* the last of the `limit` oldest expired rows in that order, a row value\n* the index ranges over, and the shapes pass Supabase's apply RPC: no IN, no\n* AS, aliases `i` and `b`.\n*/\nconst pruneStatements = (dialect, table, tablePrefix, limit) => {\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst name = quote(`${tablePrefix}${table.name}`);\n\tconst at = quote(table.retention.column);\n\tconst order = retentionOrder(table).columns.map(quote);\n\tconst list = (alias, direction = \"\") => order.map((column) => `${alias}.${column}${direction}`).join(\", \");\n\tconst oldest = (before) => `SELECT ${list(\"i\")} FROM ${name} i WHERE i.${at} <= ${before()} ORDER BY ${list(\"i\", \" ASC\")} LIMIT ${limit}`;\n\tconst doomed = (alias, before) => `${alias}.${at} <= ${before()} AND (${list(alias)}) <= (SELECT ${list(\"b\")} FROM (${oldest(before)}) b ORDER BY ${list(\"b\", \" DESC\")} LIMIT 1)`;\n\tconst entries = table.indexes.filter((index) => isMultiIndex(table, index)).map((index) => quote(`${tablePrefix}${table.name}__${index.name}`));\n\tconst keyOf = (left, right) => table.key.map((column) => `${left}.${quote(column)} = ${right}.${quote(column)}`).join(\" AND \");\n\tif (dialect === \"mysql\") return [...entries.map((index) => (before) => `DELETE e FROM ${index} e JOIN (${oldest(before)}) d ON ${keyOf(\"e\", \"d\")}`), (before) => `DELETE FROM ${name} WHERE ${at} <= ${before()} ORDER BY ${order.join(\", \")} LIMIT ${limit}`];\n\treturn [...entries.map((index) => (before) => `DELETE FROM ${index} WHERE EXISTS (SELECT * FROM ${name} b WHERE ${keyOf(\"b\", index)} AND ${doomed(\"b\", before)})`), (before) => `DELETE FROM ${name} WHERE ${doomed(name, before)}`];\n};\n//#endregion\nexport { createTableStatements, isMultiIndex, pruneStatements, quoteSql, retentionOrder, shortSqlName, sqlTableShapes };\n", "import { defineAggregate, defineTable } from \"../../serverPlugin/schema.mjs\";\n//#region src/engine/core/schema.ts\n/** A channel's id is `channel:` and its name's channel key, so ids share channel_key's bound. */\nconst CHANNEL_ID = {\n\ttype: \"string\",\n\tmaxLength: 1408,\n\tascii: true\n};\n/** Core's schema version: the `schema.core` settings row. */\nconst HOT_UPDATER_SCHEMA_VERSION = \"1.0.0\";\nconst coreSchema = {\n\tbundles: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tgit_commit_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tmetadata: { type: \"json\" },\n\t\tmanifest_storage_uri: { type: \"string\" },\n\t\tmanifest_file_hash: { type: \"string\" },\n\t\tasset_base_storage_uri: { type: \"string\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tbyPlatform: {\n\t\t\t\teq: [\"platform\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tall: {\n\t\t\t\teq: [],\n\t\t\t\tsort: [\"id\"]\n\t\t\t}\n\t\t}\n\t}),\n\tbundle_patches: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255\n\t\t},\n\t\tbundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"cascade\"\n\t\t\t}\n\t\t},\n\t\tbase_bundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"cascade\"\n\t\t\t}\n\t\t},\n\t\tbase_file_hash: { type: \"string\" },\n\t\tpatch_file_hash: { type: \"string\" },\n\t\tpatch_storage_uri: { type: \"string\" },\n\t\tbyte_size: { type: \"integer\" },\n\t\torder_index: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tpair: {\n\t\t\t\teq: [\"bundle_id\", \"base_bundle_id\"],\n\t\t\t\tsort: [],\n\t\t\t\tunique: true\n\t\t\t},\n\t\t\tbyBundle: {\n\t\t\t\teq: [\"bundle_id\"],\n\t\t\t\tsort: [\"order_index\"],\n\t\t\t\troot: { model: \"bundles\" }\n\t\t\t},\n\t\t\tbyBase: {\n\t\t\t\teq: [\"base_bundle_id\"],\n\t\t\t\tsort: [\"bundle_id\"]\n\t\t\t}\n\t\t}\n\t}),\n\treleases: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36\n\t\t},\n\t\trevision: { type: \"integer\" },\n\t\tscope_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 2048,\n\t\t\tascii: true\n\t\t},\n\t\tchannel_id: {\n\t\t\t...CHANNEL_ID,\n\t\t\treferences: {\n\t\t\t\tmodel: \"channels\",\n\t\t\t\tonDelete: \"restrict\"\n\t\t\t}\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tkind: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tbundle_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\trequired: false,\n\t\t\treferences: {\n\t\t\t\tmodel: \"bundles\",\n\t\t\t\tonDelete: \"restrict\"\n\t\t\t}\n\t\t},\n\t\tstrategy: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\ttarget_app_version: {\n\t\t\ttype: \"string\",\n\t\t\trequired: false\n\t\t},\n\t\tfingerprint_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tenabled: { type: \"boolean\" },\n\t\tshould_force_update: { type: \"boolean\" },\n\t\tmessage: {\n\t\t\ttype: \"string\",\n\t\t\trequired: false\n\t\t},\n\t\trollout_cohort_count: { type: \"integer\" },\n\t\ttarget_cohorts: { type: \"json\" },\n\t\toperation: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tsource_release_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 36,\n\t\t\trequired: false,\n\t\t\treferences: {\n\t\t\t\tmodel: \"releases\",\n\t\t\t\tonDelete: \"none\"\n\t\t\t}\n\t\t},\n\t\tcreated_at_ms: { type: \"integer\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: {\n\t\t\tbyScope: {\n\t\t\t\teq: [\"scope_key\"],\n\t\t\t\tsort: [\"id\"],\n\t\t\t\troot: { model: \"release_catalogs\" }\n\t\t\t},\n\t\t\tbyScopeEnabled: {\n\t\t\t\teq: [\"scope_key\", \"enabled\"],\n\t\t\t\tsort: [\"id\"],\n\t\t\t\troot: { model: \"release_catalogs\" }\n\t\t\t},\n\t\t\tbyChannelPlatform: {\n\t\t\t\teq: [\"channel_id\", \"platform\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tbyChannelPlatformEnabled: {\n\t\t\t\teq: [\n\t\t\t\t\t\"channel_id\",\n\t\t\t\t\t\"platform\",\n\t\t\t\t\t\"enabled\"\n\t\t\t\t],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tbyBundle: {\n\t\t\t\teq: [\"bundle_id\"],\n\t\t\t\tsort: [\"id\"]\n\t\t\t},\n\t\t\tall: {\n\t\t\t\teq: [],\n\t\t\t\tsort: [\"id\"]\n\t\t\t}\n\t\t}\n\t}),\n\trelease_catalogs: defineTable({\n\t\tscope_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 2048,\n\t\t\tascii: true\n\t\t},\n\t\tcatalog_id: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255\n\t\t},\n\t\tstrategy: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tchannel_id: {\n\t\t\t...CHANNEL_ID,\n\t\t\treferences: {\n\t\t\t\tmodel: \"channels\",\n\t\t\t\tonDelete: \"none\"\n\t\t\t}\n\t\t},\n\t\tchannel_key: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 1400,\n\t\t\tascii: true\n\t\t},\n\t\tplatform: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tfingerprint_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\trequired: false\n\t\t},\n\t\tgeneration: { type: \"integer\" },\n\t\tpayload: { type: \"string\" },\n\t\tcatalog_hash: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 71\n\t\t},\n\t\tbyte_size: { type: \"integer\" },\n\t\tis_tombstone: { type: \"boolean\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"scope_key\"],\n\t\tindexes: { all: {\n\t\t\teq: [],\n\t\t\tsort: [\"scope_key\"]\n\t\t} }\n\t}),\n\tchannels: defineTable({\n\t\tid: CHANNEL_ID,\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 255,\n\t\t\tunique: true\n\t\t}\n\t}, {\n\t\tkey: [\"id\"],\n\t\tindexes: { all: {\n\t\t\teq: [],\n\t\t\tsort: [\"name\"]\n\t\t} }\n\t}),\n\tbundle_totals: defineAggregate({ platform_key: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t} }, {\n\t\tkey: [\"platform_key\"],\n\t\tcounters: [\"bundles\"],\n\t\tindexes: { byPlatform: {\n\t\t\teq: [\"platform_key\"],\n\t\t\tsort: []\n\t\t} }\n\t})\n};\n/** Core's module: always installed, never a plugin. */\nconst coreModule = {\n\tid: \"core\",\n\tschema: coreSchema\n};\n//#endregion\nexport { HOT_UPDATER_SCHEMA_VERSION, coreModule, coreSchema };\n", "//#region src/engine/db/fixedMigratorShared.ts\nconst getEmptyMigrationResult = () => ({\n\toperations: [],\n\texecute: async () => {},\n\tgetSQL: () => \"\"\n});\n//#endregion\nexport { getEmptyMigrationResult };\n", "import { HOT_UPDATER_SCHEMA_VERSION } from \"../core/schema.mjs\";\nimport { HotUpdaterSchemaMigrationRequiredError, SETTINGS_TABLE, isMissingSchemaError } from \"../database/fence.mjs\";\nimport { getEmptyMigrationResult } from \"./fixedMigratorShared.mjs\";\nimport { quoteSql } from \"../database/sql/sqlSchema.mjs\";\nimport { settingsStatements } from \"./engineSql.mjs\";\n//#region src/engine/db/settingsMigrator.ts\n/**\n* Every settings row by key and value alone, so a v0 layout reads too; null\n* when the settings table is missing.\n*/\nconst readStoredSettings = async (executor, tablePrefix = \"\") => {\n\tconst quote = (name) => quoteSql(executor.dialect, name);\n\ttry {\n\t\tconst { rows } = await executor.execute({\n\t\t\tsql: `SELECT ${quote(\"key\")}, ${quote(\"value\")} FROM ${quote(tablePrefix + SETTINGS_TABLE.name)}`,\n\t\t\tparams: []\n\t\t});\n\t\treturn new Map(rows.map((row) => [String(row.key), row.value]));\n\t} catch (error) {\n\t\tif (!isMissingSchemaError(error)) throw error;\n\t\treturn null;\n\t}\n};\n/** `schema.core`, or a v0 database's `version`. */\nconst storedSchemaVersion = (stored) => {\n\tconst version = stored?.get(\"schema.core\") ?? stored?.get(\"version\");\n\treturn typeof version === \"string\" ? version : void 0;\n};\n/**\n* A v0 database, whose settings hold `version` and no `schema.engine`, is\n* recreated, never converted.\n*/\nconst refuseV0Database = (adapterName, stored) => {\n\tconst version = stored.get(\"version\");\n\tif (typeof version !== \"string\" || stored.has(\"schema.engine\")) return;\n\tthrow new HotUpdaterSchemaMigrationRequiredError(adapterName, version);\n};\n/**\n* `hot-updater db migrate` for an ORM that applies the DDL itself (Drizzle,\n* Prisma): it sets what the ORM cannot declare, writes the settings rows, and\n* refuses a v0 database. The `createMigrator` of an adapter whose ORM\n* creates the tables returns it, as the Drizzle and Prisma adapters' do.\n*/\nconst createSettingsMigrator = (options) => {\n\tconst read = () => readStoredSettings(options.executor);\n\tconst getVersion = async () => storedSchemaVersion(await read());\n\tconst makeResult = async (migrate = {}) => {\n\t\tconst stored = await read();\n\t\tif (stored === null) throw new Error(`${options.adapterName}: the Hot Updater tables are missing. Run \\`hot-updater db generate\\`, apply the schema with ${options.applyTables}, then migrate again.`);\n\t\trefuseV0Database(options.adapterName, stored);\n\t\tif (migrate.updateSettings === false || Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();\n\t\tconst fixups = options.fixups?.statements ?? [];\n\t\tconst statements = [...fixups, ...settingsStatements(options.executor.dialect, options.settings)];\n\t\treturn {\n\t\t\toperations: [...fixups.length === 0 ? [] : [{\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: options.fixups.description\n\t\t\t}], {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: `Write the schema settings: ${Object.keys(options.settings).join(\", \")}`\n\t\t\t}],\n\t\t\tgetSQL: () => statements.map((statement) => `${statement};`).join(\"\\n\\n\"),\n\t\t\texecute: async () => {\n\t\t\t\tfor (const sql of statements) await options.executor.execute({\n\t\t\t\t\tsql,\n\t\t\t\t\tparams: []\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t};\n\treturn {\n\t\tgetVersion,\n\t\tgetNameVariants: async () => void 0,\n\t\tnext: async () => await getVersion() === \"1.0.0\" ? void 0 : { version: HOT_UPDATER_SCHEMA_VERSION },\n\t\tprevious: async () => void 0,\n\t\tup: makeResult,\n\t\tdown: async () => {\n\t\t\tthrow new Error(\"No previous schema to migrate to.\");\n\t\t},\n\t\tmigrateTo: async (version, migrate) => {\n\t\t\tif (version !== \"1.0.0\") throw new Error(`Invalid version ${version}`);\n\t\t\treturn makeResult(migrate);\n\t\t},\n\t\tmigrateToLatest: makeResult\n\t};\n};\n//#endregion\nexport { createSettingsMigrator, readStoredSettings, refuseV0Database, storedSchemaVersion };\n", "import { DatabaseCursorError } from \"../../serverPlugin/errors.mjs\";\nimport { isKeyValue } from \"../../database/values.mjs\";\n//#region src/engine/database/cursor.ts\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\nconst toBase64Url = (text) => {\n\tlet binary = \"\";\n\tfor (const byte of encoder.encode(text)) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst fromBase64Url = (value) => {\n\tconst binary = atob(value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\"));\n\treturn decoder.decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));\n};\n/** A stable 32-bit FNV-1a hash of the text's UTF-8 bytes. */\nconst fnv1a = (text) => {\n\tlet hash = 2166136261;\n\tfor (const byte of encoder.encode(text)) hash = Math.imul(hash ^ byte, 16777619) >>> 0;\n\treturn hash;\n};\n/** A hash of the request's identity; a cursor only resumes the same read. */\nconst cursorScope = (parts) => fnv1a(JSON.stringify(parts)).toString(36);\nconst encodeCursor = (scope, after) => toBase64Url(JSON.stringify([scope, after]));\n/** The order tuple a cursor resumes after; rejects a cursor from another read. */\nconst decodeCursor = (scope, cursor) => {\n\tlet decoded;\n\ttry {\n\t\tdecoded = JSON.parse(fromBase64Url(cursor));\n\t} catch {\n\t\tdecoded = void 0;\n\t}\n\tconst [from, after] = Array.isArray(decoded) ? decoded : [];\n\tif (typeof from !== \"string\" || !Array.isArray(after) || !after.every(isKeyValue)) throw new DatabaseCursorError(\"The cursor is malformed.\");\n\tif (from !== scope) throw new DatabaseCursorError(\"The cursor belongs to a read with another model, index, filter, order, or range.\");\n\treturn after;\n};\n//#endregion\nexport { DatabaseCursorError, cursorScope, decodeCursor, encodeCursor, fnv1a };\n", "import { DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport { mergeDistinct } from \"../../database/distinct.mjs\";\nimport \"../../database/adapter.mjs\";\nimport { isKeyValue } from \"../../database/values.mjs\";\nimport { fnv1a } from \"./cursor.mjs\";\n//#region src/engine/database/engineAggregates.ts\nconst definitionOf = (model) => model.definition;\n/** Every change keyed by one value lands on one shard. */\nconst shardOf = (value, shards) => fnv1a(value) % shards;\n/** Merges one `tx.aggregate` call into its shard row's pending changes. */\nconst recordAggregate = (changes, model, identity, values, shardBy) => {\n\tconst { key: fields, counters, gauges, distinct, shards } = definitionOf(model);\n\tconst fail = (message) => new DatabaseTransactionError(`${model.table.name}: ${message}`);\n\tif (Object.keys(identity).length !== fields.length || !fields.every((name) => isKeyValue(identity[name]))) throw fail(`aggregate takes exactly its identity fields: ${fields.join(\", \")}.`);\n\tif (shardBy === void 0 && shards > 1 && gauges.some((gauge) => gauge in values)) throw fail(\"gauges of a sharded aggregate need shardBy.\");\n\tconst shard = shardBy === void 0 ? Math.floor(Math.random() * shards) : shardOf(shardBy, shards);\n\tconst key = [...fields.map((name) => identity[name]), shard];\n\tconst id = JSON.stringify([model.table.name, key]);\n\tconst change = changes.get(id) ?? {\n\t\tmodel,\n\t\tkey,\n\t\tdeltas: {},\n\t\tsketches: {}\n\t};\n\tchanges.set(id, change);\n\tfor (const [metric, value] of Object.entries(values)) if (distinct.includes(metric) && typeof value === \"string\") change.sketches[metric] = mergeDistinct([change.sketches[metric], value]);\n\telse if ((counters.includes(metric) || gauges.includes(metric)) && Number.isSafeInteger(value)) change.deltas[metric] = (change.deltas[metric] ?? 0) + Number(value);\n\telse throw fail(`${metric} is not a counter, gauge, or sketch of this aggregate.`);\n};\n/** A shard row before its first change: every metric zero or empty. */\nconst blank = (model, key) => {\n\tconst { counters, gauges, distinct } = definitionOf(model);\n\treturn Object.fromEntries([\n\t\t...model.table.key.map((column, position) => [column, key[position]]),\n\t\t...[...counters, ...gauges].map((name) => [name, 0]),\n\t\t...distinct.map((name) => [name, null]),\n\t\t[\"_v\", 0]\n\t]);\n};\n/**\n* A gauge computed below zero. Deltas from a row another writer has since\n* moved do this, so the transaction reruns; it is thrown only when it lasts.\n*/\nvar NegativeGaugeError = class extends DatabaseTransactionError {};\n/** The guarded write that merges `change` into `current`: insert, patch, or delete at zero. */\nconst rewrite = ({ model, key, deltas, sketches }, current) => {\n\tconst { table } = model;\n\tconst { counters, gauges, distinct } = definitionOf(model);\n\tconst base = current ?? blank(model, key);\n\tconst set = {};\n\tfor (const [metric, delta] of Object.entries(deltas)) set[metric] = Number(base[metric] ?? 0) + delta;\n\tfor (const [metric, sketch] of Object.entries(sketches)) set[metric] = mergeDistinct([base[metric], sketch]);\n\tif (current && Object.entries(set).every(([metric, value]) => current[metric] === value)) return;\n\tconst row = {\n\t\t...base,\n\t\t...set\n\t};\n\tif (gauges.some((gauge) => Number(row[gauge]) < 0)) {\n\t\tif (current === null && table.retention) return void 0;\n\t\tthrow new NegativeGaugeError(`${table.name}: a gauge went below 0.`);\n\t}\n\tconst zero = distinct.length === 0 && [...counters, ...gauges].every((metric) => Number(row[metric]) === 0);\n\tif (current === null) return zero ? void 0 : {\n\t\ttype: \"insert\",\n\t\ttable,\n\t\trow\n\t};\n\tconst guard = { v: Number(current[\"_v\"]) };\n\treturn zero ? {\n\t\ttype: \"delete\",\n\t\ttable,\n\t\tkey,\n\t\tguard,\n\t\tprevious: current\n\t} : {\n\t\ttype: \"patch\",\n\t\ttable,\n\t\tkey,\n\t\tset,\n\t\tguard,\n\t\tprevious: current\n\t};\n};\n/**\n* Counter-only rows become blind increments that create the row when it is\n* missing. Rows with gauges or sketches are read in one parallel batch per\n* table, merged, and written back under a guard, so a conflict resends only\n* them.\n*/\nconst compileAggregates = async (adapter, changes) => {\n\tconst ops = [];\n\tconst merged = /* @__PURE__ */ new Map();\n\tfor (const change of changes) {\n\t\tconst { model, key, deltas, sketches } = change;\n\t\tif (Object.keys(sketches).length > 0 || definitionOf(model).gauges.some((gauge) => (deltas[gauge] ?? 0) !== 0)) merged.set(model, [...merged.get(model) ?? [], change]);\n\t\telse if (Object.values(deltas).some((delta) => delta !== 0)) {\n\t\t\tconst { table } = model;\n\t\t\tconst init = blank(model, key);\n\t\t\tops.push({\n\t\t\t\ttype: \"increment\",\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tby: deltas,\n\t\t\t\tinit\n\t\t\t});\n\t\t}\n\t}\n\tconst groups = [...merged.values()];\n\tconst current = await Promise.all(groups.map((group) => adapter.get(group[0].model.table, group.map(({ key }) => key))));\n\tgroups.forEach((group, index) => group.forEach((change, position) => {\n\t\tconst op = rewrite(change, current[index][position] ?? null);\n\t\tif (op !== void 0) ops.push(op);\n\t}));\n\treturn ops;\n};\n//#endregion\nexport { NegativeGaugeError, compileAggregates, recordAggregate, shardOf };\n", "import { defineTable } from \"../../serverPlugin/schema.mjs\";\nimport { DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport \"../../database/adapter.mjs\";\nimport { compareUtf8 } from \"../../database/values.mjs\";\nimport { recordAggregate } from \"./engineAggregates.mjs\";\n//#region src/engine/database/aggregateBatching.ts\n/** Log rows spread over 8 tables, each its own DynamoDB partition. */\nconst LOG_TABLES = [\n\t0,\n\t1,\n\t2,\n\t3,\n\t4,\n\t5,\n\t6,\n\t7\n].map((at) => `aggregate_log_${at}`);\nconst LEASE_TABLE = \"aggregate_lease\";\nconst LEASE = { id: \"compaction\" };\n/** How long a compaction holds the lease before another process may take it. */\nconst LEASE_MS = 3e4;\n/**\n* Default windows: log mode compacts every 60 seconds, since reads compact\n* first; memory mode flushes every 15, since its window is what a crash\n* loses.\n*/\nconst WINDOW_MS = {\n\tlog: 6e4,\n\tmemory: 15e3\n};\n/** Log rows a compaction reads from each log table for one group. */\nconst LOG_PAGE = 200;\n/**\n* Groups one compaction applies: after a commit, so the request that runs\n* it waits for one group; before a read; and on flush.\n*/\nconst GROUPS = {\n\tcommit: 1,\n\tread: 8,\n\tflush: 256\n};\n/** Tries per write after a conflict or a transient error. */\nconst ATTEMPTS = 5;\n/** Aggregate rows a memory buffer holds before a commit waits for a flush. */\nconst MAX_BUFFERED = 1e4;\nconst log = defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\t/** One committed transaction's changes, one entry per aggregate row. */\n\tchanges: { type: \"string\" }\n}, {\n\tkey: [\"id\"],\n\tindexes: { oldest: {\n\t\teq: [],\n\t\tsort: [\"id\"]\n\t} }\n});\n/**\n* Held by `holder` until `until`; the next compaction is due at `next`.\n* `applied` lists the log rows a compaction has applied and not yet deleted,\n* as `[log table's index, id]` pairs, so no compaction applies them again.\n*/\nconst lease = defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tholder: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tuntil: { type: \"integer\" },\n\tnext: { type: \"integer\" },\n\tapplied: { type: \"string\" }\n}, { key: [\"id\"] });\n/** The log and lease tables; an engine that batches has them in its schema. */\nconst aggregateBatchingModule = {\n\tid: \"aggregateBatching\",\n\tschema: {\n\t\t...Object.fromEntries(LOG_TABLES.map((table) => [table, log])),\n\t\t[LEASE_TABLE]: lease\n\t}\n};\nconst shapeOf = (model) => model.definition;\nconst isBatched = (model) => model?.definition.kind === \"aggregate\" && shapeOf(model).batched === true;\nconst valuesOf = ({ deltas, sketches }) => ({\n\t...deltas,\n\t...sketches\n});\n/**\n* Merges `values` into the change for `key`'s identity as `tx.aggregate`\n* does: deltas add up and sketches merge. One constant `shardBy` keys each\n* identity to one entry; the write picks the shard.\n*/\nconst merge = (into, model, key, values) => recordAggregate(into, model, Object.fromEntries(shapeOf(model).key.map((field, at) => [field, key[at]])), values, \"\");\nconst mergeAll = (into, changes) => {\n\tfor (const change of changes) merge(into, change.model, change.key, valuesOf(change));\n\treturn into;\n};\n/** A row's metrics as values to merge: counters, gauges, and the sketches it has. */\nconst metricsOf = (model, row) => {\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\treturn Object.fromEntries([...[...counters, ...gauges].map((name) => [name, Number(row[name] ?? 0)]), ...distinct.flatMap((name) => row[name] === null || row[name] === void 0 ? [] : [[name, row[name]]])]);\n};\n/** A shard row before its first change: every metric zero or empty. */\nconst blank = (model, key) => {\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\treturn Object.fromEntries([\n\t\t...model.table.key.map((column, at) => [column, key[at]]),\n\t\t...[...counters, ...gauges].map((name) => [name, 0]),\n\t\t...distinct.map((name) => [name, null]),\n\t\t[\"_v\", 0]\n\t]);\n};\n/** Whether a change needs its row: sketches merge, and a gauge may reach zero. */\nconst rewrites = ({ model, deltas, sketches }) => Object.keys(sketches).length > 0 || shapeOf(model).gauges.some((gauge) => (deltas[gauge] ?? 0) !== 0);\nconst increment = ({ model, deltas }, key) => Object.values(deltas).some((delta) => delta !== 0) ? {\n\ttype: \"increment\",\n\ttable: model.table,\n\tkey,\n\tby: deltas,\n\tinit: blank(model, key)\n} : void 0;\n/**\n* The guarded write that merges `change` into `current`: insert, patch, or\n* delete at zero. Unlike a transaction's, a gauge may go below zero here: a\n* shard row holds one writer's net changes, and reads sum every shard.\n*/\nconst rewrite = (change, key, current) => {\n\tconst { model } = change;\n\tconst { table } = model;\n\tconst { counters, gauges, distinct } = shapeOf(model);\n\tconst base = current ?? blank(model, key);\n\tconst sum = mergeAll(/* @__PURE__ */ new Map(), [change]);\n\tmerge(sum, model, key, metricsOf(model, base));\n\tconst set = valuesOf([...sum.values()][0]);\n\tif (current && Object.keys(set).every((name) => current[name] === set[name])) return void 0;\n\tconst row = {\n\t\t...base,\n\t\t...set\n\t};\n\tconst zero = distinct.length === 0 && [...counters, ...gauges].every((name) => Number(row[name]) === 0);\n\tif (current === null) return zero ? void 0 : {\n\t\ttype: \"insert\",\n\t\ttable,\n\t\trow\n\t};\n\tconst guard = { v: Number(current[\"_v\"]) };\n\treturn zero ? {\n\t\ttype: \"delete\",\n\t\ttable,\n\t\tkey,\n\t\tguard,\n\t\tprevious: current\n\t} : {\n\t\ttype: \"patch\",\n\t\ttable,\n\t\tkey,\n\t\tset,\n\t\tguard,\n\t\tprevious: current\n\t};\n};\n/**\n* The write for each change on its shard: a blind increment that creates\n* the row for counters, and a guarded rewrite for gauges and sketches, whose\n* rows are read in one batch per table.\n*/\nconst compile = async (adapter, changes, shard) => {\n\tconst keys = changes.map(({ model, key }) => [...key.slice(0, -1), shard(model)]);\n\tconst reads = /* @__PURE__ */ new Map();\n\tchanges.forEach((change, at) => {\n\t\tif (rewrites(change)) reads.set(change.model, [...reads.get(change.model) ?? [], at]);\n\t});\n\tconst current = /* @__PURE__ */ new Map();\n\tawait Promise.all([...reads].map(async ([model, positions]) => {\n\t\tconst rows = await adapter.get(model.table, positions.map((at) => keys[at]));\n\t\tpositions.forEach((at, index) => current.set(at, rows[index] ?? null));\n\t}));\n\treturn changes.map((change, at) => current.has(at) ? rewrite(change, keys[at], current.get(at)) : increment(change, keys[at]));\n};\nconst isOp = (op) => op !== void 0;\nconst sleep = (attempt) => new Promise((resolve) => setTimeout(resolve, Math.min(250, 5 * 2 ** attempt) * Math.random()));\n/** Runs of one character, where shorter: a sparse sketch packs into a few. */\nconst pack = (text) => {\n\tconst runs = (text.match(/(.)\\1*/gsu) ?? []).flatMap((run) => [run[0], run.length]);\n\treturn JSON.stringify(runs).length < JSON.stringify(text).length ? runs : text;\n};\nconst unpack = (value) => Array.isArray(value) ? value.map((item, at) => at % 2 ? \"\" : item.repeat(value[at + 1])).join(\"\") : value;\n/** Raw deflate of `text` as base64, where the runtime has `CompressionStream`. */\nconst deflate = async (text) => {\n\tif (typeof CompressionStream === \"undefined\") return void 0;\n\tconst stream = new Blob([text]).stream().pipeThrough(new CompressionStream(\"deflate-raw\"));\n\tlet binary = \"\";\n\tfor (const byte of new Uint8Array(await new Response(stream).arrayBuffer())) binary += String.fromCharCode(byte);\n\treturn btoa(binary);\n};\nconst inflate = (base64) => new Response(new Blob([Uint8Array.from(atob(base64), (char) => char.charCodeAt(0))]).stream().pipeThrough(new DecompressionStream(\"deflate-raw\"))).text();\n/**\n* A log row's `changes`: entries of a table, an identity, and values, as\n* JSON, or `z` and its deflate where shorter, so a row stays under the 1 KB\n* that DynamoDB bills as one unit.\n*/\nconst encode = async (changes) => {\n\tconst json = JSON.stringify({\n\t\tv: 1,\n\t\tc: [...changes].map(({ model, key, deltas, sketches }) => {\n\t\t\tconst packed = Object.entries(sketches).map(([name, sketch]) => [name, pack(sketch)]);\n\t\t\tconst values = {\n\t\t\t\t...deltas,\n\t\t\t\t...Object.fromEntries(packed)\n\t\t\t};\n\t\t\treturn [\n\t\t\t\tmodel.table.name,\n\t\t\t\tkey.slice(0, -1),\n\t\t\t\tvalues\n\t\t\t];\n\t\t})\n\t});\n\tconst zipped = await deflate(json);\n\treturn zipped !== void 0 && zipped.length < json.length ? `z${zipped}` : json;\n};\n/**\n* Batches changes to aggregates declared `batched`. A transaction records\n* them without writing their rows; once it commits, \"memory\" mode keeps\n* them in this process until its timer flushes them, and \"log\" mode has\n* written them as one log row in the same atomic write, which a compaction\n* later merges into the aggregates and deletes, atomically again, so each\n* applies exactly once. One lease row keeps compactions one at a time.\n*/\nconst createAggregateBatches = ({ engine, adapter, schema, batching: { mode = \"log\", windowMs = WINDOW_MS[mode] }, now }) => {\n\tif (!schema.models.has(LEASE_TABLE)) throw new DatabaseTransactionError(\"An engine that batches aggregates needs aggregateBatchingModule in its schema.\");\n\tconst holder = crypto.randomUUID().replaceAll(\"-\", \"\");\n\tconst table = (name) => schema.models.get(name).table;\n\tconst warned = /* @__PURE__ */ new Set();\n\tconst warn = (what) => (error) => {\n\t\tif (warned.has(what)) return;\n\t\twarned.add(what);\n\t\tconsole.warn(`[hot-updater] Aggregate ${what} failed.`, error);\n\t};\n\t/** A log row's changes, or undefined when it names an aggregate or metric this schema lacks. */\n\tconst decode = async (text) => {\n\t\tconst changes = /* @__PURE__ */ new Map();\n\t\ttry {\n\t\t\tconst json = text.startsWith(\"z\") ? await inflate(text.slice(1)) : text;\n\t\t\tconst { c } = JSON.parse(json);\n\t\t\tfor (const [name, identity, values] of c) {\n\t\t\t\tconst model = schema.models.get(name);\n\t\t\t\tif (!isBatched(model)) return void 0;\n\t\t\t\tconst unpacked = Object.entries(values).map(([metric, value]) => [metric, unpack(value)]);\n\t\t\t\tmerge(changes, model, [...identity, 0], Object.fromEntries(unpacked));\n\t\t\t}\n\t\t} catch (error) {\n\t\t\twarn(\"log decoding\")(error);\n\t\t\treturn;\n\t\t}\n\t\treturn changes;\n\t};\n\t/**\n\t* Writes changes in atomic chunks within `fits`, and returns the ones it\n\t* could not apply. A write whose outcome is unknown is dropped, never\n\t* resent, so no change applies twice.\n\t*/\n\tconst apply = async (changes, shard) => {\n\t\tlet rest = changes;\n\t\tlet ops = [];\n\t\tlet read = true;\n\t\tfor (let failures = 0; rest.length > 0 && failures < ATTEMPTS;) try {\n\t\t\tif (read) ops = await compile(adapter, rest, shard);\n\t\t\tlet size = rest.length;\n\t\t\tconst chunk = () => ops.slice(0, size).filter(isOp);\n\t\t\twhile (size > 1 && !adapter.fits(chunk())) size = Math.ceil(size / 2);\n\t\t\tlet result = { ok: true };\n\t\t\tif (chunk().length > 0) result = await adapter.write(chunk()).catch((error) => {\n\t\t\t\twarn(\"flush\")(error);\n\t\t\t\treturn { ok: true };\n\t\t\t});\n\t\t\tread = !result.ok && !(\"retry\" in result);\n\t\t\tif (result.ok) {\n\t\t\t\trest = rest.slice(size);\n\t\t\t\tops = ops.slice(size);\n\t\t\t\tfailures = 0;\n\t\t\t} else {\n\t\t\t\tfailures += 1;\n\t\t\t\tif (!read) await sleep(failures);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\twarn(\"flush\")(error);\n\t\t\treturn rest;\n\t\t}\n\t\treturn rest;\n\t};\n\tlet buffer = /* @__PURE__ */ new Map();\n\tlet timer;\n\tlet flushing;\n\tconst shards = /* @__PURE__ */ new Map();\n\t/** Each process writes its own shard, so flushes of two processes rarely meet. */\n\tconst processShard = (model) => {\n\t\tif (!shards.has(model)) shards.set(model, Math.floor(Math.random() * shapeOf(model).shards));\n\t\treturn shards.get(model);\n\t};\n\tconst schedule = () => {\n\t\tif (timer !== void 0 || buffer.size === 0) return;\n\t\ttimer = setTimeout(() => {\n\t\t\ttimer = void 0;\n\t\t\tflushBuffer();\n\t\t}, windowMs);\n\t\ttimer.unref?.();\n\t};\n\t/** Never rejects: what it cannot apply goes back into the buffer. */\n\tconst flushBuffer = () => flushing ??= (async () => {\n\t\tclearTimeout(timer);\n\t\ttimer = void 0;\n\t\tconst pending = [...buffer.values()];\n\t\tbuffer = /* @__PURE__ */ new Map();\n\t\tmergeAll(buffer, await apply(pending, processShard));\n\t})().catch(warn(\"flush\")).finally(() => {\n\t\tflushing = void 0;\n\t\tschedule();\n\t});\n\tlet nextDue = 0;\n\tlet compacting;\n\t/** Log rows this process read, by `[log table's index, id]`, for the deletes after a group. */\n\tconst known = /* @__PURE__ */ new Map();\n\tconst idOf = (shard, id) => JSON.stringify([shard, id]);\n\t/** The lease row as stored once `set` is written over it. */\n\tconst leaseOp = (held, set) => {\n\t\tconst next = {\n\t\t\t...held,\n\t\t\t...set,\n\t\t\t_v: Number(held._v) + 1\n\t\t};\n\t\treturn {\n\t\t\top: {\n\t\t\t\ttype: \"patch\",\n\t\t\t\ttable: table(LEASE_TABLE),\n\t\t\t\tkey: [LEASE.id],\n\t\t\t\tset,\n\t\t\t\tguard: { v: Number(held._v) },\n\t\t\t\tprevious: held\n\t\t\t},\n\t\t\tnext\n\t\t};\n\t};\n\t/** The lease row as stored after this process takes it, or undefined when it is held or not due. */\n\tconst takeLease = (force) => engine.transaction(async (tx) => {\n\t\tconst at = now();\n\t\tconst held = await tx.findOne(LEASE_TABLE, LEASE);\n\t\tconst fields = {\n\t\t\tholder,\n\t\t\tuntil: at + LEASE_MS\n\t\t};\n\t\tif (held === null) {\n\t\t\tconst row = {\n\t\t\t\t...LEASE,\n\t\t\t\t...fields,\n\t\t\t\tnext: 0,\n\t\t\t\tapplied: \"[]\"\n\t\t\t};\n\t\t\ttx.create(LEASE_TABLE, row);\n\t\t\treturn {\n\t\t\t\t...row,\n\t\t\t\t_v: 0\n\t\t\t};\n\t\t}\n\t\tnextDue = Number(held.next);\n\t\tif (held.holder !== holder && Number(held.until) > at || !force && nextDue > at) return void 0;\n\t\ttx.update(LEASE_TABLE, held, fields);\n\t\treturn {\n\t\t\t...held,\n\t\t\t...fields,\n\t\t\t_v: Number(held._v) + 1\n\t\t};\n\t});\n\t/**\n\t* Writes `ops` once, retrying transient errors; true when it committed.\n\t* A conflict leaves its log rows for the next compaction; a write whose\n\t* outcome is unknown throws, and the next compaction reads what it did.\n\t*/\n\tconst commit = async (ops) => {\n\t\tfor (let failures = 0; failures < ATTEMPTS; failures += 1) {\n\t\t\tconst result = await adapter.write(ops);\n\t\t\tif (result.ok) return true;\n\t\t\tif (!(\"retry\" in result)) return false;\n\t\t\tawait sleep(failures);\n\t\t}\n\t\treturn false;\n\t};\n\t/** Deletes the log rows `held` lists as applied, in parallel writes; true once none is left. */\n\tconst deleteApplied = async (held) => {\n\t\tconst applied = JSON.parse(String(held.applied));\n\t\tawait Promise.all(LOG_TABLES.map(async (name, shard) => {\n\t\t\tconst ids = applied.flatMap(([at, id]) => at === shard && !known.has(idOf(at, id)) ? [id] : []);\n\t\t\tif (ids.length === 0) return;\n\t\t\tconst rows = await adapter.get(table(name), ids.map((id) => [id]));\n\t\t\tfor (const row of rows) if (row) known.set(idOf(shard, row.id), row);\n\t\t}));\n\t\tconst rows = applied.flatMap(([shard, id]) => {\n\t\t\tconst row = known.get(idOf(shard, id));\n\t\t\treturn row === void 0 ? [] : [{\n\t\t\t\tshard,\n\t\t\t\trow\n\t\t\t}];\n\t\t});\n\t\tif (adapter.deleteConsumed && await Promise.all(LOG_TABLES.map((name, at) => {\n\t\t\tconst own = rows.flatMap(({ shard, row }) => shard === at ? [row] : []);\n\t\t\treturn own.length > 0 && adapter.deleteConsumed(table(name), own);\n\t\t})).then(() => true, (error) => (warn(\"log cleanup\")(error), false))) {\n\t\t\tfor (const [shard, id] of applied) known.delete(idOf(shard, id));\n\t\t\treturn true;\n\t\t}\n\t\tconst deletes = rows.map(({ shard, row }) => {\n\t\t\tconst guard = { v: Number(row[\"_v\"]) };\n\t\t\treturn {\n\t\t\t\ttype: \"delete\",\n\t\t\t\ttable: table(LOG_TABLES[shard]),\n\t\t\t\tkey: [String(row.id)],\n\t\t\t\tguard,\n\t\t\t\tprevious: row\n\t\t\t};\n\t\t});\n\t\tlet size = deletes.length;\n\t\twhile (size > 1 && !adapter.fits(deletes.slice(0, size))) size = Math.ceil(size / 2);\n\t\tconst chunks = [];\n\t\tfor (let at = 0; at < deletes.length; at += size) chunks.push(deletes.slice(at, at + size));\n\t\tif ((await Promise.all(chunks.map(commit))).includes(false)) return false;\n\t\tfor (const [shard, id] of applied) known.delete(idOf(shard, id));\n\t\treturn true;\n\t};\n\t/**\n\t* The oldest pending log rows this schema can read, a page from each\n\t* table; `more` when a page was full, so more may wait.\n\t*/\n\tconst readLogs = async () => {\n\t\tlet more = false;\n\t\treturn {\n\t\t\tlogs: (await Promise.all(LOG_TABLES.map(async (name, shard) => {\n\t\t\t\tconst page = await engine.reads.findMany(name, {\n\t\t\t\t\tindex: \"oldest\",\n\t\t\t\t\tlimit: LOG_PAGE\n\t\t\t\t});\n\t\t\t\tmore ||= page.next !== void 0;\n\t\t\t\treturn (await Promise.all(page.rows.map(async (row) => ({\n\t\t\t\t\tshard,\n\t\t\t\t\trow,\n\t\t\t\t\tchanges: await decode(String(row.changes))\n\t\t\t\t})))).flatMap(({ changes, ...entry }) => changes === void 0 ? [] : [{\n\t\t\t\t\t...entry,\n\t\t\t\t\tchanges\n\t\t\t\t}]);\n\t\t\t}))).flat().sort((left, right) => compareUtf8(String(left.row.id), String(right.row.id))),\n\t\t\tmore\n\t\t};\n\t};\n\tconst rowsFor = async (changes) => (await compile(adapter, changes, () => 0)).filter(isOp);\n\t/**\n\t* Applies the oldest pending log rows whose merged changes fit in one\n\t* atomic write with the lease, which lists them as applied; the rows are\n\t* deleted after it. A log row too large for one write applies in parts,\n\t* keeping the rest in it. Returns the lease after the write and how many\n\t* log rows it applied whole, or undefined when a conflict stopped it.\n\t*/\n\tconst applyGroup = async (held, logs) => {\n\t\tfor (let count = logs.length; count > 0; count = Math.floor(count / 2)) {\n\t\t\tconst batch = logs.slice(0, count);\n\t\t\tconst changes = mergeAll(/* @__PURE__ */ new Map(), batch.flatMap((entry) => [...entry.changes.values()]));\n\t\t\tconst applied = batch.map(({ shard, row }) => [shard, row.id]);\n\t\t\tconst lease = leaseOp(held, { applied: JSON.stringify(applied) });\n\t\t\tconst ops = [...await rowsFor([...changes.values()]), lease.op];\n\t\t\tif (!adapter.fits(ops)) continue;\n\t\t\tfor (const { shard, row } of batch) known.set(idOf(shard, row.id), row);\n\t\t\treturn await commit(ops) ? {\n\t\t\t\theld: lease.next,\n\t\t\t\tcount\n\t\t\t} : void 0;\n\t\t}\n\t\tconst [{ shard, row, changes }] = logs;\n\t\tconst name = LOG_TABLES[shard];\n\t\tconst entries = [...changes.values()];\n\t\tfor (let take = entries.length - 1; take > 0; take = Math.floor(take / 2)) {\n\t\t\tconst kept = {\n\t\t\t\ttype: \"patch\",\n\t\t\t\ttable: table(name),\n\t\t\t\tkey: [String(row.id)],\n\t\t\t\tset: { changes: await encode(entries.slice(take)) },\n\t\t\t\tguard: { v: Number(row[\"_v\"]) },\n\t\t\t\tprevious: row\n\t\t\t};\n\t\t\tconst lease = leaseOp(held, {});\n\t\t\tconst ops = [\n\t\t\t\t...await rowsFor(entries.slice(0, take)),\n\t\t\t\tkept,\n\t\t\t\tlease.op\n\t\t\t];\n\t\t\tif (adapter.fits(ops)) return await commit(ops) ? {\n\t\t\t\theld: lease.next,\n\t\t\t\tcount: 0\n\t\t\t} : void 0;\n\t\t}\n\t\tthrow new DatabaseTransactionError(`${name}: one aggregate change does not fit in one write.`);\n\t};\n\t/**\n\t* Applies up to `groups` groups under the lease, deleting each group's log\n\t* rows before the next; the next compaction is due at once when some are\n\t* left. The lease release clears the applied list once its rows are gone.\n\t*/\n\tconst run = async (force, groups) => {\n\t\tlet held = await takeLease(force);\n\t\tif (held === void 0) return;\n\t\tlet pending = true;\n\t\tlet clear = false;\n\t\ttry {\n\t\t\tfor (let group = 0;; group += 1) {\n\t\t\t\tclear = await deleteApplied(held);\n\t\t\t\tif (!clear || !pending || group === groups) break;\n\t\t\t\tconst { logs, more } = await readLogs();\n\t\t\t\tif (logs.length === 0) {\n\t\t\t\t\tpending = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst applied = await applyGroup(held, logs);\n\t\t\t\tif (applied === void 0) break;\n\t\t\t\t[held, clear] = [applied.held, false];\n\t\t\t\tpending = more || applied.count < logs.length;\n\t\t\t}\n\t\t} finally {\n\t\t\tnextDue = now() + (pending ? 0 : windowMs);\n\t\t\tconst set = {\n\t\t\t\tuntil: 0,\n\t\t\t\tnext: nextDue,\n\t\t\t\t...clear ? { applied: \"[]\" } : {}\n\t\t\t};\n\t\t\tawait commit([leaseOp(held, set).op]);\n\t\t\tknown.clear();\n\t\t}\n\t};\n\t/** One compaction at a time in this process; never rejects. */\n\tconst compact = (force, groups) => compacting ??= run(force, groups).catch(warn(\"compaction\")).finally(() => {\n\t\tcompacting = void 0;\n\t});\n\tlet checking;\n\t/** Whether any log row waits; reads at once share one check. */\n\tconst hasPending = () => checking ??= Promise.all(LOG_TABLES.map((name) => engine.reads.findMany(name, {\n\t\tindex: \"oldest\",\n\t\tlimit: 1\n\t}))).then((pages) => pages.some((page) => page.rows.length > 0)).finally(() => {\n\t\tchecking = void 0;\n\t});\n\t/** Takes a committed transaction's changes; never rejects, since the transaction already committed. */\n\tconst committed = async (changes) => {\n\t\tif (mode === \"log\") {\n\t\t\tif (now() >= nextDue) await compact(false, GROUPS.commit);\n\t\t\treturn;\n\t\t}\n\t\tmergeAll(buffer, changes.values());\n\t\tschedule();\n\t\tif (buffer.size >= MAX_BUFFERED) await flushBuffer();\n\t};\n\tconst flush = async () => {\n\t\tawait flushBuffer();\n\t\tif (mode === \"log\" && await hasPending()) await compact(true, GROUPS.flush);\n\t};\n\treturn {\n\t\tasync transaction(fn) {\n\t\t\tlet changes = /* @__PURE__ */ new Map();\n\t\t\tconst result = await engine.transaction(async (tx) => {\n\t\t\t\tconst attempt = /* @__PURE__ */ new Map();\n\t\t\t\tchanges = attempt;\n\t\t\t\tlet open = true;\n\t\t\t\tlet failure;\n\t\t\t\tconst aggregate = (name, identity, values, options) => {\n\t\t\t\t\tconst model = schema.models.get(name);\n\t\t\t\t\tif (!isBatched(model)) return tx.aggregate(name, identity, values, options);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!open) throw new DatabaseTransactionError(\"The transaction has ended.\");\n\t\t\t\t\t\trecordAggregate(attempt, model, identity, values, options?.shardBy);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tfailure ??= { error };\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttry {\n\t\t\t\t\tconst value = await fn({\n\t\t\t\t\t\t...tx,\n\t\t\t\t\t\taggregate\n\t\t\t\t\t});\n\t\t\t\t\tif (failure) throw failure.error;\n\t\t\t\t\tif (mode === \"log\" && attempt.size > 0) {\n\t\t\t\t\t\tconst id = `${now().toString(36).padStart(9, \"0\")}${holder.slice(0, 8)}${crypto.randomUUID().slice(0, 8)}`;\n\t\t\t\t\t\tconst shard = Math.floor(Math.random() * LOG_TABLES.length);\n\t\t\t\t\t\tconst merged = mergeAll(/* @__PURE__ */ new Map(), attempt.values());\n\t\t\t\t\t\ttx.create(LOG_TABLES[shard], {\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tchanges: await encode(merged.values())\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t} finally {\n\t\t\t\t\topen = false;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (changes.size > 0) await committed(changes);\n\t\t\treturn result;\n\t\t},\n\t\tasync beforeRead(name) {\n\t\t\tif (!isBatched(schema.models.get(name))) return;\n\t\t\tif (buffer.size > 0 || flushing !== void 0) await flushBuffer();\n\t\t\tif (mode === \"log\") {\n\t\t\t\tif (await hasPending().catch((error) => {\n\t\t\t\t\twarn(\"read\")(error);\n\t\t\t\t\treturn false;\n\t\t\t\t})) await compact(true, GROUPS.read);\n\t\t\t}\n\t\t},\n\t\tflush,\n\t\tasync dispose() {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = void 0;\n\t\t\tawait flush();\n\t\t}\n\t};\n};\n//#endregion\nexport { aggregateBatchingModule, createAggregateBatches };\n", "//#region src/engine/database/retention.ts\nconst MINUTE_MS = 6e4;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\n/** A model's retention as its physical table carries it, which each adapter maps natively. */\nconst physicalRetention = ({ retention }) => retention === void 0 ? {} : { retention: {\n\tcolumn: retention.field,\n\tms: retention.days * DAY_MS\n} };\n/** Models in a reference or a rooted index, which an expired row's delete would break. */\nconst linkedModels = (schema) => Object.entries(schema).flatMap(([name, { fields, indexes }]) => [...Object.values(fields).map(({ references }) => references), ...Object.values(indexes).map(({ root }) => root)].flatMap((link) => link ? [name, link.model] : []));\n/**\n* What is wrong with a model's retention: it counts from an integer field,\n* over whole days, and expired rows are deleted without cascades, counter\n* moves, or root bumps, so the model is in no reference or rooted index.\n*/\nconst retentionProblems = (schema, model) => {\n\tconst definition = schema[model];\n\tif (definition.retention === void 0) return [];\n\tconst { field, days } = definition.retention;\n\tconst declared = definition.fields[field] ?? (definition.kind === \"table\" ? definition.derived[field] : void 0);\n\treturn [\n\t\t...declared?.type !== \"integer\" || \"multi\" in declared && declared.multi === true ? [`retention field \"${field}\" is not an integer field`] : [],\n\t\t...Number.isSafeInteger(days) && days >= 1 ? [] : [\"retention days must be a whole number of at least 1\"],\n\t\t...linkedModels(schema).includes(model) ? [\"a model with retention is in no reference or rooted index\"] : []\n\t];\n};\n/**\n* Rows a pass deletes from each table: one statement or two a table, so a\n* pass stays well inside D1's 50 queries an invocation.\n*/\nconst PASS_LIMIT = 500;\n/** The lease row: when the next pass is due, in epoch ms. */\nconst LEASE_KEY = \"retention.nextPassAt\";\n/**\n* The adapter, pruning during its writes with no scheduler: once the lease\n* row in `leaseTable` is due, the write that takes it first runs one bounded\n* pass over the tables with retention, and other writers skip. The next pass\n* is due in an hour, or in a minute while a pass still found a full batch of\n* expired rows in some table; a pass that fails is due again at once. A\n* backend that expires rows natively, or a schema without retention, gets its\n* adapter back.\n*/\nconst pruneDuringWrites = (adapter, tables, { leaseTable: table, now }) => {\n\tconst expiring = tables.filter(({ retention }) => retention !== void 0);\n\tif (adapter.prune === void 0 || expiring.length === 0) return adapter;\n\tconst key = [LEASE_KEY];\n\tlet checkAt = 0;\n\tconst lease = async (row, due) => {\n\t\tconst value = String(due);\n\t\tconst guard = { v: row === null ? -1 : Number(row._v) };\n\t\tconst next = {\n\t\t\tkey: LEASE_KEY,\n\t\t\tvalue,\n\t\t\t_v: guard.v + 1\n\t\t};\n\t\tconst op = row === null ? {\n\t\t\ttype: \"insert\",\n\t\t\ttable,\n\t\t\trow: next\n\t\t} : {\n\t\t\ttype: \"patch\",\n\t\t\ttable,\n\t\t\tkey,\n\t\t\tset: { value },\n\t\t\tguard,\n\t\t\tprevious: row\n\t\t};\n\t\treturn (await adapter.write([op])).ok ? next : null;\n\t};\n\tconst pass = async () => {\n\t\tconst at = now();\n\t\tif (at < checkAt) return;\n\t\tcheckAt = at + MINUTE_MS;\n\t\tconst [row = null] = await adapter.get(table, [key]);\n\t\tcheckAt = row === null ? at : Number(row.value);\n\t\tif (checkAt > at) return;\n\t\tconst held = await lease(row, at + HOUR_MS);\n\t\tif (held === null) return;\n\t\tcheckAt = at + HOUR_MS;\n\t\tconst deleted = [];\n\t\ttry {\n\t\t\tfor (const t of expiring) deleted.push(await adapter.prune(t, at - t.retention.ms, PASS_LIMIT));\n\t\t} catch (error) {\n\t\t\tcheckAt = at + MINUTE_MS;\n\t\t\tawait lease(held, at).catch(() => null);\n\t\t\tthrow error;\n\t\t}\n\t\tif (deleted.includes(PASS_LIMIT) && await lease(held, at + MINUTE_MS) !== null) checkAt = at + MINUTE_MS;\n\t};\n\tconst warn = (error) => console.warn(\"[hot-updater] Pruning expired rows failed.\", error);\n\treturn Object.assign(Object.create(adapter), { async write(ops) {\n\t\tawait pass().catch(warn);\n\t\treturn adapter.write(ops);\n\t} });\n};\n//#endregion\nexport { physicalRetention, pruneDuringWrites, retentionProblems };\n", "import { DatabaseSchemaError } from \"../../database/adapter.mjs\";\nimport { physicalRetention, retentionProblems } from \"./retention.mjs\";\n//#region src/engine/database/resolveSchema.ts\nconst SHARD_COLUMN = \"_shard\";\nconst NAME = /^[a-z][a-z0-9_]*$/u;\nconst INDEX_NAME = /^[A-Za-z][A-Za-z0-9_]*$/u;\nconst tableName = (module, model) => module.namespace ? `${module.namespace}_${model}` : model;\nconst integer = (name, defaulted = false) => ({\n\tname,\n\ttype: \"integer\",\n\tnullable: false,\n\t...defaulted ? { default: 0 } : {}\n});\n/** A declared or derived field's type, and whether it holds several values. */\nconst fieldType = (model, name) => {\n\tconst field = model.fields[name] ?? (model.kind === \"table\" ? model.derived[name] : void 0);\n\treturn field && {\n\t\ttype: field.type,\n\t\tmulti: \"multi\" in field && !!field.multi\n\t};\n};\nconst metricsOf = (model) => [\n\t...model.counters,\n\t...model.gauges,\n\t...model.distinct\n];\n/** Field names, the key, and each field's options. */\nconst fieldProblems = (definition, add) => {\n\tconst names = [...Object.keys(definition.fields), ...definition.kind === \"table\" ? Object.keys(definition.derived) : metricsOf(definition)];\n\tfor (const name of new Set(names)) {\n\t\tif (!NAME.test(name)) add(`field \"${name}\" must match ${NAME.source}`);\n\t\tif (names.indexOf(name) !== names.lastIndexOf(name)) add(`field \"${name}\" is declared twice`);\n\t}\n\tconst { key } = definition;\n\tif (key.length === 0) add(\"key is empty\");\n\tif (new Set(key).size !== key.length) add(\"key repeats a field\");\n\tfor (const name of key) {\n\t\tconst field = definition.fields[name];\n\t\tif (field === void 0) add(`key field \"${name}\" is not a declared field`);\n\t\telse if (field.required === false) add(`key field \"${name}\" is nullable`);\n\t\telse if (field.type === \"json\") add(`key field \"${name}\" is json`);\n\t}\n\tfor (const [name, { type, maxLength, ascii }] of Object.entries(definition.fields)) {\n\t\tif (maxLength !== void 0 && (type !== \"string\" || !Number.isSafeInteger(maxLength) || maxLength < 1)) add(`field \"${name}\" has an invalid maxLength`);\n\t\tif (ascii && type !== \"string\") add(`field \"${name}\" is ascii but not a string`);\n\t}\n};\n/** A table's derived fields and references. */\nconst tableProblems = (definition, add, table) => {\n\tfor (const [name, derived] of Object.entries(definition.derived)) {\n\t\tif (typeof derived.compute !== \"function\") add(`derived field \"${name}\" has no compute function`);\n\t\tif (derived.multi && derived.type === \"json\") add(`derived field \"${name}\" cannot be multi-valued json`);\n\t}\n\tfor (const [name, { type, references }] of Object.entries(definition.fields)) {\n\t\tif (references === void 0) continue;\n\t\tconst target = table(references.model);\n\t\tconst targetKey = target?.key.length === 1 ? target.fields[target.key[0]] : void 0;\n\t\tif (targetKey === void 0) add(`field \"${name}\" references \"${references.model}\", which is not a single-key table of this module`);\n\t\telse if (targetKey.type !== type) add(`field \"${name}\" and the key of \"${references.model}\" differ in type`);\n\t\tif (references.onDelete === \"cascade\" && !Object.values(definition.indexes).some(({ eq }) => eq.length === 1 && eq[0] === name)) add(`cascade on \"${name}\" needs an index whose eq is exactly [${name}]`);\n\t}\n};\n/** An aggregate's identity, metrics, and shards. */\nconst aggregateProblems = (definition, add) => {\n\tconst identity = Object.keys(definition.fields);\n\tif (definition.key.join(\"\\0\") !== identity.join(\"\\0\")) add(`key must list the identity fields in declaration order: ${identity.join(\", \")}`);\n\tif (metricsOf(definition).length === 0) add(\"aggregate has no metrics\");\n\tif (definition.distinct.length > 0 && definition.counters.length + definition.gauges.length > 0) add(\"distinct sketches need an aggregate of their own\");\n\tconst { shards } = definition;\n\tif (!Number.isSafeInteger(shards) || shards < 1 || shards > 64) add(`shards must be 1\u201364`);\n};\n/** Every problem in one model's declaration, its roots and references included. */\nconst problemsOf = (module, model, definition) => {\n\tconst problems = [];\n\tconst add = (message) => problems.push(`${module.id}.${model}: ${message}`);\n\tconst table = (name) => {\n\t\tconst target = module.schema[name];\n\t\treturn target?.kind === \"table\" ? target : void 0;\n\t};\n\tif (!NAME.test(model)) add(\"model names use lowercase letters, digits, and _\");\n\tfieldProblems(definition, add);\n\tfor (const [name, index] of Object.entries(definition.indexes)) {\n\t\tconst columns = [...index.eq, ...index.sort];\n\t\tif (!INDEX_NAME.test(name)) add(`index \"${name}\" must match ${INDEX_NAME.source}`);\n\t\tif (columns.length === 0) add(`index \"${name}\" has no fields`);\n\t\tif (index.unique && index.sort.length > 0) add(`unique index \"${name}\" cannot sort`);\n\t\tif (columns.filter((column) => {\n\t\t\tconst type = fieldType(definition, column);\n\t\t\tif (type === void 0) add(`index \"${name}\" names undeclared field \"${column}\"`);\n\t\t\telse if (type.type === \"json\") add(`index \"${name}\" names json field \"${column}\"`);\n\t\t\telse if (type.multi && index.sort.includes(column)) add(`index \"${name}\" sorts by multi-valued field \"${column}\"`);\n\t\t\treturn type?.type !== \"json\" && type?.multi;\n\t\t}).length > 1) add(`index \"${name}\" has more than one multi-valued field`);\n\t\tif (index.root === void 0) continue;\n\t\tconst root = table(index.root.model);\n\t\tif (root === void 0) add(`index \"${name}\" is rooted at unknown table \"${index.root.model}\"`);\n\t\telse if (root.key.length > index.eq.length || root.key.some((field, position) => fieldType(definition, index.eq[position])?.type !== root.fields[field].type)) add(`index \"${name}\" eq must start with the key of \"${index.root.model}\"`);\n\t}\n\tif (definition.kind === \"table\") tableProblems(definition, add, table);\n\telse aggregateProblems(definition, add);\n\tfor (const problem of retentionProblems(module.schema, model)) add(problem);\n\treturn problems;\n};\n/** Rejects invalid module schemas at startup, listing every problem. */\nconst validateSchema = (modules) => {\n\tconst problems = [];\n\tconst owners = /* @__PURE__ */ new Map();\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tconst name = tableName(module, model);\n\t\tconst owner = owners.get(name);\n\t\tif (owner !== void 0) problems.push(`${module.id}.${model}: table \"${name}\" is also declared by ${owner}`);\n\t\towners.set(name, `${module.id}.${model}`);\n\t\tproblems.push(...problemsOf(module, model, definition));\n\t}\n\tif (problems.length > 0) throw new DatabaseSchemaError(`Invalid database schema:\\n- ${problems.join(\"\\n- \")}`);\n};\nconst indexesOf = (definition) => [...Object.entries(definition.indexes).map(([name, index]) => ({\n\tname,\n\teq: [...index.eq],\n\tsort: [...index.sort],\n\t...index.unique ? { unique: true } : {}\n})), ...Object.entries(definition.fields).flatMap(([name, field]) => field.unique ? [{\n\tname,\n\teq: [name],\n\tsort: [],\n\tunique: true\n}] : [])];\n/** Validates the modules, then resolves them into physical tables with engine columns. */\nconst resolveSchema = (modules) => {\n\tvalidateSchema(modules);\n\tconst references = [];\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tif (definition.kind !== \"table\") continue;\n\t\tconst table = tableName(module, model);\n\t\tfor (const [field, { references: to }] of Object.entries(definition.fields)) {\n\t\t\tif (to === void 0) continue;\n\t\t\tconst { onDelete } = to;\n\t\t\tconst target = tableName(module, to.model);\n\t\t\tconst counter = onDelete === \"none\" ? {} : { counter: `_refs_${table}_${field}` };\n\t\t\treferences.push({\n\t\t\t\ttable,\n\t\t\t\tfield,\n\t\t\t\ttarget,\n\t\t\t\tonDelete,\n\t\t\t\t...counter\n\t\t\t});\n\t\t}\n\t}\n\tconst models = /* @__PURE__ */ new Map();\n\tfor (const module of modules) for (const [model, definition] of Object.entries(module.schema)) {\n\t\tconst name = tableName(module, model);\n\t\tconst referencedBy = references.filter(({ target }) => target === name);\n\t\tconst columns = Object.entries(definition.fields).map(([field, { type, required, maxLength, ascii }]) => ({\n\t\t\tname: field,\n\t\t\ttype,\n\t\t\tnullable: required === false,\n\t\t\t...maxLength === void 0 ? {} : { maxLength },\n\t\t\t...ascii ? { ascii } : {}\n\t\t}));\n\t\tif (definition.kind === \"table\") for (const [field, { type, multi }] of Object.entries(definition.derived)) columns.push({\n\t\t\tname: field,\n\t\t\ttype,\n\t\t\tnullable: true,\n\t\t\t...multi ? { multi } : {}\n\t\t});\n\t\telse columns.push(integer(SHARD_COLUMN), ...[...definition.counters, ...definition.gauges].map((metric) => integer(metric)), ...definition.distinct.map((metric) => ({\n\t\t\tname: metric,\n\t\t\ttype: \"string\",\n\t\t\tnullable: true\n\t\t})));\n\t\tfor (const { counter } of referencedBy) if (counter !== void 0) columns.push(integer(counter, true));\n\t\tcolumns.push(integer(\"_v\", true));\n\t\tmodels.set(name, {\n\t\t\tmodule: module.id,\n\t\t\tmodel,\n\t\t\tdefinition,\n\t\t\ttable: {\n\t\t\t\tname,\n\t\t\t\tcolumns,\n\t\t\t\tkey: definition.kind === \"aggregate\" ? [...definition.key, SHARD_COLUMN] : [...definition.key],\n\t\t\t\tindexes: indexesOf(definition),\n\t\t\t\t...physicalRetention(definition)\n\t\t\t},\n\t\t\treferences: references.filter(({ table }) => table === name),\n\t\t\treferencedBy,\n\t\t\troots: new Map(Object.entries(definition.indexes).flatMap(([index, { root }]) => root === void 0 ? [] : [[index, tableName(module, root.model)]]))\n\t\t});\n\t}\n\treturn {\n\t\tmodels,\n\t\ttables: [...models.values()].map(({ table }) => table)\n\t};\n};\n//#endregion\nexport { SHARD_COLUMN, resolveSchema, validateSchema };\n", "import { HOT_UPDATER_SCHEMA_VERSION } from \"../core/schema.mjs\";\nimport { getEmptyMigrationResult } from \"./fixedMigratorShared.mjs\";\nimport { migrateSchema } from \"./schemaSettings.mjs\";\nimport { refuseV0Database, storedSchemaVersion } from \"./settingsMigrator.mjs\";\n//#region src/engine/db/engineMigrator.ts\n/**\n* `hot-updater db migrate` for a store whose adapter creates its own tables\n* (MongoDB and the key-value stores): the tables and indexes, then the\n* settings rows, applied when a setting is missing or different, and refused\n* on a v0 database.\n*/\nconst createEngineMigrator = (options) => {\n\tconst getVersion = async () => storedSchemaVersion(await options.readSettings());\n\tconst makeResult = async (migrate = {}) => {\n\t\tconst stored = await options.readSettings();\n\t\trefuseV0Database(options.adapterName, stored);\n\t\tif (Object.entries(options.settings).every(([key, value]) => stored.get(key) === value)) return getEmptyMigrationResult();\n\t\treturn {\n\t\t\toperations: [...options.schema.tables.map((table) => ({\n\t\t\t\ttype: \"create-table\",\n\t\t\t\tvalue: {\n\t\t\t\t\tormName: table.name,\n\t\t\t\t\tcolumns: Object.fromEntries(table.columns.map((column) => [column.name, {\n\t\t\t\t\t\tormName: column.name,\n\t\t\t\t\t\ttype: column.type\n\t\t\t\t\t}]))\n\t\t\t\t}\n\t\t\t})), ...migrate.updateSettings === false ? [] : [{\n\t\t\t\ttype: \"custom\",\n\t\t\t\tdescription: `Write the schema settings: ${Object.keys(options.settings).join(\", \")}`\n\t\t\t}]],\n\t\t\texecute: () => migrateSchema(options.adapter, options.adapterName, options.schema.tables, options.settings)\n\t\t};\n\t};\n\treturn {\n\t\tgetVersion,\n\t\tgetNameVariants: async () => void 0,\n\t\tnext: async () => await getVersion() === \"1.0.0\" ? void 0 : { version: HOT_UPDATER_SCHEMA_VERSION },\n\t\tprevious: async () => void 0,\n\t\tup: makeResult,\n\t\tdown: async () => {\n\t\t\tthrow new Error(\"No previous schema to migrate to.\");\n\t\t},\n\t\tmigrateTo: async (version, migrate) => {\n\t\t\tif (version !== \"1.0.0\") throw new Error(`Invalid version ${version}`);\n\t\t\treturn makeResult(migrate);\n\t\t},\n\t\tmigrateToLatest: makeResult\n\t};\n};\n//#endregion\nexport { createEngineMigrator };\n", "import { HOT_UPDATER_SCHEMA_VERSION, coreModule } from \"../core/schema.mjs\";\nimport { aggregateBatchingModule } from \"../database/aggregateBatching.mjs\";\nimport { resolveSchema } from \"../database/resolveSchema.mjs\";\nimport { ENGINE_SCHEMA_KEY, isMissingSchemaError, readSettings, withSchemaFence } from \"../database/fence.mjs\";\nimport { migrateSchema } from \"./schemaSettings.mjs\";\nimport { createEngineMigrator } from \"./engineMigrator.mjs\";\n//#region src/engine/db/coreDatabase.ts\n/** Core's tables: the tables every provider's tooling creates. */\nconst coreSchema = resolveSchema([coreModule]);\n/** The settings rows a provider's database is fenced by. */\nconst coreSettings = {\n\t[ENGINE_SCHEMA_KEY]: \"1\",\n\t\"schema.core\": HOT_UPDATER_SCHEMA_VERSION\n};\n/** What `hot-updater db` creates for a server without plugins. */\nconst coreTarget = {\n\tschema: coreSchema,\n\tsettings: coreSettings\n};\n/**\n* The log and lease tables a database with `aggregateBatching` writes\n* beside core's and the plugins', which a provider's access policy names,\n* such as the managed AWS server's IAM role.\n*/\nconst aggregateBatchingTables = resolveSchema([aggregateBatchingModule]).tables;\n/** Each plugin's `schema.<id>` settings row. */\nconst pluginSettings = (plugins) => Object.fromEntries(plugins.map(({ id, schemaVersion }) => [`schema.${id}`, schemaVersion]));\n/** A plugin's schema as the engine resolves it: prefixed by its id unless it keeps its names. */\nconst pluginModule = ({ id, schema, namespace }) => ({\n\tid,\n\tschema,\n\t...namespace === false ? {} : { namespace: id }\n});\n/**\n* What `hot-updater db` creates for a server's plugins: core's tables, then\n* each plugin's tables with its `schema.<id>` settings row.\n*/\nconst toolingTargetOf = (plugins) => plugins.length === 0 ? coreTarget : {\n\tschema: resolveSchema([coreModule, ...plugins.map(pluginModule)]),\n\tsettings: {\n\t\t...coreSettings,\n\t\t...pluginSettings(plugins)\n\t}\n};\n/**\n* Creates core's tables and those of `plugins`, then writes their settings\n* rows: what a provider's setup runs for the plugins its server runs.\n*/\nconst migrateCoreSchema = (adapter, name, plugins = []) => {\n\tconst { schema, settings } = toolingTargetOf(plugins);\n\treturn migrateSchema(adapter, name, schema.tables, settings);\n};\n/**\n* A provider's database on the storage engine: its adapter behind the schema\n* fence, which checks core's settings rows before the first read or write\n* and names `hot-updater db migrate` when they are missing or stale. When the\n* adapter creates its own tables, `hot-updater db migrate` creates core's\n* tables and the server's plugin tables, then writes their settings rows.\n*/\nconst createEngineDatabase = ({ name, adapter, onCachedRoutesChange, aggregateBatching, retry, readSettings: readStored }) => {\n\tconst fenced = withSchemaFence(adapter, name, coreSettings);\n\tconst createMigrator = ({ schema, settings } = coreTarget) => createEngineMigrator({\n\t\tadapterName: name,\n\t\tadapter,\n\t\tschema,\n\t\tsettings,\n\t\treadSettings: readStored ?? (async () => {\n\t\t\tconst rows = await readSettings(adapter, Object.keys(settings)).catch((error) => {\n\t\t\t\tif (isMissingSchemaError(error)) return [];\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\treturn new Map(rows.flatMap((row) => row === null ? [] : [[String(row.key), row.value]]));\n\t\t})\n\t});\n\treturn {\n\t\tname,\n\t\tadapter: fenced,\n\t\t...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange },\n\t\t...aggregateBatching ? { aggregateBatching } : {},\n\t\t...retry === void 0 ? {} : { retry },\n\t\t...adapter.dispose === void 0 ? {} : { dispose: () => adapter.dispose() },\n\t\t...adapter.migrations === void 0 ? {} : { createMigrator }\n\t};\n};\n//#endregion\nexport { aggregateBatchingTables, coreSchema, coreSettings, coreTarget, createEngineDatabase, migrateCoreSchema, pluginModule, pluginSettings, toolingTargetOf };\n", "import { DatabaseAmbiguousCommitError, DatabaseConflictError, DatabaseConstraintError, DatabaseQueryError, DatabaseTransactionError } from \"../../serverPlugin/errors.mjs\";\nimport { rowKey } from \"../../database/adapter.mjs\";\nimport { canonicalJson, compareTuples, indexEntries } from \"../../database/values.mjs\";\nimport { NegativeGaugeError, compileAggregates, recordAggregate } from \"./engineAggregates.mjs\";\n//#region src/engine/database/engineTransaction.ts\n/** A row this attempt read changed while it ran; the attempt reruns. */\nvar StaleReadError = class extends Error {};\nconst idOf = (table, key) => JSON.stringify([table, key]);\nconst versionOf = (row) => Number(row[\"_v\"]);\nconst isKeyed = (value) => value !== null && value !== void 0;\nconst misuse = (table, message) => new DatabaseTransactionError(`${table}: ${message}`);\nconst once = (table) => misuse(table, \"a transaction writes one key once.\");\nconst hooks = globalThis.process?.getBuiltinModule?.(\"node:async_hooks\");\n/** Where the runtime tracks async context, `db.*` inside a transaction throws. */\nconst transactionScope = hooks && new hooks.AsyncLocalStorage();\nconst assertOutsideTransaction = () => {\n\tif (transactionScope?.getStore() !== void 0) throw new DatabaseTransactionError(\"Inside transaction(), read and write through its handle; db and core are not part of it.\");\n};\nconst createTransactions = ({ adapter, schema, reads, retry = {} }) => {\n\tconst { attempts = 8, baseDelayMs = 5, maxDelayMs = 250, onRetry } = retry;\n\tconst { modelOf } = reads;\n\t/**\n\t* A key-value index copy has no `_v`. A transaction guards what it reads,\n\t* so it reads such a row whole, and reruns if it changed since the copy.\n\t*/\n\tconst complete = async ({ table }, rows) => {\n\t\tconst copies = rows.filter((row) => !(\"_v\" in row));\n\t\tif (copies.length === 0) return [...rows];\n\t\tconst current = await adapter.get(table, copies.map((copy) => rowKey(table, copy)));\n\t\treturn rows.map((row) => {\n\t\t\tconst at = copies.indexOf(row);\n\t\t\tif (at < 0) return row;\n\t\t\tconst whole = current[at];\n\t\t\tif (!whole || Object.keys(row).some((column) => canonicalJson(row[column]) !== canonicalJson(whole[column]))) throw new StaleReadError();\n\t\t\treturn whole;\n\t\t});\n\t};\n\tconst attempt = async (fn) => {\n\t\tconst read = /* @__PURE__ */ new Map();\n\t\t/** Rows of rooted ranges: their root guards them, so they need no check of their own. */\n\t\tconst ranged = /* @__PURE__ */ new Map();\n\t\tconst writes = /* @__PURE__ */ new Map();\n\t\t/** Deleted keys, children before their parents. */\n\t\tconst deleted = [];\n\t\tconst aggregates = /* @__PURE__ */ new Map();\n\t\tlet open = true;\n\t\tlet failure;\n\t\t/** A failed call fails the attempt even when `fn` catches it. */\n\t\tconst step = (method) => (...args) => {\n\t\t\tif (!open) throw new DatabaseTransactionError(\"The transaction has ended.\");\n\t\t\tconst fail = (error) => {\n\t\t\t\tfailure ??= { error };\n\t\t\t\tthrow error;\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = method(...args);\n\t\t\t\treturn result instanceof Promise ? result.catch(fail) : result;\n\t\t\t} catch (error) {\n\t\t\t\treturn fail(error);\n\t\t\t}\n\t\t};\n\t\tconst remember = (model, key, row) => {\n\t\t\tconst id = idOf(model.table.name, key);\n\t\t\tconst known = read.get(id);\n\t\t\tif (known !== void 0 && (known && row ? versionOf(known) !== versionOf(row) : known !== row)) throw new StaleReadError();\n\t\t\tread.set(id, row);\n\t\t\treturn row;\n\t\t};\n\t\tconst readRow = ({ table }, row) => {\n\t\t\tconst id = idOf(table.name, rowKey(table, row));\n\t\t\tconst known = read.get(id) ?? ranged.get(id);\n\t\t\tif (known && versionOf(known) === versionOf(row)) return known;\n\t\t\tthrow misuse(table.name, \"update and delete take a row this transaction read.\");\n\t\t};\n\t\tconst checkFields = ({ table, definition: { fields } }, values, creating) => {\n\t\t\tfor (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\"}.`);\n\t\t\tfor (const [field, { required }] of Object.entries(fields)) if (required !== false && (creating || field in values) && !isKeyed(values[field])) throw misuse(table.name, `${field} is required.`);\n\t\t};\n\t\t/** Adds counter deltas to a key's pending op; an empty `by` still bumps `_v`. */\n\t\tconst bump = (model, key, by) => {\n\t\t\tconst id = idOf(model.table.name, key);\n\t\t\tconst pending = writes.get(id);\n\t\t\tif (pending === void 0) writes.set(id, {\n\t\t\t\tmodel,\n\t\t\t\tkey,\n\t\t\t\ttype: \"increment\",\n\t\t\t\trow: { ...by }\n\t\t\t});\n\t\t\telse if (pending.type !== \"delete\") for (const [column, delta] of Object.entries(by)) pending.row[column] = Number(pending.row[column] ?? pending.read?.[column] ?? 0) + delta;\n\t\t\telse if (Object.values(by).some((delta) => delta > 0)) throw new DatabaseConstraintError(\"not_found\", model.table.name);\n\t\t};\n\t\t/** Moves parent counters when a reference changes and bumps every rooted parent. */\n\t\tconst touchParents = (model, before, after) => {\n\t\t\tfor (const { field, counter, target } of model.references) {\n\t\t\t\tconst [from, to] = [before?.[field], after?.[field]];\n\t\t\t\tif (counter === void 0 || from === to) continue;\n\t\t\t\tif (isKeyed(from)) bump(modelOf(target), [from], { [counter]: -1 });\n\t\t\t\tif (isKeyed(to)) bump(modelOf(target), [to], { [counter]: 1 });\n\t\t\t}\n\t\t\tfor (const [index, root] of model.roots) {\n\t\t\t\tconst parent = modelOf(root);\n\t\t\t\tconst { eq } = model.table.indexes.find(({ name }) => name === index);\n\t\t\t\tfor (const row of [before, after]) {\n\t\t\t\t\tconst key = eq.slice(0, parent.table.key.length).map((field) => row?.[field]);\n\t\t\t\t\tif (row && key.every(isKeyed)) bump(parent, key, {});\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tconst derive = ({ definition }, row) => {\n\t\t\tif (definition.kind === \"table\") for (const [name, derived] of Object.entries(definition.derived)) row[name] = derived.compute(row);\n\t\t\treturn row;\n\t\t};\n\t\t/** Deletes a row after its cascaded children, or refuses a restricted delete. */\n\t\tconst remove = async (model, known) => {\n\t\t\tconst { table } = model;\n\t\t\tconst key = rowKey(table, known);\n\t\t\tconst id = idOf(table.name, key);\n\t\t\tconst pending = writes.get(id);\n\t\t\tif (pending?.type === \"delete\") return;\n\t\t\tif (pending && pending.type !== \"increment\") throw once(table.name);\n\t\t\twrites.set(id, {\n\t\t\t\tmodel,\n\t\t\t\tkey,\n\t\t\t\ttype: \"delete\",\n\t\t\t\trow: {},\n\t\t\t\tread: known\n\t\t\t});\n\t\t\ttouchParents(model, known, null);\n\t\t\tfor (const reference of model.referencedBy) {\n\t\t\t\tconst { counter, field, onDelete, table: name } = reference;\n\t\t\t\tif (counter === void 0) continue;\n\t\t\t\tconst stored = Number(known[counter] ?? 0);\n\t\t\t\tconst added = Number(pending?.row[counter] ?? 0);\n\t\t\t\tif (added > 0) throw new DatabaseConstraintError(\"referenced\", table.name);\n\t\t\t\tif (stored + added <= 0) continue;\n\t\t\t\tif (onDelete === \"restrict\") {\n\t\t\t\t\tconst [current] = await adapter.get(table, [key]);\n\t\t\t\t\tif (current && versionOf(current) === versionOf(known)) throw new DatabaseConstraintError(\"referenced\", table.name);\n\t\t\t\t\tthrow new StaleReadError();\n\t\t\t\t}\n\t\t\t\tconst child = modelOf(name);\n\t\t\t\tconst index = child.table.indexes.find(({ eq }) => eq.length === 1 && eq[0] === field);\n\t\t\t\tlet cursor;\n\t\t\t\tlet seen = 0;\n\t\t\t\tdo {\n\t\t\t\t\tconst page = await reads.findMany(name, {\n\t\t\t\t\t\tindex: index.name,\n\t\t\t\t\t\twhere: { [field]: key[0] },\n\t\t\t\t\t\tlimit: Math.min(stored - seen, reads.maxPageSize),\n\t\t\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t\t\t});\n\t\t\t\t\tfor (const row of await complete(child, page.rows)) {\n\t\t\t\t\t\tremember(child, rowKey(child.table, row), row);\n\t\t\t\t\t\tawait remove(child, row);\n\t\t\t\t\t}\n\t\t\t\t\tseen += page.rows.length;\n\t\t\t\t\tcursor = page.next;\n\t\t\t\t} while (cursor !== void 0 && seen < stored);\n\t\t\t}\n\t\t\tdeleted.push(id);\n\t\t};\n\t\tconst tx = {\n\t\t\tfindOne: step(async (name, lookup) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst { table } = model;\n\t\t\t\tconst found = await reads.findOne(name, lookup);\n\t\t\t\tif (found === null && !table.key.every((field) => field in lookup)) return null;\n\t\t\t\tconst [row = null] = found ? await complete(model, [found]) : [];\n\t\t\t\tconst key = row ? rowKey(table, row) : table.key.map((field) => lookup[field]);\n\t\t\t\treturn remember(model, key, row);\n\t\t\t}),\n\t\t\tfindMany: step(async (name, input) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst root = model.roots.get(input.index);\n\t\t\t\tif (root === void 0) throw new DatabaseQueryError(`${name}.${input.index} is not rooted; a transaction reads a range only under a guarded parent.`);\n\t\t\t\tconst parent = modelOf(root);\n\t\t\t\tconst { eq } = model.table.indexes.find(({ name: index }) => index === input.index);\n\t\t\t\tconst where = input.where ?? {};\n\t\t\t\tconst lookup = Object.fromEntries(parent.table.key.map((field, at) => [field, where[eq[at]]]));\n\t\t\t\tremember(parent, Object.values(lookup), await reads.findOne(root, lookup));\n\t\t\t\tconst found = await reads.findMany(name, input);\n\t\t\t\tconst rows = await complete(model, found.rows);\n\t\t\t\tfor (const row of rows) ranged.set(idOf(name, rowKey(model.table, row)), row);\n\t\t\t\treturn {\n\t\t\t\t\t...found,\n\t\t\t\t\trows\n\t\t\t\t};\n\t\t\t}),\n\t\t\tcreate: step((name, values) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tcheckFields(model, values, true);\n\t\t\t\tconst defaults = model.table.columns.flatMap((column) => column.nullable || column.default !== void 0 ? [[column.name, column.default ?? null]] : []);\n\t\t\t\tconst row = derive(model, {\n\t\t\t\t\t...Object.fromEntries(defaults),\n\t\t\t\t\t...values\n\t\t\t\t});\n\t\t\t\tconst key = rowKey(model.table, row);\n\t\t\t\tconst id = idOf(name, key);\n\t\t\t\tconst pending = writes.get(id);\n\t\t\t\tif (pending && pending.type !== \"increment\") throw once(name);\n\t\t\t\tfor (const [column, delta] of Object.entries(pending?.row ?? {})) row[column] = Number(row[column]) + Number(delta);\n\t\t\t\twrites.set(id, {\n\t\t\t\t\tmodel,\n\t\t\t\t\tkey,\n\t\t\t\t\ttype: \"insert\",\n\t\t\t\t\trow\n\t\t\t\t});\n\t\t\t\ttouchParents(model, null, row);\n\t\t\t}),\n\t\t\tupdate: step((name, row, set) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tconst known = readRow(model, row);\n\t\t\t\tcheckFields(model, set, false);\n\t\t\t\tconst key = rowKey(model.table, known);\n\t\t\t\tconst id = idOf(name, key);\n\t\t\t\tconst pending = writes.get(id);\n\t\t\t\tif (pending?.type === \"insert\" || pending?.type === \"delete\") throw once(name);\n\t\t\t\tconst before = pending?.type === \"patch\" ? {\n\t\t\t\t\t...known,\n\t\t\t\t\t...pending.row\n\t\t\t\t} : known;\n\t\t\t\tconst next = derive(model, {\n\t\t\t\t\t...before,\n\t\t\t\t\t...set\n\t\t\t\t});\n\t\t\t\tconst changed = Object.entries(next).filter(([column, value]) => column !== \"_v\" && JSON.stringify(value) !== JSON.stringify(known[column]));\n\t\t\t\tconst patch = Object.fromEntries(changed);\n\t\t\t\twrites.set(id, {\n\t\t\t\t\tmodel,\n\t\t\t\t\tkey,\n\t\t\t\t\ttype: \"patch\",\n\t\t\t\t\trow: patch,\n\t\t\t\t\tread: known\n\t\t\t\t});\n\t\t\t\tif (pending?.type === \"increment\") bump(model, key, pending.row);\n\t\t\t\ttouchParents(model, before, next);\n\t\t\t}),\n\t\t\tdelete: step(async (name, row) => {\n\t\t\t\tconst model = modelOf(name);\n\t\t\t\tawait remove(model, readRow(model, row));\n\t\t\t}),\n\t\t\taggregate: step((name, identity, values, options) => {\n\t\t\t\tconst model = modelOf(name, \"aggregate\");\n\t\t\t\trecordAggregate(aggregates, model, identity, values, options?.shardBy);\n\t\t\t})\n\t\t};\n\t\ttry {\n\t\t\tconst result = await (transactionScope ? transactionScope.run(tx, () => fn(tx)) : fn(tx));\n\t\t\tif (failure) throw failure.error;\n\t\t\treturn {\n\t\t\t\tresult,\n\t\t\t\tread,\n\t\t\t\tops: compile(writes, read, deleted),\n\t\t\t\taggregates: [...aggregates.values()]\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow failure?.error instanceof StaleReadError ? failure.error : error;\n\t\t} finally {\n\t\t\topen = false;\n\t\t}\n\t};\n\t/** Inserts first, then patches and increments, then checks, then deletes, children before parents. */\n\tconst compile = (writes, read, deleted) => {\n\t\tconst toOp = (id) => {\n\t\t\tconst { model, key, type, row, read: previous } = writes.get(id);\n\t\t\tconst { table } = model;\n\t\t\tif (type === \"insert\") return {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\trow\n\t\t\t};\n\t\t\tif (type === \"increment\") {\n\t\t\t\tconst known = read.get(id);\n\t\t\t\tconst by = row;\n\t\t\t\treturn known ? {\n\t\t\t\t\ttype,\n\t\t\t\t\ttable,\n\t\t\t\t\tkey,\n\t\t\t\t\tby,\n\t\t\t\t\tguard: { v: versionOf(known) }\n\t\t\t\t} : {\n\t\t\t\t\ttype,\n\t\t\t\t\ttable,\n\t\t\t\t\tkey,\n\t\t\t\t\tby\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst guard = { v: versionOf(previous) };\n\t\t\treturn type === \"patch\" ? {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tset: row,\n\t\t\t\tguard,\n\t\t\t\tprevious\n\t\t\t} : {\n\t\t\t\ttype,\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t\tguard,\n\t\t\t\tprevious\n\t\t\t};\n\t\t};\n\t\tconst checks = [...read].flatMap(([id, row]) => {\n\t\t\tif (row === null || writes.has(id)) return [];\n\t\t\tconst { table } = schema.models.get(JSON.parse(id)[0]);\n\t\t\tconst guard = { v: versionOf(row) };\n\t\t\treturn [{\n\t\t\t\ttype: \"check\",\n\t\t\t\ttable,\n\t\t\t\tkey: rowKey(table, row),\n\t\t\t\tguard\n\t\t\t}];\n\t\t});\n\t\tconst ofType = (...types) => [...writes.keys()].filter((id) => types.includes(writes.get(id).type));\n\t\treturn [\n\t\t\t...[...ofType(\"insert\"), ...ofType(\"patch\", \"increment\")].map(toOp),\n\t\t\t...checks,\n\t\t\t...deleted.map(toOp)\n\t\t];\n\t};\n\t/** Only a constraint the current state confirms is reported; anything else reruns. */\n\tconst classify = async (op, read) => {\n\t\tif (op.type === \"check\" || op.type === \"delete\") return void 0;\n\t\tif (op.type === \"increment\" && op.guard) return void 0;\n\t\tconst { table } = op;\n\t\tconst key = op.type === \"insert\" ? rowKey(table, op.row) : op.key;\n\t\tconst [current] = await adapter.get(table, [key]);\n\t\tif (op.type === \"increment\") return current ? void 0 : \"not_found\";\n\t\tif (op.type === \"insert\" && current) {\n\t\t\tconst known = read.get(idOf(table.name, key));\n\t\t\treturn known === null || known !== void 0 && versionOf(known) !== versionOf(current) ? void 0 : \"exists\";\n\t\t}\n\t\tif (op.type === \"patch\" && current?.[\"_v\"] !== op.guard.v) return;\n\t\tconst row = op.type === \"insert\" ? op.row : {\n\t\t\t...current,\n\t\t\t...op.set\n\t\t};\n\t\tfor (const index of table.indexes) {\n\t\t\tif (!index.unique) continue;\n\t\t\tfor (const eq of indexEntries(table, index, row)) if ((await adapter.query(table, {\n\t\t\t\tindex: index.name,\n\t\t\t\teq,\n\t\t\t\torder: \"asc\",\n\t\t\t\tlimit: 2\n\t\t\t})).some((other) => compareTuples(rowKey(table, other), key))) return \"unique\";\n\t\t}\n\t};\n\treturn { async transaction(fn) {\n\t\tassertOutsideTransaction();\n\t\tlet run;\n\t\tlet negative;\n\t\tfor (let round = 0; round < attempts; round += 1) {\n\t\t\tconst delay = round && Math.min(maxDelayMs, baseDelayMs * 2 ** (round - 1));\n\t\t\tif (delay > 0) await new Promise((resolve) => setTimeout(resolve, delay / 2 + Math.random() * (delay / 2)));\n\t\t\trun ??= await attempt(fn).catch((error) => {\n\t\t\t\tif (error instanceof StaleReadError) return void 0;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\tif (run === void 0) {\n\t\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet aggregates;\n\t\t\ttry {\n\t\t\t\taggregates = await compileAggregates(adapter, run.aggregates);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof NegativeGaugeError)) throw error;\n\t\t\t\tnegative = error;\n\t\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\t\trun = void 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ops = [...run.ops, ...aggregates];\n\t\t\tif (ops.length <= 1 && ops.every(({ type }) => type === \"check\")) return run.result;\n\t\t\tif (!adapter.fits(ops)) throw new DatabaseConstraintError(\"too_large\", ops[0].table.name);\n\t\t\tlet outcome;\n\t\t\ttry {\n\t\t\t\toutcome = await adapter.write(ops);\n\t\t\t} catch (cause) {\n\t\t\t\tthrow new DatabaseAmbiguousCommitError(\"The commit outcome is unknown.\", { cause });\n\t\t\t}\n\t\t\tif (outcome.ok) return run.result;\n\t\t\tconst failed = \"failedOp\" in outcome ? outcome.failedOp : void 0;\n\t\t\tif (failed === void 0 || failed >= run.ops.length) {\n\t\t\t\tonRetry?.(\"resend\", round + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst reason = await classify(ops[failed], run.read);\n\t\t\tif (reason) throw new DatabaseConstraintError(reason, ops[failed].table.name);\n\t\t\tonRetry?.(\"rerun\", round + 1);\n\t\t\trun = void 0;\n\t\t}\n\t\tthrow negative ?? new DatabaseConflictError(`The transaction conflicted ${attempts} times.`);\n\t} };\n};\n//#endregion\nexport { assertOutsideTransaction, createTransactions };\n", "import { DatabaseQueryError } from \"../../serverPlugin/errors.mjs\";\nimport { mergeDistinct } from \"../../database/distinct.mjs\";\nimport { indexOrderColumns } from \"../../database/adapter.mjs\";\nimport { indexOrderTuple, isKeyValue } from \"../../database/values.mjs\";\nimport { cursorScope, decodeCursor, encodeCursor } from \"./cursor.mjs\";\nimport { SHARD_COLUMN } from \"./resolveSchema.mjs\";\n//#region src/engine/database/engineReads.ts\nconst sameFields = (left, right) => left.length === right.length && left.every((field) => right.includes(field));\nconst keyValue = (value, field) => {\n\tif (isKeyValue(value)) return value;\n\tthrow new DatabaseQueryError(`${field} needs a string, number, or boolean.`);\n};\nconst bound = (exclusive, inclusive, columns) => {\n\tif (exclusive !== void 0 && inclusive !== void 0) throw new DatabaseQueryError(`range on ${columns[0]} sets both bounds of one side.`);\n\tconst value = exclusive ?? inclusive;\n\tif (value === void 0) return void 0;\n\tconst values = Array.isArray(value) ? value : [value];\n\tif (values.length === 0 || values.length > columns.length) throw new DatabaseQueryError(`range on ${columns[0]} takes 1\u2013${columns.length} values of ${columns.join(\", \")}.`);\n\treturn {\n\t\tvalues: values.map((item, position) => keyValue(item, columns[position])),\n\t\tinclusive: inclusive !== void 0\n\t};\n};\nconst createEngineReads = ({ adapter, schema, maxPageSize: requested = 500 }) => {\n\tconst maxPageSize = Math.min(requested, 500);\n\tlet count = {\n\t\tcalls: 0,\n\t\trows: 0\n\t};\n\tconst returned = (rows) => {\n\t\tconst size = Array.isArray(rows) ? rows.length : rows === null ? 0 : 1;\n\t\tcount = {\n\t\t\tcalls: count.calls + 1,\n\t\t\trows: count.rows + size\n\t\t};\n\t\treturn rows;\n\t};\n\t/** A model of `kind` by physical table name, for reads and transactions. */\n\tconst modelOf = (name, kind = \"table\") => {\n\t\tconst model = schema.models.get(name);\n\t\tif (model?.definition.kind === kind) return model;\n\t\tthrow 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.`);\n\t};\n\tconst plan = ({ table }, input) => {\n\t\tconst index = table.indexes.find(({ name }) => name === input.index);\n\t\tif (index === void 0) throw new DatabaseQueryError(`${table.name} has no index ${input.index}.`);\n\t\tconst where = input.where ?? {};\n\t\tif (!sameFields(Object.keys(where), index.eq)) throw new DatabaseQueryError(`${table.name}.${index.name} reads need where on exactly: ${index.eq.join(\", \") || \"(none)\"}.`);\n\t\tconst { limit, order = \"asc\", range } = input;\n\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxPageSize) throw new DatabaseQueryError(`limit must be 1\u2013${maxPageSize}.`);\n\t\tconst columns = indexOrderColumns(table, index);\n\t\tconst eq = index.eq.map((field) => keyValue(where[field], `${table.name}.${field}`));\n\t\tconst scope = cursorScope([\n\t\t\ttable.name,\n\t\t\tindex.name,\n\t\t\teq,\n\t\t\torder,\n\t\t\trange\n\t\t]);\n\t\tlet lower = bound(range?.gt, range?.gte, columns);\n\t\tlet upper = bound(range?.lt, range?.lte, columns);\n\t\tif (input.cursor !== void 0) {\n\t\t\tconst values = decodeCursor(scope, input.cursor);\n\t\t\tif (order === \"asc\") lower = {\n\t\t\t\tvalues,\n\t\t\t\tinclusive: false\n\t\t\t};\n\t\t\telse upper = {\n\t\t\t\tvalues,\n\t\t\t\tinclusive: false\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\trequest: {\n\t\t\t\tindex: index.name,\n\t\t\t\teq,\n\t\t\t\torder,\n\t\t\t\tlimit,\n\t\t\t\t...lower === void 0 ? {} : { lower },\n\t\t\t\t...upper === void 0 ? {} : { upper }\n\t\t\t},\n\t\t\tindex,\n\t\t\tscope\n\t\t};\n\t};\n\t/** Reads rows by key in one batch; the results follow the keys' order. */\n\tconst findByKeys = async (name, lookups) => {\n\t\tconst { table } = modelOf(name, \"table\");\n\t\tconst keys = lookups.map((lookup) => {\n\t\t\tif (!sameFields(Object.keys(lookup), table.key)) throw new DatabaseQueryError(`findByKeys on ${name} takes its key: ${table.key.join(\", \")}.`);\n\t\t\treturn table.key.map((field) => keyValue(lookup[field], `${name}.${field}`));\n\t\t});\n\t\tconst rows = keys.length === 0 ? [] : await adapter.get(table, keys);\n\t\treturned(rows.filter((row) => row !== null));\n\t\treturn rows.map((row) => row ?? null);\n\t};\n\treturn {\n\t\tmaxPageSize,\n\t\tmodelOf,\n\t\treads: {\n\t\t\ttotal: () => count,\n\t\t\treset: () => {\n\t\t\t\tcount = {\n\t\t\t\t\tcalls: 0,\n\t\t\t\t\trows: 0\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\tfindByKeys,\n\t\t/** Reads one row by its key or by the eq fields of a unique index. */\n\t\tasync findOne(name, lookup) {\n\t\t\tconst { table } = modelOf(name, \"table\");\n\t\t\tconst fields = Object.keys(lookup);\n\t\t\tif (sameFields(fields, table.key)) return (await findByKeys(name, [lookup]))[0];\n\t\t\tconst index = table.indexes.find(({ unique, eq }) => unique && sameFields(fields, eq));\n\t\t\tif (index === void 0) throw new DatabaseQueryError(`findOne on ${name} needs its key or a unique field, not ${fields.join(\", \")}.`);\n\t\t\tconst [row] = await adapter.query(table, {\n\t\t\t\tindex: index.name,\n\t\t\t\teq: index.eq.map((field) => keyValue(lookup[field], `${name}.${field}`)),\n\t\t\t\torder: \"asc\",\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn returned(row ?? null);\n\t\t},\n\t\t/** Reads one page of an index range; `next` resumes right after it. */\n\t\tasync findMany(name, input) {\n\t\t\tconst model = modelOf(name, \"table\");\n\t\t\tconst { request, index, scope } = plan(model, input);\n\t\t\tconst rows = returned(await adapter.query(model.table, request));\n\t\t\tconst last = rows.at(-1);\n\t\t\treturn rows.length === input.limit && last !== void 0 ? {\n\t\t\t\trows,\n\t\t\t\tnext: encodeCursor(scope, indexOrderTuple(model.table, index, last))\n\t\t\t} : { rows };\n\t\t},\n\t\t/**\n\t\t* Reads one page of logical aggregate rows, summing counters and gauges\n\t\t* and merging sketches across each row's shards. A row cut off by the\n\t\t* limit is completed by reading only its remaining shards.\n\t\t*/\n\t\tasync findAggregates(name, input) {\n\t\t\tconst model = modelOf(name, \"aggregate\");\n\t\t\tconst { table, definition } = model;\n\t\t\tif (definition.kind !== \"aggregate\") throw new DatabaseQueryError(name);\n\t\t\tconst { request, index, scope } = plan(model, input);\n\t\t\tconst rows = await adapter.query(table, request);\n\t\t\tconst logicalKey = (row) => definition.key.map((column) => keyValue(row[column], column));\n\t\t\tconst groups = /* @__PURE__ */ new Map();\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst key = JSON.stringify(logicalKey(row));\n\t\t\t\tgroups.set(key, [...groups.get(key) ?? [], row]);\n\t\t\t}\n\t\t\tconst full = rows.length === input.limit;\n\t\t\tconst last = [...groups.values()].at(-1);\n\t\t\tif (full && last !== void 0) {\n\t\t\t\tconst seen = new Set(last.map((row) => row[SHARD_COLUMN]));\n\t\t\t\tconst missing = Array.from({ length: definition.shards }, (_, shard) => shard).filter((shard) => !seen.has(shard));\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\tconst key = logicalKey(last[0]);\n\t\t\t\t\tconst rest = await adapter.get(table, missing.map((shard) => [...key, shard]));\n\t\t\t\t\tlast.push(...rest.filter((row) => row !== null));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst merged = [...groups.values()].map((shards) => {\n\t\t\t\tconst row = Object.fromEntries(definition.key.map((field) => [field, shards[0][field]]));\n\t\t\t\tfor (const metric of [...definition.counters, ...definition.gauges]) row[metric] = shards.reduce((sum, shard) => sum + Number(shard[metric] ?? 0), 0);\n\t\t\t\tfor (const metric of definition.distinct) row[metric] = mergeDistinct(shards.map((shard) => shard[metric]));\n\t\t\t\treturn row;\n\t\t\t});\n\t\t\treturned(merged);\n\t\t\tif (!full || last === void 0) return { rows: merged };\n\t\t\tconst tuple = indexOrderTuple(table, index, last[0]);\n\t\t\treturn {\n\t\t\t\trows: merged,\n\t\t\t\tnext: encodeCursor(scope, tuple.slice(0, -1))\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { DatabaseQueryError, createEngineReads };\n", "import { verifyAdapter } from \"../../database/verifyAdapter.mjs\";\nimport { createEngineReads } from \"./engineReads.mjs\";\nimport { createTransactions } from \"./engineTransaction.mjs\";\n//#region src/engine/database/engine.ts\n/** Storage semantics over one adapter, addressed by physical table name. */\nconst createStorageEngine = ({ adapter: given, schema, maxPageSize, verify, retry }) => {\n\tconst verified = verify ? verifyAdapter(given) : void 0;\n\tconst adapter = verified ?? given;\n\tconst reads = createEngineReads({\n\t\tadapter,\n\t\tschema,\n\t\tmaxPageSize\n\t});\n\tconst { transaction } = createTransactions({\n\t\tadapter,\n\t\tschema,\n\t\treads,\n\t\tretry\n\t});\n\treturn {\n\t\treads,\n\t\ttransaction,\n\t\t/** Runs `read` and reports what it read at both boundaries (verify mode only). */\n\t\tasync measureReads(read) {\n\t\t\tif (verified === void 0) throw new Error(\"measureReads needs an engine created with verify: true.\");\n\t\t\tverified.reads.reset();\n\t\t\treads.reads.reset();\n\t\t\treturn {\n\t\t\t\tresult: await read(),\n\t\t\t\tadapter: verified.reads.total(),\n\t\t\t\tengine: reads.reads.total()\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { createStorageEngine };\n", "import \"../../database/adapter.mjs\";\nimport { createAggregateBatches } from \"./aggregateBatching.mjs\";\nimport { assertOutsideTransaction } from \"./engineTransaction.mjs\";\nimport { createStorageEngine } from \"./engine.mjs\";\n//#region src/engine/database/database.ts\n/** The engine plus `database(module)`, which hands a module its typed handle. */\nconst createDatabaseEngine = ({ batching, now = Date.now, meter, ...options }) => {\n\tconst adapter = meter ? meter.wrap(options.adapter) : options.adapter;\n\tconst engine = createStorageEngine({\n\t\t...options,\n\t\tadapter\n\t});\n\tconst { reads } = engine;\n\tmeter?.attach(reads.reads);\n\tconst batches = batching && createAggregateBatches({\n\t\tengine,\n\t\tadapter,\n\t\tschema: options.schema,\n\t\tbatching,\n\t\tnow\n\t});\n\tconst transaction = batches?.transaction ?? engine.transaction;\n\tconst outside = (read) => (...args) => {\n\t\tassertOutsideTransaction();\n\t\treturn read(...args);\n\t};\n\t/** No read outside a transaction returns `_v`, which a key-value index copy lacks. */\n\tconst bare = (row) => row && Object.fromEntries(Object.entries(row).filter(([column]) => column !== \"_v\"));\n\tconst barePage = async (page) => {\n\t\tconst { rows, next } = await page;\n\t\treturn {\n\t\t\trows: rows.map(bare),\n\t\t\t...next === void 0 ? {} : { next }\n\t\t};\n\t};\n\treturn {\n\t\t...engine,\n\t\t/** Applies batched aggregate changes still pending: this process's buffer and the log. */\n\t\tflush: async () => {\n\t\t\tawait batches?.flush();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait batches?.dispose();\n\t\t},\n\t\tdatabase(module) {\n\t\t\tconst name = (model) => module.namespace ? `${module.namespace}_${model}` : model;\n\t\t\treturn {\n\t\t\t\tfindOne: outside(async (model, lookup) => bare(await reads.findOne(name(model), lookup))),\n\t\t\t\tfindByKeys: outside(async (model, keys) => (await reads.findByKeys(name(model), keys)).map(bare)),\n\t\t\t\tfindMany: outside((model, input) => barePage(reads.findMany(name(model), input))),\n\t\t\t\tfindAggregates: outside(async (model, input) => {\n\t\t\t\t\tawait batches?.beforeRead(name(model));\n\t\t\t\t\treturn await barePage(reads.findAggregates(name(model), input));\n\t\t\t\t}),\n\t\t\t\ttransaction: (fn) => transaction((tx) => fn({\n\t\t\t\t\tfindOne: (model, lookup) => tx.findOne(name(model), lookup),\n\t\t\t\t\tfindMany: (model, input) => tx.findMany(name(model), input),\n\t\t\t\t\tcreate: (model, row) => tx.create(name(model), row),\n\t\t\t\t\tupdate: (model, row, set) => tx.update(name(model), row, set),\n\t\t\t\t\tdelete: (model, row) => tx.delete(name(model), row),\n\t\t\t\t\taggregate: (model, identity, changes, options) => tx.aggregate(name(model), identity, changes, options)\n\t\t\t\t}))\n\t\t\t};\n\t\t}\n\t};\n};\n//#endregion\nexport { createDatabaseEngine };\n", "import { HotUpdaterConfigError } from \"../serverPlugin/configError.mjs\";\nimport { coreModule } from \"./core/schema.mjs\";\nimport { aggregateBatchingModule } from \"./database/aggregateBatching.mjs\";\nimport { pruneDuringWrites } from \"./database/retention.mjs\";\nimport { resolveSchema, validateSchema } from \"./database/resolveSchema.mjs\";\nimport { createDatabaseEngine } from \"./database/database.mjs\";\nimport { SETTINGS_TABLE, fencedName, withSchemaFence } from \"./database/fence.mjs\";\nimport { readMeterOf } from \"./database/readMeter.mjs\";\nimport { pluginModule, pluginSettings } from \"./db/coreDatabase.mjs\";\n//#region src/engine/createEngine.ts\n/**\n* How to create plugins' tables on a database, by the tooling it offers:\n* what the plugins' schema fence names when their settings rows are missing.\n*/\nconst pluginTablesFix = (database) => {\n\tconst { createMigrator, generateSchema } = database;\n\tconst managed = \"A managed server runs only its provider's plugins, and rerunning `hot-updater init --provider <provider>` applies the provider's migrations.\";\n\tconst serverProject = \"Run `hot-updater db` commands in the server's project: they load the server file named on the command line, or src/hotUpdater.* or src/db.*, and don't read hot-updater.config.ts.\";\n\treturn createMigrator !== void 0 ? `Run \\`hot-updater db migrate\\`. ${managed} ${serverProject}` : generateSchema !== void 0 ? `Run \\`hot-updater db generate\\` and apply the file it writes. ${managed} ${serverProject}` : managed;\n};\n/**\n* The storage engine over a database, as a server runs it: core's tables\n* and the plugins', with the plugins' settings rows fenced on a fenced\n* database, expired rows pruned during writes, aggregates batched when the\n* database batches them, and reads metered when it came from `meterReads`.\n* `createHotUpdater` runs core and its plugins on one; tests and tools run\n* a plugin on one without a server. Wrap the adapter with `verifyAdapter`\n* to check every call against the adapter contract.\n*/\nconst createEngine = (database, { plugins = [], now = Date.now } = {}) => {\n\tconst modules = /* @__PURE__ */ new Map();\n\tfor (const plugin of plugins) {\n\t\tif (plugin.id === coreModule.id) throw new HotUpdaterConfigError(`Plugin id \"${plugin.id}\" is core's own.`);\n\t\tif (modules.has(plugin.id)) throw new HotUpdaterConfigError(`Plugin \"${plugin.id}\" is registered twice.`);\n\t\tmodules.set(plugin.id, pluginModule(plugin));\n\t}\n\tif (modules.size > 0) validateSchema([coreModule, ...modules.values()]);\n\tconst name = fencedName(database.adapter);\n\tconst fenced = name === void 0 || plugins.length === 0 ? database.adapter : withSchemaFence(database.adapter, name, pluginSettings(plugins), pluginTablesFix(database));\n\tconst batching = database.aggregateBatching;\n\tconst schema = resolveSchema([\n\t\tcoreModule,\n\t\t...modules.values(),\n\t\t...batching === void 0 ? [] : [aggregateBatchingModule]\n\t]);\n\tconst meter = readMeterOf(database);\n\tconst engine = createDatabaseEngine({\n\t\tadapter: pruneDuringWrites(fenced, schema.tables, {\n\t\t\tleaseTable: SETTINGS_TABLE,\n\t\t\tnow\n\t\t}),\n\t\tschema,\n\t\t...database.retry === void 0 ? {} : { retry: database.retry },\n\t\t...batching === void 0 ? {} : {\n\t\t\tbatching,\n\t\t\tnow\n\t\t},\n\t\t...meter === void 0 ? {} : { meter }\n\t});\n\treturn {\n\t\tcore: engine.database(coreModule),\n\t\tdatabase: (plugin) => {\n\t\t\tconst module = modules.get(plugin.id);\n\t\t\tif (module === void 0) throw new HotUpdaterConfigError(`Plugin \"${plugin.id}\" is not one of this engine's plugins.`);\n\t\t\treturn engine.database(module);\n\t\t},\n\t\tflush: () => engine.flush(),\n\t\tdispose: () => engine.dispose()\n\t};\n};\n//#endregion\nexport { createEngine };\n", "import { findPhysicalColumn, findPhysicalIndex, indexOrderColumns, rowKey } from \"../../../database/adapter.mjs\";\nimport { indexEntries, indexOrderTuple, normalizeStoredRow } from \"../../../database/values.mjs\";\nimport { createTableStatements, isMultiIndex, pruneStatements, quoteSql } from \"./sqlSchema.mjs\";\n//#region src/engine/database/sql/sqlAdapter.ts\n/** Where a batch write records its first failed op, before any change applies. */\nconst WRITE_GUARD_TABLE = {\n\tname: \"_hu_write\",\n\tcolumns: [{\n\t\tname: \"id\",\n\t\ttype: \"string\",\n\t\tnullable: false,\n\t\tmaxLength: 36\n\t}, {\n\t\tname: \"failed_op\",\n\t\ttype: \"integer\",\n\t\tnullable: true\n\t}],\n\tkey: [\"id\"],\n\tindexes: []\n};\nconst codes = (values) => new Set(values.split(\" \"));\nconst UNIQUE = codes(\"23505 1062 23503 1451 1452 SQLITE_CONSTRAINT_UNIQUE SQLITE_CONSTRAINT_PRIMARYKEY SQLITE_CONSTRAINT_FOREIGNKEY SQLITE:2067 SQLITE:1555 SQLITE:787\");\nconst RETRY = codes(\"40001 40P01 1213 1205 SQLITE_BUSY SQLITE_BUSY_SNAPSHOT SQLITE_LOCKED SQLITE:5 SQLITE:517 SQLITE:6\");\n/** Driver codes on an error and its causes: SQLSTATE, MySQL errno, SQLite codes. */\nconst codesOf = (error, depth = 0) => {\n\tif (typeof error !== \"object\" || error === null || depth > 3) return [];\n\tconst record = error;\n\tconst named = [\n\t\t\"code\",\n\t\t\"errno\",\n\t\t\"sqlState\",\n\t\t\"extendedCode\"\n\t].flatMap((field) => record[field] === void 0 ? [] : [String(record[field])]);\n\tconst sqlite = [\"errcode\", \"rawCode\"].flatMap((field) => typeof record[field] === \"number\" ? [`SQLITE:${record[field]}`] : []);\n\treturn [\n\t\t...named,\n\t\t...sqlite,\n\t\t...codesOf(record.cause, depth + 1)\n\t];\n};\n/** A constraint names the failed op; a transient error asks the engine to retry. */\nconst classifySqlError = (error) => {\n\tconst found = codesOf(error);\n\tif (found.some((code) => UNIQUE.has(code))) return \"constraint\";\n\treturn found.some((code) => RETRY.has(code)) ? \"retry\" : void 0;\n};\n/** An increment that creates its missing row: an upsert, which always applies. */\nconst upserts = (op) => op.type === \"increment\" && op.init !== void 0 && op.guard === void 0;\nvar FailedOp = class {\n\tindex;\n\tconstructor(index) {\n\t\tthis.index = index;\n\t}\n};\n/**\n* The shared SQL core over one executor: each write compiles to statements\n* run in one transaction, or in one atomic batch where the executor batches.\n*/\nconst createSqlAdapter = ({ executor, tablePrefix = \"\", maxOps = 1e3, maxParams = Number.POSITIVE_INFINITY }) => {\n\tconst { dialect } = executor;\n\tconst postgres = dialect === \"postgresql\";\n\tconst sqlite = dialect === \"sqlite\";\n\tconst lock = sqlite ? \"\" : \" FOR UPDATE\";\n\tconst quote = (name) => quoteSql(dialect, name);\n\tconst tableOf = (table, index) => quote(`${tablePrefix}${table.name}${index ? `__${index.name}` : \"\"}`);\n\tconst version = quote(\"_v\");\n\t/** A statement from `build`, whose `bind` collects parameters in order. */\n\tconst sql = (build) => {\n\t\tconst params = [];\n\t\tconst bind = (value, column) => {\n\t\t\tconst json = column?.multi || column?.type === \"json\";\n\t\t\tparams.push(value === null || value === void 0 ? null : json ? JSON.stringify(value) : typeof value === \"boolean\" && !postgres ? Number(value) : value);\n\t\t\treturn postgres ? `$${params.length}${json ? \"::jsonb\" : \"\"}` : \"?\";\n\t\t};\n\t\treturn {\n\t\t\tsql: build(bind),\n\t\t\tparams\n\t\t};\n\t};\n\t/** Each key column equal to its value in `key`. */\n\tconst keyMatch = (bind, table, key) => table.key.map((column, position) => `${quote(column)} = ${bind(key[position])}`).join(\" AND \");\n\t/** `columns op values` over a tuple prefix, expanded into ORs on MySQL. */\n\tconst compare = (bind, columns, bound, op) => {\n\t\tconst cols = columns.slice(0, bound.values.length).map((column) => `i.${quote(column)}`);\n\t\tconst last = `${op}${bound.inclusive ? \"=\" : \"\"}`;\n\t\tif (cols.length === 1) return `${cols[0]} ${last} ${bind(bound.values[0])}`;\n\t\tif (dialect !== \"mysql\") {\n\t\t\tconst values = bound.values.map((value) => bind(value));\n\t\t\treturn `(${cols.join(\", \")}) ${last} (${values.join(\", \")})`;\n\t\t}\n\t\treturn `(${cols.map((column, position) => [...cols.slice(0, position).map((prefix, at) => `${prefix} = ${bind(bound.values[at])}`), `${column} ${position === cols.length - 1 ? last : op} ${bind(bound.values[position])}`].join(\" AND \")).map((term) => `(${term})`).join(\" OR \")})`;\n\t};\n\t/**\n\t* An op's statements; the first one's result shows whether the op applied.\n\t* Guards via `UPDATE \u2026 WHERE _v = ?`, checks via locking reads, counters\n\t* via upserts. With `when`, every statement also carries that condition,\n\t* and a check has none: a batch write evaluated it first (`failure`).\n\t*/\n\tconst compile = (op, when) => {\n\t\tconst { table } = op;\n\t\tconst name = tableOf(table);\n\t\t/** The row with `key`, at version `v` when given, where `when` holds. */\n\t\tconst where = (bind, key, v) => `${keyMatch(bind, table, key)}${v === void 0 ? \"\" : ` AND ${version} = ${bind(v)}`}${when ? ` AND ${when(bind)}` : \"\"}`;\n\t\t/** Inserts bound values; with `when`, a SELECT yields them only while it holds. */\n\t\tconst insert = (bind, into, columns, values) => `INSERT INTO ${into} (${columns.map(quote).join(\", \")}) ${when ? `SELECT ${values.join(\", \")} WHERE ${when(bind)}` : `VALUES (${values.join(\", \")})`}`;\n\t\t/** Inserts `row` into the op's table, each value bound as its column's type. */\n\t\tconst insertRow = (bind, row) => insert(bind, name, table.columns.map((column) => column.name), table.columns.map((column) => bind(row[column.name], column)));\n\t\t/** Replaces the row's entries in the index table of every multi-valued index. */\n\t\tconst entries = (key, row, changed) => table.indexes.flatMap((index) => {\n\t\t\tconst columns = [...index.eq, ...indexOrderColumns(table, index)];\n\t\t\tif (!isMultiIndex(table, index) || changed && !columns.some((column) => changed.includes(column))) return [];\n\t\t\tconst into = tableOf(table, index);\n\t\t\tconst found = row ? indexEntries(table, index, row) : [];\n\t\t\tconst order = found.length > 0 ? indexOrderTuple(table, index, row) : [];\n\t\t\treturn [sql((bind) => `DELETE FROM ${into} WHERE ${where(bind, key)}`), ...found.map((eq) => sql((bind) => {\n\t\t\t\tconst values = [...eq, ...order].map((value) => bind(value));\n\t\t\t\treturn insert(bind, into, columns, values);\n\t\t\t}))];\n\t\t});\n\t\tswitch (op.type) {\n\t\t\tcase \"insert\": return [sql((bind) => insertRow(bind, op.row)), ...entries(rowKey(table, op.row), op.row)];\n\t\t\tcase \"patch\": return [sql((bind) => {\n\t\t\t\tconst set = Object.entries(op.set).map(([column, value]) => `${quote(column)} = ${bind(value, findPhysicalColumn(table, column))}`);\n\t\t\t\treturn `UPDATE ${name} SET ${[...set, `${version} = ${version} + 1`].join(\", \")} WHERE ${where(bind, op.key, op.guard.v)}`;\n\t\t\t}), ...entries(op.key, {\n\t\t\t\t...op.previous,\n\t\t\t\t...op.set\n\t\t\t}, Object.keys(op.set))];\n\t\t\tcase \"delete\": return [sql((bind) => `DELETE FROM ${name} WHERE ${where(bind, op.key, op.guard.v)}`), ...entries(op.key)];\n\t\t\tcase \"increment\": {\n\t\t\t\tconst deltas = [...Object.entries(op.by), [\"_v\", 1]];\n\t\t\t\tconst bump = (bind, qualify = \"\") => deltas.map(([column, delta]) => `${quote(column)} = ${qualify}${quote(column)} + ${bind(delta)}`).join(\", \");\n\t\t\t\tif (!upserts(op)) return [sql((bind) => `UPDATE ${name} SET ${bump(bind)} WHERE ${where(bind, op.key, op.guard?.v)}`)];\n\t\t\t\tconst row = { ...op.init };\n\t\t\t\tfor (const [column, delta] of deltas) row[column] = Number(row[column] ?? 0) + delta;\n\t\t\t\tconst conflict = dialect === \"mysql\" ? \"ON DUPLICATE KEY UPDATE\" : `ON CONFLICT (${table.key.map(quote).join(\", \")}) DO UPDATE SET`;\n\t\t\t\treturn [sql((bind) => `${insertRow(bind, row)} ${conflict} ${bump(bind, `${name}.`)}`)];\n\t\t\t}\n\t\t\tcase \"check\":\n\t\t\t\tif (when) return [];\n\t\t\t\treturn [sql((bind) => `SELECT ${version} FROM ${name} WHERE ${where(bind, op.key)}${lock}`)];\n\t\t}\n\t};\n\t/**\n\t* SQL that holds when `op` would fail against the rows before any change.\n\t* Rows the write deletes or patches (`released`) do not count as holding a\n\t* unique value.\n\t*/\n\tconst failure = (bind, op, released) => {\n\t\tconst { table } = op;\n\t\tconst from = `SELECT 1 FROM ${tableOf(table)} WHERE`;\n\t\tconst exists = (key, v) => `EXISTS (${from} ${keyMatch(bind, table, key)}${v === void 0 ? \"\" : ` AND ${version} = ${bind(v)}`}${lock})`;\n\t\t/** Another row already holding a unique value this op writes. */\n\t\tconst clashes = (row, own, changed) => table.indexes.filter((index) => index.unique && !isMultiIndex(table, index) && index.eq.every((column) => (row[column] ?? null) !== null) && (!changed || index.eq.some((column) => changed.includes(column)))).map((index) => {\n\t\t\tconst match = index.eq.map((column) => `${quote(column)} = ${bind(row[column], findPhysicalColumn(table, column))}`);\n\t\t\tconst others = [...own ? [own] : [], ...released].map((key) => ` AND NOT (${keyMatch(bind, table, key)})`);\n\t\t\treturn `EXISTS (${from} ${match.join(\" AND \")}${others.join(\"\")})`;\n\t\t});\n\t\tswitch (op.type) {\n\t\t\tcase \"insert\": return [exists(rowKey(table, op.row)), ...clashes(op.row)].join(\" OR \");\n\t\t\tcase \"patch\": return [`NOT ${exists(op.key, op.guard.v)}`, ...clashes({\n\t\t\t\t...op.previous,\n\t\t\t\t...op.set\n\t\t\t}, op.key, Object.keys(op.set))].join(\" OR \");\n\t\t\tdefault: return `NOT ${exists(op.key, op.guard?.v)}`;\n\t\t}\n\t};\n\t/**\n\t* A write as one atomic batch, for drivers without interactive transactions:\n\t* each op's guard, against the rows before any change, records the first\n\t* failing op in a guard row; every change applies only when none failed; the\n\t* last two statements read the failure and remove the row. Unique fields are\n\t* checked ahead, since a batch cannot name the statement a constraint stopped.\n\t*/\n\tconst batchWrite = (ops, id) => {\n\t\tconst guard = tableOf(WRITE_GUARD_TABLE);\n\t\tconst [idColumn, failed] = [\"id\", \"failed_op\"].map(quote);\n\t\tconst byId = (bind) => `${idColumn} = ${bind(id)}`;\n\t\tconst released = (table) => ops.flatMap((op) => (op.type === \"delete\" || op.type === \"patch\") && op.table.name === table ? [op.key] : []);\n\t\tconst when = (bind) => `(SELECT ${failed} FROM ${guard} WHERE ${byId(bind)}) IS NULL`;\n\t\treturn [\n\t\t\tsql((bind) => `INSERT INTO ${guard} (${idColumn}, ${failed}) VALUES (${bind(id)}, NULL)`),\n\t\t\t...ops.flatMap((op, position) => upserts(op) ? [] : [sql((bind) => `UPDATE ${guard} SET ${failed} = ${position} WHERE ${failed} IS NULL AND (${failure(bind, op, released(op.table.name))}) AND ${byId(bind)}`)]),\n\t\t\t...ops.flatMap((op) => compile(op, when)),\n\t\t\tsql((bind) => `SELECT ${failed} FROM ${guard} WHERE ${byId(bind)}`),\n\t\t\tsql((bind) => `DELETE FROM ${guard} WHERE ${byId(bind)}`)\n\t\t];\n\t};\n\t/** Runs a read and converts its rows to stored values. */\n\tconst read = async (table, statement) => {\n\t\tconst { rows } = await executor.execute(statement);\n\t\treturn rows.map((row) => normalizeStoredRow(table, row, { jsonText: sqlite }));\n\t};\n\treturn {\n\t\tid: `sql:${dialect}`,\n\t\tfits: (ops) => ops.length <= maxOps,\n\t\tasync get(table, keys) {\n\t\t\tconst size = Math.max(1, Math.floor(maxParams / table.key.length));\n\t\t\tconst found = /* @__PURE__ */ new Map();\n\t\t\tfor (let start = 0; start < keys.length; start += size) {\n\t\t\t\tconst chunk = keys.slice(start, start + size);\n\t\t\t\tconst statement = sql((bind) => {\n\t\t\t\t\tconst where = chunk.map((key) => `(${keyMatch(bind, table, key)})`);\n\t\t\t\t\treturn `SELECT * FROM ${tableOf(table)} WHERE ${where.join(\" OR \")}`;\n\t\t\t\t});\n\t\t\t\tfor (const row of await read(table, statement)) found.set(JSON.stringify(rowKey(table, row)), row);\n\t\t\t}\n\t\t\treturn keys.map((key) => found.get(JSON.stringify(key)) ?? null);\n\t\t},\n\t\tasync query(table, request) {\n\t\t\tconst index = findPhysicalIndex(table, request.index);\n\t\t\tif (!Number.isSafeInteger(request.limit) || request.limit < 1) throw new RangeError(\"query limit must be a positive integer.\");\n\t\t\tconst order = indexOrderColumns(table, index);\n\t\t\tconst multi = isMultiIndex(table, index);\n\t\t\tconst source = multi ? `${tableOf(table, index)} i JOIN ${tableOf(table)} b ON ${table.key.map((column) => `b.${quote(column)} = i.${quote(column)}`).join(\" AND \")}` : `${tableOf(table)} i`;\n\t\t\tconst direction = request.order === \"asc\" ? \"ASC\" : \"DESC\";\n\t\t\tconst statement = sql((bind) => {\n\t\t\t\tconst conditions = [\n\t\t\t\t\t...index.eq.map((column, position) => `i.${quote(column)} = ${bind(request.eq[position])}`),\n\t\t\t\t\t...request.lower ? [compare(bind, order, request.lower, \">\")] : [],\n\t\t\t\t\t...request.upper ? [compare(bind, order, request.upper, \"<\")] : []\n\t\t\t\t];\n\t\t\t\treturn `SELECT ${multi ? \"b\" : \"i\"}.* FROM ${source}${conditions.length > 0 ? ` WHERE ${conditions.join(\" AND \")}` : \"\"} ORDER BY ${order.map((column) => `i.${quote(column)} ${direction}`).join(\", \")} LIMIT ${request.limit}`;\n\t\t\t});\n\t\t\treturn read(table, statement);\n\t\t},\n\t\tasync write(ops) {\n\t\t\ttry {\n\t\t\t\tif (executor.batch) {\n\t\t\t\t\tconst statements = batchWrite(ops, crypto.randomUUID());\n\t\t\t\t\tconst failed = (await executor.batch(statements)).at(-2)?.rows[0]?.failed_op ?? null;\n\t\t\t\t\treturn failed === null ? { ok: true } : {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\tfailedOp: Number(failed)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tawait executor.transaction(async (connection) => {\n\t\t\t\t\tfor (const [position, op] of ops.entries()) {\n\t\t\t\t\t\tconst [first, ...rest] = compile(op);\n\t\t\t\t\t\tlet result;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresult = await connection.execute(first);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (classifySqlError(error) === \"constraint\") throw new FailedOp(position);\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!(op.type === \"check\" ? result.rows.length === 1 && Number(result.rows[0][\"_v\"]) === op.guard.v : op.type === \"insert\" || upserts(op) || result.changes === 1)) throw new FailedOp(position);\n\t\t\t\t\t\tfor (const statement of rest) await connection.execute(statement);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { ok: true };\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof FailedOp) return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailedOp: error.index\n\t\t\t\t};\n\t\t\t\tconst kind = classifySqlError(error);\n\t\t\t\tif (kind === \"retry\") return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tretry: true\n\t\t\t\t};\n\t\t\t\tif (kind === \"constraint\" && executor.batch) return {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailedOp: 0\n\t\t\t\t};\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\tasync prune(table, before, limit) {\n\t\t\tconst statements = pruneStatements(dialect, table, tablePrefix, limit).map((render) => sql((bind) => render(() => bind(before))));\n\t\t\treturn (executor.batch ? await executor.batch(statements) : await executor.transaction(async (connection) => {\n\t\t\t\tconst done = [];\n\t\t\t\tfor (const statement of statements) done.push(await connection.execute(statement));\n\t\t\t\treturn done;\n\t\t\t})).at(-1)?.changes ?? 0;\n\t\t},\n\t\tmigrations: { async apply(tables) {\n\t\t\tconst created = executor.batch && !tables.includes(WRITE_GUARD_TABLE) ? [...tables, WRITE_GUARD_TABLE] : tables;\n\t\t\tconst statements = createTableStatements(dialect, created, tablePrefix);\n\t\t\tfor (const text of statements) await executor.execute({\n\t\t\t\tsql: text,\n\t\t\t\tparams: []\n\t\t\t});\n\t\t} }\n\t};\n};\n//#endregion\nexport { WRITE_GUARD_TABLE, classifySqlError, createSqlAdapter };\n", "//#region package.json\nvar version = \"1.0.3\";\n//#endregion\nexport { version };\n", "import { version } from \"./package.mjs\";\n//#region src/version.ts\nconst HOT_UPDATER_SERVER_VERSION = version;\n//#endregion\nexport { HOT_UPDATER_SERVER_VERSION };\n", "import { HOT_UPDATER_SERVER_VERSION } from \"./version.mjs\";\n//#region src/handlerVersionRoutes.ts\nconst HOT_UPDATER_INFRASTRUCTURE_GENERATION = 1;\n/**\n* `/version` on both mounts. The admin mount also lists the ids of the\n* plugins the server runs, sorted; apps never learn which plugins a server\n* runs.\n*/\nconst createVersionRouteHandlers = (plugins = []) => {\n\tconst version = {\n\t\tadminProtocol: 2,\n\t\tinfrastructureGeneration: 1,\n\t\tversion: HOT_UPDATER_SERVER_VERSION\n\t};\n\tconst adminVersion = {\n\t\t...version,\n\t\tplugins: [...plugins].sort()\n\t};\n\treturn {\n\t\tversion: async () => Response.json(version),\n\t\tadminVersion: async () => Response.json(adminVersion)\n\t};\n};\n//#endregion\nexport { HOT_UPDATER_INFRASTRUCTURE_GENERATION, createVersionRouteHandlers };\n", "import { HotUpdaterConfigError } from \"../assembly/configError.mjs\";\n//#region src/plugins/official.ts\n/**\n* The brand Hot Updater's own plugin factories set. It is a registered\n* symbol, not a module-private one, so a plugin made by one package's ESM\n* build still carries it when another's CommonJS build reads it, as a config\n* loaded through `require` may; no plugin sets it by accident. Each official\n* plugin package sets it with a copy of its own, so no package imports\n* another's internals for it. It guards Hot Updater's ids against a\n* clash, not against a determined impostor.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/**\n* The ids of Hot Updater's own plugins. The console and tooling tell\n* features apart by plugin id, so no other plugin may take one.\n*/\nconst OFFICIAL_IDS = /* @__PURE__ */ new Set([\n\t\"insights\",\n\t\"apiKeys\",\n\t\"remoteConfig\"\n]);\n/** Whether one of Hot Updater's own factories made `plugin`. */\nconst isOfficialPlugin = (plugin) => typeof plugin === \"object\" && plugin !== null && Reflect.get(plugin, OFFICIAL) === true;\n/**\n* Refuses a plugin that takes one of Hot Updater's own ids without being\n* that plugin: `at` names it in the error, such as `plugins[0]`.\n*/\nconst checkReservedId = (plugin, at) => {\n\tconst id = typeof plugin === \"object\" && plugin !== null ? Reflect.get(plugin, \"id\") : void 0;\n\tif (typeof id === \"string\" && OFFICIAL_IDS.has(id) && !isOfficialPlugin(plugin)) throw new HotUpdaterConfigError(`${at} takes the id \"${id}\", which is reserved for Hot Updater's ${id}() plugin; give this plugin another id.`);\n};\n//#endregion\nexport { checkReservedId, isOfficialPlugin };\n", "import { HotUpdaterConfigError } from \"./configError.mjs\";\nimport { checkReservedId } from \"../plugins/official.mjs\";\n//#region src/assembly/clientPlugins.ts\nconst EXPORT_NAME = /^[A-Za-z_$][\\w$]*$/u;\n/**\n* Names app code cannot import as they are: reserved words, and the names\n* the printed app code declares itself.\n*/\nconst UNAVAILABLE_NAMES = /* @__PURE__ */ new Set([\n\t\"App\",\n\t\"HotUpdater\",\n\t\"arguments\",\n\t\"await\",\n\t\"break\",\n\t\"case\",\n\t\"catch\",\n\t\"class\",\n\t\"const\",\n\t\"continue\",\n\t\"debugger\",\n\t\"default\",\n\t\"delete\",\n\t\"do\",\n\t\"else\",\n\t\"enum\",\n\t\"eval\",\n\t\"export\",\n\t\"extends\",\n\t\"false\",\n\t\"finally\",\n\t\"for\",\n\t\"function\",\n\t\"if\",\n\t\"implements\",\n\t\"import\",\n\t\"in\",\n\t\"instanceof\",\n\t\"interface\",\n\t\"let\",\n\t\"new\",\n\t\"null\",\n\t\"package\",\n\t\"private\",\n\t\"protected\",\n\t\"public\",\n\t\"return\",\n\t\"static\",\n\t\"super\",\n\t\"switch\",\n\t\"this\",\n\t\"throw\",\n\t\"true\",\n\t\"try\",\n\t\"typeof\",\n\t\"var\",\n\t\"void\",\n\t\"while\",\n\t\"with\",\n\t\"yield\"\n]);\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/**\n* The client plugins an app adds for the plugins, each once, in plugin\n* order: what init prints in `HotUpdater.init`'s `plugins`. A malformed one,\n* or one name from two modules, throws `HotUpdaterConfigError`.\n*/\nconst clientPluginsOf = (plugins) => {\n\tif (!Array.isArray(plugins)) throw new HotUpdaterConfigError(\"plugins must be an array of plugins.\");\n\tconst found = [];\n\tplugins.forEach((plugin, position) => checkReservedId(plugin, `plugins[${position}]`));\n\tfor (const plugin of plugins) {\n\t\tif (!isRecord(plugin) || !isRecord(plugin.cli)) continue;\n\t\tconst value = plugin.cli.clientPlugin;\n\t\tif (value === void 0) continue;\n\t\tconst id = String(plugin.id);\n\t\tif (!isRecord(value) || typeof value.module !== \"string\" || value.module === \"\" || typeof value.name !== \"string\" || !EXPORT_NAME.test(value.name) || UNAVAILABLE_NAMES.has(value.name)) throw new HotUpdaterConfigError(`Plugin \"${id}\" cli.clientPlugin needs a module and an export name the app can import: an identifier other than a reserved word, App, or HotUpdater.`);\n\t\tconst { module, name } = value;\n\t\tconst named = found.find((entry) => entry.name === name);\n\t\tif (named === void 0) found.push({\n\t\t\tmodule,\n\t\t\tname\n\t\t});\n\t\telse if (named.module !== module) throw new HotUpdaterConfigError(`Plugin \"${id}\" names the client plugin \"${name}\" from ${module}, but another plugin names it from ${named.module}.`);\n\t}\n\treturn found;\n};\n//#endregion\nexport { clientPluginsOf };\n", "import { projectCompiledCatalog, projectCompiledRollbackCatalog } from \"@hot-updater/plugin-core\";\nimport { RELEASE_CATALOG_FALLBACK_POLICY, RELEASE_CATALOG_SCHEMA_VERSION, createReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/db/releaseCatalog.ts\n/** A stored catalog payload, checked against its strategy's shape. */\nconst parseCompiledCatalog = (payload, strategy) => {\n\tconst parsed = JSON.parse(payload);\n\tif (typeof parsed !== \"object\" || parsed === null || Reflect.get(parsed, \"schemaVersion\") !== RELEASE_CATALOG_SCHEMA_VERSION || Reflect.get(parsed, \"strategy\") !== strategy || Reflect.get(parsed, \"fallbackPolicy\") !== RELEASE_CATALOG_FALLBACK_POLICY || !Array.isArray(Reflect.get(parsed, \"releaseDescriptors\"))) throw new Error(\"Stored Release catalog payload is invalid\");\n\tif (strategy === \"APP_VERSION\" && !Array.isArray(Reflect.get(parsed, \"segments\"))) throw new Error(\"Stored app-version Release catalog is invalid\");\n\tif (strategy === \"FINGERPRINT\" && !Array.isArray(Reflect.get(parsed, \"releaseIndexes\"))) throw new Error(\"Stored fingerprint Release catalog is invalid\");\n\treturn parsed;\n};\n/** The scope key an update check reads. */\nconst releaseCatalogScopeKeyOf = (input) => input.strategy === \"APP_VERSION\" ? createReleaseCatalogScopeKey({\n\tchannelKey: input.channelKey,\n\tplatform: input.platform,\n\tstrategy: \"APP_VERSION\"\n}) : createReleaseCatalogScopeKey({\n\tchannelKey: input.channelKey,\n\tfingerprintHash: input.fingerprintHash,\n\tplatform: input.platform,\n\tstrategy: \"FINGERPRINT\"\n});\n/** Projects a stored catalog row for one update check; null when the row is not this scope's. */\nconst projectReleaseCatalogRow = (row, input, scopeKey = releaseCatalogScopeKeyOf(input)) => {\n\tif (row === null || row.platform !== input.platform || row.strategy !== input.strategy || row.channel_key !== input.channelKey || row.scope_key !== scopeKey || row.fingerprint_hash !== (input.strategy === \"FINGERPRINT\" ? input.fingerprintHash : null)) return null;\n\tconst compiled = parseCompiledCatalog(row.payload, input.strategy);\n\tconst appVersion = input.strategy === \"APP_VERSION\" ? input.appVersion : void 0;\n\treturn {\n\t\tcatalogId: row.catalog_id,\n\t\tcatalogHash: row.catalog_hash,\n\t\tfallbackPolicy: RELEASE_CATALOG_FALLBACK_POLICY,\n\t\tgeneration: row.generation,\n\t\treleases: projectCompiledCatalog(compiled, appVersion),\n\t\trollbackReleases: projectCompiledRollbackCatalog(compiled, appVersion),\n\t\tschemaVersion: RELEASE_CATALOG_SCHEMA_VERSION,\n\t\tscopeKey\n\t};\n};\n//#endregion\nexport { parseCompiledCatalog, projectReleaseCatalogRow, releaseCatalogScopeKeyOf };\n", "import { getBundleArchiveStorageUri, getManifestAssetDownloadPath, isContentAddressedAssetFileHash, resolveManifestAssetStorageUri } from \"@hot-updater/plugin-core\";\nimport { ARTIFACT_PROTOCOL_VERSION, getAssetBaseStorageUri, getBundlePatch, getManifestFileHash, getManifestStorageUri } from \"@hot-updater/protocol\";\n//#region src/db/updateArtifacts.ts\nconst HBC_ASSET_PATH_RE = /\\.bundle$/;\nconst asByteSize = (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : null;\nconst resolveUniqueHbcAssetPath = (manifest) => {\n\tconst candidates = Object.keys(manifest.assets).sort((left, right) => left.localeCompare(right)).filter((candidate) => HBC_ASSET_PATH_RE.test(candidate));\n\treturn candidates.length === 1 ? candidates[0] : null;\n};\nconst isBundleManifest = (value) => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst manifest = value;\n\tif (typeof manifest.bundleId !== \"string\") return false;\n\tif (!manifest.assets || typeof manifest.assets !== \"object\") return false;\n\treturn Object.values(manifest.assets).every((asset) => {\n\t\tif (!asset || typeof asset !== \"object\" || Array.isArray(asset)) return false;\n\t\tconst manifestAsset = asset;\n\t\treturn typeof manifestAsset.fileHash === \"string\" && (manifestAsset.signature === void 0 || typeof manifestAsset.signature === \"string\");\n\t});\n};\nasync function fetchBundleManifest(storageUri, readStorageText) {\n\tconst storageText = await readStorageText(storageUri);\n\tif (storageText === null) return null;\n\tlet payload;\n\ttry {\n\t\tpayload = JSON.parse(storageText);\n\t} catch {\n\t\treturn null;\n\t}\n\tif (!isBundleManifest(payload)) return null;\n\treturn payload;\n}\nfunction resolveHbcPatchPlan({ currentBundle, targetBundle, targetManifest }) {\n\tconst matchingPatch = currentBundle ? getBundlePatch(targetBundle, currentBundle.id) : null;\n\tconst patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);\n\tif (!currentBundle || !matchingPatch || !patchAssetPath || !matchingPatch.patchStorageUri || !matchingPatch.patchFileHash || !matchingPatch.baseFileHash) return null;\n\treturn {\n\t\tassetPath: patchAssetPath,\n\t\tpatch: {\n\t\t\tbaseBundleId: matchingPatch.baseBundleId,\n\t\t\tbaseFileHash: matchingPatch.baseFileHash,\n\t\t\tbyteSize: asByteSize(matchingPatch.byteSize),\n\t\t\tpatchFileHash: matchingPatch.patchFileHash,\n\t\t\tstorageUri: matchingPatch.patchStorageUri\n\t\t}\n\t};\n}\nfunction createManifestArtifactPlan({ assetBaseStorageUri, currentBundle, targetBundle, targetManifest }) {\n\tconst patchCandidate = resolveHbcPatchPlan({\n\t\tcurrentBundle,\n\t\ttargetBundle,\n\t\ttargetManifest\n\t});\n\treturn { assets: Object.entries(targetManifest.assets).map(([assetPath, asset]) => {\n\t\tconst downloadByteSize = asByteSize(asset.downloadByteSize);\n\t\tconst downloadPath = getManifestAssetDownloadPath(assetPath);\n\t\tconst isTransformedDownload = downloadPath !== assetPath;\n\t\tconst hasValidDownloadFileHash = isContentAddressedAssetFileHash(asset.downloadFileHash);\n\t\tconst file = {\n\t\t\tbyteSize: downloadByteSize !== null && (hasValidDownloadFileHash || !isTransformedDownload && asset.downloadFileHash === void 0) ? downloadByteSize : null,\n\t\t\tstorageUri: resolveManifestAssetStorageUri({\n\t\t\t\tassetBaseStorageUri,\n\t\t\t\tassetPath: downloadPath,\n\t\t\t\tdownloadFileHash: asset.downloadFileHash,\n\t\t\t\tfileHash: asset.fileHash\n\t\t\t})\n\t\t};\n\t\tif (isTransformedDownload) file.compression = \"br\";\n\t\tconst patch = patchCandidate?.assetPath === assetPath ? patchCandidate.patch : null;\n\t\treturn {\n\t\t\tassetPath,\n\t\t\tfile,\n\t\t\tfileHash: asset.fileHash,\n\t\t\tpatch\n\t\t};\n\t}) };\n}\nasync function resolveAssets(plan, resolveFileUrl) {\n\tconst patchAsset = plan.assets.find((asset) => asset.patch !== null);\n\tlet resolvedPatch = null;\n\tif (patchAsset?.patch) {\n\t\tconst patchUrl = await resolveFileUrl(patchAsset.patch.storageUri);\n\t\tif (patchUrl) resolvedPatch = {\n\t\t\tassetPath: patchAsset.assetPath,\n\t\t\tpatch: {\n\t\t\t\talgorithm: \"bsdiff\",\n\t\t\t\tbaseBundleId: patchAsset.patch.baseBundleId,\n\t\t\t\tbaseFileHash: patchAsset.patch.baseFileHash,\n\t\t\t\tpatchFileHash: patchAsset.patch.patchFileHash,\n\t\t\t\tpatchUrl,\n\t\t\t\t...patchAsset.patch.byteSize === null ? {} : { byteSize: patchAsset.patch.byteSize }\n\t\t\t}\n\t\t};\n\t}\n\tconst entries = await Promise.all(plan.assets.map(async (asset) => {\n\t\tlet patch = resolvedPatch?.assetPath === asset.assetPath ? resolvedPatch.patch : null;\n\t\tlet fileUrl = null;\n\t\ttry {\n\t\t\tfileUrl = await resolveFileUrl(asset.file.storageUri);\n\t\t} catch (error) {\n\t\t\tif (!patch) throw error;\n\t\t}\n\t\tif (fileUrl && patch && asset.file.byteSize !== null && asset.patch !== null && asset.patch.byteSize !== null && asset.patch.byteSize >= asset.file.byteSize) patch = null;\n\t\tif (!fileUrl) return null;\n\t\tconst changedAsset = {\n\t\t\tfile: { url: fileUrl },\n\t\t\tfileHash: asset.fileHash\n\t\t};\n\t\tif (asset.file.compression) changedAsset.file.compression = asset.file.compression;\n\t\tif (patch) changedAsset.patch = patch;\n\t\treturn { asset: [asset.assetPath, changedAsset] };\n\t}));\n\tif (entries.some((entry) => entry === null)) return null;\n\tconst resolvedEntries = entries.filter((entry) => entry !== null);\n\treturn { assets: Object.fromEntries(resolvedEntries.map((entry) => entry.asset)) };\n}\nasync function resolveManifestArtifacts({ currentBundle, resolveFileUrl, readStorageText, targetBundle }) {\n\tconst manifestStorageUri = targetBundle ? getManifestStorageUri(targetBundle) : null;\n\tconst manifestFileHash = targetBundle ? getManifestFileHash(targetBundle) : null;\n\tconst assetBaseStorageUri = targetBundle ? getAssetBaseStorageUri(targetBundle) : null;\n\tif (!targetBundle || !manifestStorageUri || !manifestFileHash || !assetBaseStorageUri) return null;\n\tconst targetManifest = await fetchBundleManifest(manifestStorageUri, readStorageText);\n\tif (!targetManifest) return null;\n\tconst plan = createManifestArtifactPlan({\n\t\tassetBaseStorageUri,\n\t\tcurrentBundle,\n\t\ttargetBundle,\n\t\ttargetManifest\n\t});\n\tconst manifestUrl = await resolveFileUrl(manifestStorageUri);\n\tif (!manifestUrl) return null;\n\tconst resolved = await resolveAssets(plan, resolveFileUrl);\n\tif (!resolved) return null;\n\tlet archiveUrl = null;\n\tconst archive = targetManifest.archive;\n\tif (archive && isContentAddressedAssetFileHash(archive.downloadFileHash) && (asByteSize(archive.downloadByteSize) ?? 0) > 0 && (asByteSize(archive.tarByteSize) ?? 0) > 0) try {\n\t\tarchiveUrl = await resolveFileUrl(getBundleArchiveStorageUri({\n\t\t\tmanifestStorageUri,\n\t\t\tbundleId: targetBundle.id\n\t\t}));\n\t} catch {}\n\treturn {\n\t\tartifactProtocolVersion: ARTIFACT_PROTOCOL_VERSION,\n\t\tassets: resolved.assets,\n\t\tmanifestFileHash,\n\t\tmanifestUrl,\n\t\t...archiveUrl ? { archiveUrl } : {}\n\t};\n}\n//#endregion\nexport { resolveManifestArtifacts };\n", "//#region src/version/constants.ts\nconst SEMVER_SPEC_VERSION = \"2.0.0\";\nconst INCREMENT_TYPES = [\n\t\"major\",\n\t\"premajor\",\n\t\"minor\",\n\t\"preminor\",\n\t\"patch\",\n\t\"prepatch\",\n\t\"prerelease\",\n\t\"release\"\n];\nconst TRUNCATION_TYPES = [\n\t\"major\",\n\t\"premajor\",\n\t\"minor\",\n\t\"preminor\",\n\t\"patch\",\n\t\"prepatch\",\n\t\"prerelease\"\n];\n//#endregion\n//#region src/version/patterns.ts\nconst LETTER_DASH_NUMBER = \"[a-zA-Z0-9-]\";\nconst NUMERIC_IDENTIFIER = String.raw`0|[1-9]\\d*`;\nconst NUMERIC_IDENTIFIER_LOOSE = String.raw`\\d+`;\nconst NON_NUMERIC_IDENTIFIER = String.raw`\\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;\nconst MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})\\.(${NUMERIC_IDENTIFIER})`;\nconst MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})\\.(${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;\nconst PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;\nconst PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*))`;\nconst PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;\nconst BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;\nconst BUILD = String.raw`(?:\\+(${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*))`;\nconst FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;\nconst LOOSE_PLAIN = String.raw`[v=\\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;\nconst GREATER_LESS_THAN = \"((?:<|>)?=?)\";\nconst XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\\*`;\nconst XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\\*`;\nconst XRANGE_PLAIN = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:\\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;\nconst XRANGE_PLAIN_LOOSE = String.raw`[v=\\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:\\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;\nconst LONE_TILDE = \"(?:~>?)\";\nconst LONE_CARET = String.raw`(?:\\^)`;\nconst COERCE_PLAIN = String.raw`(^|[^\\d])(\\d{1,${16}})(?:\\.(\\d{1,${16}}))?(?:\\.(\\d{1,${16}}))?`;\nconst COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\\d])`;\nconst COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\\d])`;\nfunction makeSafeRegexSource(source) {\n\tconst replacements = [\n\t\t[String.raw`\\s`, 1],\n\t\t[String.raw`\\d`, 256],\n\t\t[LETTER_DASH_NUMBER, 250]\n\t];\n\tfor (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);\n\treturn source;\n}\nfunction safeRegex(source, flags) {\n\treturn new RegExp(makeSafeRegexSource(source), flags);\n}\n//#endregion\n//#region src/version/parse.ts\nconst FULL = safeRegex(`^${FULL_PLAIN}$`);\nconst LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);\nconst NUMERIC$1 = /^\\d+$/;\nfunction formatComparableVersion(version) {\n\tconst base = `${version.major}.${version.minor}.${version.patch}`;\n\treturn version.prerelease?.length ? `${base}-${version.prerelease.join(\".\")}` : base;\n}\nfunction formatFullVersion(version) {\n\tconst comparable = formatComparableVersion(version);\n\treturn version.build?.length ? `${comparable}+${version.build.join(\".\")}` : comparable;\n}\nfunction parse(version, options = {}) {\n\tif (typeof version !== \"string\") return version;\n\tif (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);\n\tconst match = version.trim().match(options.loose ? LOOSE : FULL);\n\tif (!match) throw new TypeError(`Invalid version syntax: ${version}`);\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\tconst patch = Number(match[3]);\n\tif (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);\n\tif (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);\n\tif (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);\n\tconst prerelease = match[4] ? match[4].split(\".\").map((identifier) => {\n\t\tif (NUMERIC$1.test(identifier)) {\n\t\t\tconst numeric = Number(identifier);\n\t\t\tif (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;\n\t\t}\n\t\treturn identifier;\n\t}) : void 0;\n\treturn {\n\t\tbuild: match[5]?.split(\".\"),\n\t\tmajor,\n\t\tminor,\n\t\tpatch,\n\t\tprerelease\n\t};\n}\nfunction tryParse(version, options = {}) {\n\ttry {\n\t\treturn parse(version, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region src/version/identifiers.ts\nconst NUMERIC = /^\\d+$/;\nfunction compareIdentifiers(left, right) {\n\tif (typeof left === \"number\" && typeof right === \"number\") return left === right ? 0 : left < right ? -1 : 1;\n\tconst leftNumeric = NUMERIC.test(String(left));\n\tconst rightNumeric = NUMERIC.test(String(right));\n\tconst normalizedLeft = leftNumeric ? Number(left) : left;\n\tconst normalizedRight = rightNumeric ? Number(right) : right;\n\treturn normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;\n}\nfunction compareIdentifiersReversed(left, right) {\n\treturn compareIdentifiers(right, left);\n}\n//#endregion\n//#region src/version/comparison.ts\nfunction compareMainParsed(left, right) {\n\treturn left.major === right.major ? left.minor === right.minor ? left.patch === right.patch ? 0 : left.patch < right.patch ? -1 : 1 : left.minor < right.minor ? -1 : 1 : left.major < right.major ? -1 : 1;\n}\nfunction comparePrereleaseParsed(left, right) {\n\tconst leftPrerelease = left.prerelease;\n\tconst rightPrerelease = right.prerelease;\n\tif (leftPrerelease?.length && !rightPrerelease?.length) return -1;\n\tif (!leftPrerelease?.length && rightPrerelease?.length) return 1;\n\tif (!leftPrerelease?.length && !rightPrerelease?.length) return 0;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = leftPrerelease?.[index];\n\t\tconst rightIdentifier = rightPrerelease?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compareParsed(left, right) {\n\treturn compareMainParsed(left, right) || comparePrereleaseParsed(left, right);\n}\nfunction compareBuildParsed(left, right) {\n\tconst precedence = compareParsed(left, right);\n\tif (precedence !== 0) return precedence;\n\tfor (let index = 0;; index++) {\n\t\tconst leftIdentifier = left.build?.[index];\n\t\tconst rightIdentifier = right.build?.[index];\n\t\tif (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;\n\t\tif (rightIdentifier === void 0) return 1;\n\t\tif (leftIdentifier === void 0) return -1;\n\t\tif (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);\n\t}\n}\nfunction compare(left, right, options = {}) {\n\treturn compareParsed(parse(left, options), parse(right, options));\n}\nfunction compareReversed(left, right, options = {}) {\n\treturn compare(right, left, options);\n}\nfunction compareMain(left, right, options = {}) {\n\treturn compareMainParsed(parse(left, options), parse(right, options));\n}\nfunction comparePrerelease(left, right, options = {}) {\n\treturn comparePrereleaseParsed(parse(left, options), parse(right, options));\n}\nfunction compareBuild(left, right, options = {}) {\n\treturn compareBuildParsed(parse(left, options), parse(right, options));\n}\nfunction compareWithOperator(left, operator, right, options = {}) {\n\tif (operator === \"===\") return left === right;\n\tif (operator === \"!==\") return left !== right;\n\tconst comparison = compare(left, right, options);\n\tswitch (operator) {\n\t\tcase \"\":\n\t\tcase \"=\":\n\t\tcase \"==\": return comparison === 0;\n\t\tcase \"!=\": return comparison !== 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t\tdefault: throw new TypeError(`Invalid operator: ${operator}`);\n\t}\n}\nfunction isEqual(left, right, options = {}) {\n\treturn compare(left, right, options) === 0;\n}\nfunction isNotEqual(left, right, options = {}) {\n\treturn compare(left, right, options) !== 0;\n}\nfunction isGreater(left, right, options = {}) {\n\treturn compare(left, right, options) > 0;\n}\nfunction isGreaterOrEqual(left, right, options = {}) {\n\treturn compare(left, right, options) >= 0;\n}\nfunction isLess(left, right, options = {}) {\n\treturn compare(left, right, options) < 0;\n}\nfunction isLessOrEqual(left, right, options = {}) {\n\treturn compare(left, right, options) <= 0;\n}\nfunction sort(versions, options = {}) {\n\treturn [...versions].sort((left, right) => compareBuild(left, right, options));\n}\nfunction sortReversed(versions, options = {}) {\n\treturn [...versions].sort((left, right) => compareBuild(right, left, options));\n}\n//#endregion\nexport { LOOSE_PLAIN as A, BUILD as C, GREATER_LESS_THAN as D, FULL_PLAIN as E, safeRegex as F, INCREMENT_TYPES as I, SEMVER_SPEC_VERSION as L, PRERELEASE_LOOSE as M, XRANGE_PLAIN as N, LONE_CARET as O, XRANGE_PLAIN_LOOSE as P, TRUNCATION_TYPES as R, tryParse as S, COERCE_FULL as T, compareIdentifiers as _, compareParsed as a, formatFullVersion as b, compareWithOperator as c, isGreaterOrEqual as d, isLess as f, sortReversed as g, sort as h, compareMainParsed as i, PRERELEASE as j, LONE_TILDE as k, isEqual as l, isNotEqual as m, compareBuild as n, comparePrerelease as o, isLessOrEqual as p, compareMain as r, compareReversed as s, compare as t, isGreater as u, compareIdentifiersReversed as v, COERCE as w, parse as x, formatComparableVersion as y };\n", "import { A as LOOSE_PLAIN, D as GREATER_LESS_THAN, E as FULL_PLAIN, F as safeRegex, S as tryParse, a as compareParsed, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.js\";\n//#region src/comparator/parse.ts\nconst STRICT_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${FULL_PLAIN})$|^$`);\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction formatComparator(comparator) {\n\treturn comparator.version ? `${comparator.operator}${formatComparableVersion(comparator.version)}` : \"\";\n}\nfunction parseComparator(comparator, options = {}) {\n\tif (typeof comparator !== \"string\") return comparator;\n\tconst normalized = comparator.trim().replaceAll(/\\s+/g, \" \");\n\tconst match = normalized.match(options.loose ? LOOSE_COMPARATOR : STRICT_COMPARATOR);\n\tif (!match) throw new TypeError(`Invalid comparator: ${normalized}`);\n\tconst operator = match[1] === \"=\" ? \"\" : match[1] || \"\";\n\tconst version = match[2] ? parse(match[2], options) : null;\n\treturn {\n\t\toperator,\n\t\toptions,\n\t\tvalue: version ? `${operator}${formatComparableVersion(version)}` : \"\",\n\t\tversion\n\t};\n}\nfunction tryParseComparator(comparator, options = {}) {\n\ttry {\n\t\treturn typeof comparator === \"string\" ? parseComparator(comparator, options) : comparator;\n\t} catch {\n\t\treturn null;\n\t}\n}\n//#endregion\n//#region src/comparator/set.ts\nfunction testParsedComparator(comparator, version) {\n\tif (!comparator.version) return true;\n\tconst comparison = compareParsed(version, comparator.version);\n\tswitch (comparator.operator) {\n\t\tcase \"\": return comparison === 0;\n\t\tcase \">\": return comparison > 0;\n\t\tcase \">=\": return comparison >= 0;\n\t\tcase \"<\": return comparison < 0;\n\t\tcase \"<=\": return comparison <= 0;\n\t}\n}\nfunction testComparatorVersion(comparator, version) {\n\tconst parsed = tryParse(version, comparator.options);\n\treturn parsed ? testParsedComparator(comparator, parsed) : false;\n}\nfunction comparatorAllowsPrerelease(comparator, version) {\n\tconst allowed = comparator.version;\n\treturn allowed !== null && !!allowed.prerelease?.length && allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch;\n}\nfunction testComparatorSet(set, version, options) {\n\tif (set.some((comparator) => !testParsedComparator(comparator, version))) return false;\n\treturn !version.prerelease?.length || !!options.includePrerelease || set.some((comparator) => comparatorAllowsPrerelease(comparator, version));\n}\nfunction parsedComparatorsIntersect(left, right, options = {}) {\n\tif (!left.version || !right.version) return true;\n\tif (left.operator === \"\") return testComparatorSet([right], left.version, options);\n\tif (right.operator === \"\") return testComparatorSet([left], right.version, options);\n\tconst leftValue = formatComparator(left);\n\tconst rightValue = formatComparator(right);\n\tif (options.includePrerelease && (leftValue === \"<0.0.0-0\" || rightValue === \"<0.0.0-0\")) return false;\n\tif (!options.includePrerelease && (leftValue.startsWith(\"<0.0.0\") || rightValue.startsWith(\"<0.0.0\"))) return false;\n\tif (left.operator.startsWith(\">\") && right.operator.startsWith(\">\")) return true;\n\tif (left.operator.startsWith(\"<\") && right.operator.startsWith(\"<\")) return true;\n\tconst comparison = compareParsed(left.version, right.version);\n\tif (comparison === 0 && left.operator.includes(\"=\") && right.operator.includes(\"=\")) return true;\n\tif (comparison < 0 && left.operator.startsWith(\">\") && right.operator.startsWith(\"<\")) return true;\n\treturn comparison > 0 && left.operator.startsWith(\"<\") && right.operator.startsWith(\">\");\n}\n//#endregion\nexport { testParsedComparator as a, tryParseComparator as c, testComparatorVersion as i, parsedComparatorsIntersect as n, formatComparator as o, testComparatorSet as r, parseComparator as s, comparatorAllowsPrerelease as t };\n", "import { A as LOOSE_PLAIN, C as BUILD, D as GREATER_LESS_THAN, F as safeRegex, N as XRANGE_PLAIN, O as LONE_CARET, P as XRANGE_PLAIN_LOOSE, S as tryParse, a as compareParsed, h as sort, k as LONE_TILDE, x as parse, y as formatComparableVersion } from \"./comparison-DenM3wCn.js\";\nimport { a as testParsedComparator, n as parsedComparatorsIntersect, o as formatComparator, r as testComparatorSet, s as parseComparator, t as comparatorAllowsPrerelease } from \"./set-CC5YeoYX.js\";\n//#region src/range/parse.ts\nfunction formatRange(range) {\n\treturn range.sets.map((set) => set.map(formatComparator).join(\" \")).join(\"||\");\n}\nconst BUILD_STRIP = new RegExp(BUILD, \"g\");\nconst BUILD_SAFE = safeRegex(BUILD);\nconst STRICT_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN})\\s+-\\s+(${XRANGE_PLAIN})\\s*$`);\nconst LOOSE_HYPHEN = safeRegex(String.raw`^\\s*(${XRANGE_PLAIN_LOOSE})\\s+-\\s+(${XRANGE_PLAIN_LOOSE})\\s*$`);\nconst COMPARATOR_TRIM = safeRegex(String.raw`(\\s*)${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN}|${XRANGE_PLAIN})`, \"g\");\nconst TILDE_TRIM = safeRegex(String.raw`(\\s*)${LONE_TILDE}\\s+`, \"g\");\nconst CARET_TRIM = safeRegex(String.raw`(\\s*)${LONE_CARET}\\s+`, \"g\");\nconst STRICT_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN}$`);\nconst LOOSE_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN}$`);\nconst LOOSE_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN_LOOSE}$`);\nconst STRICT_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN}$`);\nconst LOOSE_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*${XRANGE_PLAIN_LOOSE}$`);\nconst STAR = safeRegex(String.raw`(<|>)?=?\\s*\\*`);\nconst GTE_ZERO = /^\\s*>=\\s*0\\.0\\.0\\s*$/;\nconst GTE_ZERO_PRERELEASE = /^\\s*>=\\s*0\\.0\\.0-0\\s*$/;\nconst LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\\s*(${LOOSE_PLAIN})$|^$`);\nfunction isWildcard(value) {\n\treturn !value || String(value).toLowerCase() === \"x\" || String(value) === \"*\";\n}\nfunction hasInvalidWildcardOrder(major, minor, patch) {\n\treturn isWildcard(major) && !isWildcard(minor) || isWildcard(minor) && Boolean(patch) && !isWildcard(patch);\n}\nfunction replaceTilde(comparator, options) {\n\tconst expression = options.loose ? LOOSE_TILDE : STRICT_TILDE;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn prerelease ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;\n\t});\n}\nfunction replaceTildes(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceTilde(part, options)).join(\" \");\n}\nfunction replaceCaret(comparator, options) {\n\tconst expression = options.loose ? LOOSE_CARET : STRICT_CARET;\n\tconst lowerPrerelease = options.includePrerelease ? \"-0\" : \"\";\n\treturn comparator.replace(expression, (_match, major, minor, patch, prerelease) => {\n\t\tif (isWildcard(major)) return \"\";\n\t\tif (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (isWildcard(patch)) return major === \"0\" ? `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (prerelease) return major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch}-${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\treturn major === \"0\" ? minor === \"0\" ? `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;\n\t});\n}\nfunction replaceCarets(comparator, options) {\n\treturn comparator.trim().split(/\\s+/).map((part) => replaceCaret(part, options)).join(\" \");\n}\nfunction replaceXRange(comparator, options) {\n\tconst expression = options.loose ? LOOSE_XRANGE : STRICT_XRANGE;\n\treturn comparator.trim().replace(expression, (match, rawOperator, rawMajor, rawMinor, rawPatch) => {\n\t\tlet operator = rawOperator;\n\t\tlet major = rawMajor;\n\t\tlet minor = rawMinor;\n\t\tlet patch = rawPatch;\n\t\tif (hasInvalidWildcardOrder(String(major), minor === void 0 ? void 0 : String(minor), patch === void 0 ? void 0 : String(patch))) return comparator;\n\t\tconst wildcardMajor = isWildcard(major);\n\t\tconst wildcardMinor = wildcardMajor || isWildcard(minor);\n\t\tconst wildcardPatch = wildcardMinor || isWildcard(patch);\n\t\tif (operator === \"=\" && wildcardPatch) operator = \"\";\n\t\tif (wildcardMajor) return operator === \">\" || operator === \"<\" ? \"<0.0.0-0\" : \"*\";\n\t\tlet prerelease = options.includePrerelease ? \"-0\" : \"\";\n\t\tif (operator && wildcardPatch) {\n\t\t\tif (wildcardMinor) minor = 0;\n\t\t\tpatch = 0;\n\t\t\tif (operator === \">\") {\n\t\t\t\toperator = \">=\";\n\t\t\t\tif (wildcardMinor) {\n\t\t\t\t\tmajor = Number(major) + 1;\n\t\t\t\t\tminor = 0;\n\t\t\t\t} else minor = Number(minor) + 1;\n\t\t\t} else if (operator === \"<=\") {\n\t\t\t\toperator = \"<\";\n\t\t\t\tif (wildcardMinor) major = Number(major) + 1;\n\t\t\t\telse minor = Number(minor) + 1;\n\t\t\t}\n\t\t\tif (operator === \"<\") prerelease = \"-0\";\n\t\t\treturn `${operator}${major}.${minor}.${patch}${prerelease}`;\n\t\t}\n\t\tif (wildcardMinor) return `>=${major}.0.0${prerelease} <${Number(major) + 1}.0.0-0`;\n\t\tif (wildcardPatch) return `>=${major}.${minor}.0${prerelease} <${major}.${Number(minor) + 1}.0-0`;\n\t\treturn match;\n\t});\n}\nfunction replaceXRanges(comparator, options) {\n\treturn comparator.split(/\\s+/).map((part) => replaceXRange(part, options)).join(\" \");\n}\nfunction replaceHyphenRange(range, options) {\n\tconst expression = options.loose ? LOOSE_HYPHEN : STRICT_HYPHEN;\n\treturn range.replace(expression, (_match, rawFrom, fromMajor, fromMinor, fromPatch, fromPrerelease, _fromBuild, rawTo, toMajor, toMinor, toPatch, toPrerelease) => {\n\t\tlet from = rawFrom;\n\t\tlet to = rawTo;\n\t\tif (isWildcard(fromMajor)) from = \"\";\n\t\telse if (isWildcard(fromMinor)) from = `>=${fromMajor}.0.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (isWildcard(fromPatch)) from = `>=${fromMajor}.${fromMinor}.0${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\telse if (fromPrerelease) from = `>=${from}`;\n\t\telse from = `>=${from}${options.includePrerelease ? \"-0\" : \"\"}`;\n\t\tif (isWildcard(toMajor)) to = \"\";\n\t\telse if (isWildcard(toMinor)) to = `<${Number(toMajor) + 1}.0.0-0`;\n\t\telse if (isWildcard(toPatch)) to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;\n\t\telse if (toPrerelease) to = `<=${toMajor}.${toMinor}.${toPatch}-${toPrerelease}`;\n\t\telse if (options.includePrerelease) to = `<${toMajor}.${toMinor}.${Number(toPatch) + 1}-0`;\n\t\telse to = `<=${to}`;\n\t\treturn `${from} ${to}`.trim();\n\t});\n}\nfunction expandComparator(comparator, options) {\n\treturn replaceXRanges(replaceTildes(replaceCarets(comparator.replace(BUILD_SAFE, \"\"), options), options), options).trim().replace(STAR, \"\");\n}\nfunction parseSimpleRange(input, options) {\n\tlet parts = replaceHyphenRange(input.replace(BUILD_STRIP, \"\"), options).replace(COMPARATOR_TRIM, \"$1$2$3\").replace(TILDE_TRIM, \"$1~\").replace(CARET_TRIM, \"$1^\").split(\" \").map((part) => expandComparator(part, options)).join(\" \").split(/\\s+/).map((part) => part.trim().replace(options.includePrerelease ? GTE_ZERO_PRERELEASE : GTE_ZERO, \"\"));\n\tif (options.loose) parts = parts.filter((part) => LOOSE_COMPARATOR.test(part));\n\tconst unique = /* @__PURE__ */ new Map();\n\tfor (const comparator of parts.map((part) => parseComparator(part, options))) {\n\t\tif (comparator.value === \"<0.0.0-0\") return [comparator];\n\t\tunique.set(comparator.value, comparator);\n\t}\n\tif (unique.size > 1) unique.delete(\"\");\n\treturn [...unique.values()];\n}\nfunction parseRange(range, options = {}) {\n\tif (typeof range !== \"string\") return range;\n\tconst parsedOptions = { ...options };\n\tconst normalizedRange = range.trim().replaceAll(/\\s+/g, \" \");\n\tlet sets = normalizedRange.split(\"||\").map((part) => parseSimpleRange(part.trim(), parsedOptions)).filter((set) => set.length);\n\tif (!sets.length) throw new TypeError(`Range contains no valid comparator sets: ${normalizedRange}`);\n\tif (sets.length > 1) {\n\t\tconst first = sets[0];\n\t\tsets = sets.filter((set) => set[0]?.value !== \"<0.0.0-0\");\n\t\tif (!sets.length) sets = [first];\n\t\telse if (sets.length > 1) {\n\t\t\tconst any = sets.find((set) => set.length === 1 && set[0]?.value === \"\");\n\t\t\tif (any) sets = [any];\n\t\t}\n\t}\n\treturn {\n\t\toptions: parsedOptions,\n\t\tsets\n\t};\n}\nfunction tryParseRange(range, options = {}) {\n\ttry {\n\t\treturn parseRange(range, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\nfunction testParsedRange(range, version) {\n\treturn range.sets.some((set) => testComparatorSet(set, version, range.options));\n}\nfunction testRangeVersion(range, version) {\n\tconst parsed = tryParse(version, range.options);\n\treturn parsed ? testParsedRange(range, parsed) : false;\n}\nfunction exactVersion(set) {\n\tfor (const comparator of set) if (comparator.operator === \"\" && comparator.version) return comparator.version;\n\treturn null;\n}\nfunction isSatisfiable(comparators, options) {\n\tconst exact = exactVersion(comparators);\n\tif (exact) return testComparatorSet(comparators, exact, options);\n\tconst remaining = [...comparators];\n\tlet current = remaining.pop();\n\twhile (current && remaining.length) {\n\t\tif (remaining.some((other) => !parsedComparatorsIntersect(current, other, options))) return false;\n\t\tcurrent = remaining.pop();\n\t}\n\treturn true;\n}\nfunction setsIntersect(left, right, options) {\n\tconst leftExact = exactVersion(left);\n\tif (leftExact) return testComparatorSet(right, leftExact, options);\n\tconst rightExact = exactVersion(right);\n\tif (rightExact) return testComparatorSet(left, rightExact, options);\n\treturn left.every((leftComparator) => right.every((rightComparator) => parsedComparatorsIntersect(leftComparator, rightComparator, options)));\n}\nfunction parsedRangesIntersect(left, right, options = {}) {\n\treturn left.sets.some((leftSet) => isSatisfiable(leftSet, options) && right.sets.some((rightSet) => isSatisfiable(rightSet, options) && setsIntersect(leftSet, rightSet, options)));\n}\n//#endregion\n//#region src/range/operations.ts\nfunction isValidRange(range, options = {}) {\n\treturn tryParseRange(range, options) !== null;\n}\nfunction normalizeRange(range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? formatRange(parsed) || \"*\" : null;\n}\nfunction satisfies(version, range, options = {}) {\n\tconst parsed = tryParseRange(range, options);\n\treturn parsed ? testRangeVersion(parsed, version) : false;\n}\nfunction rangeToComparators(range, options = {}) {\n\treturn parseRange(range, options).sets.map((set) => set.map(formatComparator).join(\" \").trim().split(\" \"));\n}\nfunction findMaxSatisfying(versions, range, options = {}) {\n\tconst parsedRange = tryParseRange(range, options);\n\tif (!parsedRange) return null;\n\tlet maximum = null;\n\tlet maximumParsed = null;\n\tfor (const version of versions) {\n\t\tconst parsedVersion = tryParse(version, parsedRange.options);\n\t\tif (!parsedVersion || !testParsedRange(parsedRange, parsedVersion)) continue;\n\t\tif (!maximumParsed || compareParsed(maximumParsed, parsedVersion) < 0) {\n\t\t\tmaximum = version;\n\t\t\tmaximumParsed = parsedVersion;\n\t\t}\n\t}\n\treturn maximum;\n}\nfunction findMinSatisfying(versions, range, options = {}) {\n\tconst parsedRange = tryParseRange(range, options);\n\tif (!parsedRange) return null;\n\tlet minimum = null;\n\tlet minimumParsed = null;\n\tfor (const version of versions) {\n\t\tconst parsedVersion = tryParse(version, parsedRange.options);\n\t\tif (!parsedVersion || !testParsedRange(parsedRange, parsedVersion)) continue;\n\t\tif (!minimumParsed || compareParsed(minimumParsed, parsedVersion) > 0) {\n\t\t\tminimum = version;\n\t\t\tminimumParsed = parsedVersion;\n\t\t}\n\t}\n\treturn minimum;\n}\nfunction nextVersionAfter(version) {\n\tconst { prerelease } = version;\n\treturn prerelease?.length ? {\n\t\tmajor: version.major,\n\t\tminor: version.minor,\n\t\tpatch: version.patch,\n\t\tprerelease: [...prerelease, 0]\n\t} : {\n\t\tmajor: version.major,\n\t\tminor: version.minor,\n\t\tpatch: version.patch + 1\n\t};\n}\nfunction findMinimumForRange(range, options = {}) {\n\tconst parsedRange = parseRange(range, options);\n\tconst zero = {\n\t\tmajor: 0,\n\t\tminor: 0,\n\t\tpatch: 0\n\t};\n\tif (testParsedRange(parsedRange, zero)) return zero;\n\tconst zeroPrerelease = {\n\t\t...zero,\n\t\tprerelease: [0]\n\t};\n\tif (testParsedRange(parsedRange, zeroPrerelease)) return zeroPrerelease;\n\tlet minimum = null;\n\tfor (const set of parsedRange.sets) {\n\t\tlet setMinimum = null;\n\t\tfor (const comparator of set) {\n\t\t\tif (!comparator.version) continue;\n\t\t\tconst candidate = comparator.operator === \">\" ? nextVersionAfter(comparator.version) : comparator.operator === \"\" || comparator.operator === \">=\" ? structuredClone(comparator.version) : null;\n\t\t\tif (candidate && (!setMinimum || compareParsed(candidate, setMinimum) > 0)) setMinimum = candidate;\n\t\t}\n\t\tif (setMinimum && (!minimum || compareParsed(minimum, setMinimum) > 0)) minimum = setMinimum;\n\t}\n\treturn minimum && testParsedRange(parsedRange, minimum) ? minimum : null;\n}\nfunction compareInDirection(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison > 0 : comparison < 0;\n}\nfunction compareOppositeOrEqual(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison <= 0 : comparison >= 0;\n}\nfunction compareOpposite(left, right, direction) {\n\tconst comparison = compareParsed(left, right);\n\treturn direction === \">\" ? comparison < 0 : comparison > 0;\n}\nfunction isOutsideRange(version, range, direction, options = {}) {\n\tif (direction !== \">\" && direction !== \"<\") throw new TypeError(\"Must provide a direction of \\\"<\\\" or \\\">\\\"\");\n\tconst parsedRange = parseRange(range, options);\n\tconst parsedVersion = parse(version, parsedRange.options);\n\tif (testParsedRange(parsedRange, parsedVersion)) return false;\n\tconst inclusiveDirection = direction === \">\" ? \">=\" : \"<=\";\n\tfor (const set of parsedRange.sets) {\n\t\tconst concrete = set.map((comparator) => comparator.version ? comparator : parseComparator(\">=0.0.0\"));\n\t\tlet high = concrete[0];\n\t\tlet low = concrete[0];\n\t\tfor (const comparator of concrete) if (compareInDirection(comparator.version, high.version, direction)) high = comparator;\n\t\telse if (compareOpposite(comparator.version, low.version, direction)) low = comparator;\n\t\tif (high.operator === direction || high.operator === inclusiveDirection) return false;\n\t\tif ((!low.operator || low.operator === direction) && compareOppositeOrEqual(parsedVersion, low.version, direction)) return false;\n\t\tif (low.operator === inclusiveDirection && compareOpposite(parsedVersion, low.version, direction)) return false;\n\t}\n\treturn true;\n}\nfunction isGreaterThanRange(version, range, options = {}) {\n\treturn isOutsideRange(version, range, \">\", options);\n}\nfunction isLessThanRange(version, range, options = {}) {\n\treturn isOutsideRange(version, range, \"<\", options);\n}\nfunction rangesIntersect(left, right, options = {}) {\n\tconst parsedLeft = parseRange(left, options);\n\tconst parsedRight = parseRange(right, options);\n\treturn parsedRangesIntersect(parsedLeft, parsedRight, {\n\t\t...parsedLeft.options,\n\t\t...parsedRight.options,\n\t\t...options\n\t});\n}\nfunction simplifyRange(versions, range, options = {}) {\n\tconst parsedRange = parseRange(range, options);\n\tconst sorted = sort(versions, parsedRange.options);\n\tconst sets = [];\n\tlet first = null;\n\tlet previous = null;\n\tfor (const version of sorted) if (testRangeVersion(parsedRange, version)) {\n\t\tprevious = version;\n\t\tfirst ??= version;\n\t} else if (previous) {\n\t\tsets.push([first, previous]);\n\t\tfirst = null;\n\t\tprevious = null;\n\t}\n\tif (first) sets.push([first, null]);\n\tconst simplified = sets.map(([minimum, maximum]) => {\n\t\tconst minimumValue = formatComparableVersion(parse(minimum, parsedRange.options));\n\t\tconst maximumValue = maximum ? formatComparableVersion(parse(maximum, parsedRange.options)) : null;\n\t\tif (minimumValue === maximumValue) return minimumValue;\n\t\tif (!maximum && minimum === sorted[0]) return \"*\";\n\t\tif (!maximumValue) return `>=${minimumValue}`;\n\t\tif (minimum === sorted[0]) return `<=${maximumValue}`;\n\t\treturn `${minimumValue} - ${maximumValue}`;\n\t}).join(\" || \");\n\tconst original = typeof range === \"string\" ? range : formatRange(parsedRange) || \"*\";\n\treturn simplified.length < original.length ? simplified : original;\n}\n//#endregion\n//#region src/range/subset.ts\nfunction higherLowerBound(left, right) {\n\tif (!left) return right;\n\tconst comparison = compareParsed(left.version, right.version);\n\treturn comparison > 0 ? left : comparison < 0 || right.operator === \">\" && left.operator === \">=\" ? right : left;\n}\nfunction lowerUpperBound(left, right) {\n\tif (!left) return right;\n\tconst comparison = compareParsed(left.version, right.version);\n\treturn comparison < 0 ? left : comparison > 0 || right.operator === \"<\" && left.operator === \"<=\" ? right : left;\n}\nfunction simpleRangeSubset(rawSubset, rawSuperset, options) {\n\tlet subset = rawSubset;\n\tlet superset = rawSuperset;\n\tconst subsetAny = subset.length === 1 && !subset[0].version;\n\tconst supersetAny = superset.length === 1 && !superset[0].version;\n\tif (subsetAny) {\n\t\tif (supersetAny) return true;\n\t\tsubset = [parseComparator(options.includePrerelease ? \">=0.0.0-0\" : \">=0.0.0\")];\n\t}\n\tif (supersetAny) {\n\t\tif (options.includePrerelease) return true;\n\t\tsuperset = [parseComparator(\">=0.0.0\")];\n\t}\n\tconst equal = /* @__PURE__ */ new Map();\n\tlet lower;\n\tlet upper;\n\tfor (const comparator of subset) if (comparator.operator === \">\" || comparator.operator === \">=\") lower = higherLowerBound(lower, comparator);\n\telse if (comparator.operator === \"<\" || comparator.operator === \"<=\") upper = lowerUpperBound(upper, comparator);\n\telse if (comparator.version) equal.set(formatComparableVersion(comparator.version), comparator.version);\n\tif (equal.size > 1) return null;\n\tlet boundsComparison;\n\tif (lower && upper) {\n\t\tboundsComparison = compareParsed(lower.version, upper.version);\n\t\tif (boundsComparison > 0) return null;\n\t\tif (boundsComparison === 0 && (lower.operator !== \">=\" || upper.operator !== \"<=\")) return null;\n\t}\n\tfor (const version of equal.values()) {\n\t\tif (lower && !testParsedComparator(lower, version)) return null;\n\t\tif (upper && !testParsedComparator(upper, version)) return null;\n\t\treturn testComparatorSet(superset, version, options);\n\t}\n\tlet needsLowerPrerelease = lower && !options.includePrerelease && lower.version.prerelease?.length ? lower.version : null;\n\tlet needsUpperPrerelease = upper && !options.includePrerelease && upper.version.prerelease?.length ? upper.version : null;\n\tconst upperPrerelease = needsUpperPrerelease?.prerelease;\n\tif (upperPrerelease?.length === 1 && upper?.operator === \"<\" && upperPrerelease[0] === 0) needsUpperPrerelease = null;\n\tlet hasSupersetLower = false;\n\tlet hasSupersetUpper = false;\n\tfor (const comparator of superset) {\n\t\thasSupersetLower ||= comparator.operator === \">\" || comparator.operator === \">=\";\n\t\thasSupersetUpper ||= comparator.operator === \"<\" || comparator.operator === \"<=\";\n\t\tif (lower) {\n\t\t\tif (needsLowerPrerelease && comparatorAllowsPrerelease(comparator, needsLowerPrerelease)) needsLowerPrerelease = null;\n\t\t\tif (comparator.operator === \">\" || comparator.operator === \">=\") {\n\t\t\t\tconst higher = higherLowerBound(lower, comparator);\n\t\t\t\tif (higher === comparator && higher !== lower) return false;\n\t\t\t} else if (lower.operator === \">=\" && !testParsedComparator(comparator, lower.version)) return false;\n\t\t}\n\t\tif (upper) {\n\t\t\tif (needsUpperPrerelease && comparatorAllowsPrerelease(comparator, needsUpperPrerelease)) needsUpperPrerelease = null;\n\t\t\tif (comparator.operator === \"<\" || comparator.operator === \"<=\") {\n\t\t\t\tconst lowerBound = lowerUpperBound(upper, comparator);\n\t\t\t\tif (lowerBound === comparator && lowerBound !== upper) return false;\n\t\t\t} else if (upper.operator === \"<=\" && !testParsedComparator(comparator, upper.version)) return false;\n\t\t}\n\t\tif (comparator.operator === \"\" && (lower || upper) && boundsComparison !== 0) return false;\n\t}\n\tif (lower && hasSupersetUpper && !upper && boundsComparison !== 0) return false;\n\tif (upper && hasSupersetLower && !lower && boundsComparison !== 0) return false;\n\treturn !needsLowerPrerelease && !needsUpperPrerelease;\n}\nfunction isRangeSubset(subset, superset, options = {}) {\n\tif (subset === superset) return true;\n\tconst parsedSubset = parseRange(subset, options);\n\tconst parsedSuperset = parseRange(superset, options);\n\tconst effectiveOptions = {\n\t\t...parsedSubset.options,\n\t\t...parsedSuperset.options,\n\t\t...options\n\t};\n\tlet sawNonNull = false;\n\tfor (const subsetSet of parsedSubset.sets) {\n\t\tlet matched = false;\n\t\tfor (const supersetSet of parsedSuperset.sets) {\n\t\t\tconst result = simpleRangeSubset(subsetSet, supersetSet, effectiveOptions);\n\t\t\tsawNonNull ||= result !== null;\n\t\t\tif (result) {\n\t\t\t\tmatched = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!matched && sawNonNull) return false;\n\t}\n\treturn true;\n}\n//#endregion\nexport { isGreaterThanRange as a, isValidRange as c, rangesIntersect as d, satisfies as f, tryParseRange as h, findMinimumForRange as i, normalizeRange as l, parseRange as m, findMaxSatisfying as n, isLessThanRange as o, simplifyRange as p, findMinSatisfying as r, isOutsideRange as s, isRangeSubset as t, rangeToComparators as u };\n", "import { parseCompiledCatalog } from \"../db/releaseCatalog.mjs\";\nimport { rangesIntersect } from \"verkit\";\n//#region src/core/baseCandidates.ts\n/** A compiled segment as a range: its version when it holds exactly one. */\nconst segmentRange = ({ lower, upper }) => lower?.inclusive && upper?.inclusive && lower.version === upper.version ? lower.version : [lower === null ? \"\" : `${lower.inclusive ? \">=\" : \">\"}${lower.version}`, upper === null ? \"\" : `${upper.inclusive ? \"<=\" : \"<\"}${upper.version}`].join(\" \").trim() || \"*\";\n/**\n* Auto-patch bases from a scope's compiled Release Catalog, which holds\n* every enabled bundle release of the scope: those whose range intersects\n* `range` (all of them in a fingerprint scope), newest release first, each\n* bundle once and older than `bundleId`, at most `limit`.\n*/\nconst baseBundleIdsOf = (row, range, bundleId, limit) => {\n\tconst catalog = parseCompiledCatalog(row.payload, row.strategy);\n\tconst serving = new Set(catalog.strategy === \"FINGERPRINT\" ? catalog.rollbackReleaseIndexes : catalog.segments.flatMap((segment) => range !== null && rangesIntersect(range, segmentRange(segment)) ? segment.rollbackReleaseIndexes : []));\n\tconst newestFirst = catalog.releaseDescriptors.map((descriptor, index) => ({\n\t\tdescriptor,\n\t\tindex\n\t})).sort((left, right) => left.descriptor.releaseId < right.descriptor.releaseId ? 1 : -1);\n\tconst ids = [];\n\tfor (const { descriptor, index } of newestFirst) {\n\t\tif (ids.length >= limit) break;\n\t\tconst id = descriptor.bundleId;\n\t\tif (serving.has(index) && id !== null && id < bundleId && !ids.includes(id)) ids.push(id);\n\t}\n\treturn ids;\n};\n//#endregion\nexport { baseBundleIdsOf };\n", "import { projectReleaseCatalogRow, releaseCatalogScopeKeyOf } from \"../db/releaseCatalog.mjs\";\nimport { resolveManifestArtifacts } from \"../db/updateArtifacts.mjs\";\nimport { baseBundleIdsOf } from \"./baseCandidates.mjs\";\nimport { parseBaseCandidateKey, rowToBundle } from \"@hot-updater/plugin-core\";\nimport { ARTIFACT_PROTOCOL_VERSION, NIL_UUID } from \"@hot-updater/protocol\";\n//#region src/core/reads.ts\nconst PAGE = 500;\nconst pick = (fields) => (row) => Object.fromEntries(fields.map((field) => [field, row[field]]));\nconst toBundleRow = pick([\n\t\"id\",\n\t\"platform\",\n\t\"git_commit_hash\",\n\t\"metadata\",\n\t\"manifest_storage_uri\",\n\t\"manifest_file_hash\",\n\t\"asset_base_storage_uri\"\n]);\nconst toPatchRow = pick([\n\t\"id\",\n\t\"bundle_id\",\n\t\"base_bundle_id\",\n\t\"base_file_hash\",\n\t\"patch_file_hash\",\n\t\"patch_storage_uri\",\n\t\"byte_size\",\n\t\"order_index\"\n]);\nconst toReleaseRow = pick([\n\t\"id\",\n\t\"revision\",\n\t\"scope_key\",\n\t\"channel_id\",\n\t\"platform\",\n\t\"kind\",\n\t\"bundle_id\",\n\t\"strategy\",\n\t\"target_app_version\",\n\t\"fingerprint_hash\",\n\t\"enabled\",\n\t\"should_force_update\",\n\t\"message\",\n\t\"rollout_cohort_count\",\n\t\"target_cohorts\",\n\t\"operation\",\n\t\"source_release_id\",\n\t\"created_at_ms\",\n\t\"updated_at_ms\"\n]);\nconst toCatalogRow = pick([\n\t\"scope_key\",\n\t\"catalog_id\",\n\t\"strategy\",\n\t\"channel_id\",\n\t\"channel_key\",\n\t\"platform\",\n\t\"fingerprint_hash\",\n\t\"generation\",\n\t\"payload\",\n\t\"catalog_hash\",\n\t\"byte_size\",\n\t\"is_tombstone\",\n\t\"updated_at_ms\"\n]);\nconst toChannelRow = pick([\"id\", \"name\"]);\n/** Every page of one read, in order. */\nconst drain = async (read) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await read(cursor === void 0 ? {} : { cursor });\n\t\trows.push(...page.rows);\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\n/** Core's reads, each through one declared index or key. */\nconst createCoreReads = (db, storage) => {\n\t/** A bundle row's patches, exactly as many as its reference counter holds. */\n\tconst detail = async (row) => {\n\t\tconst count = row._refs_bundle_patches_bundle_id ?? 0;\n\t\tconst patches = [];\n\t\tlet cursor;\n\t\twhile (patches.length < count) {\n\t\t\tconst page = await db.findMany(\"bundle_patches\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: { bundle_id: row.id },\n\t\t\t\tlimit: Math.min(count - patches.length, PAGE),\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\tpatches.push(...page.rows.map(toPatchRow));\n\t\t\tif (page.next === void 0) break;\n\t\t\tcursor = page.next;\n\t\t}\n\t\treturn {\n\t\t\tbundle: toBundleRow(row),\n\t\t\tpatches,\n\t\t\tchildCount: row._refs_bundle_patches_base_bundle_id ?? 0\n\t\t};\n\t};\n\tconst after = (input) => input.after === void 0 ? {} : { range: (input.order ?? \"asc\") === \"asc\" ? { gt: input.after } : { lt: input.after } };\n\treturn {\n\t\t/** The update check: one point read of its scope's catalog. */\n\t\tasync getReleaseCatalog(input) {\n\t\t\tconst scopeKey = releaseCatalogScopeKeyOf(input);\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\t\t\treturn projectReleaseCatalogRow(row === null ? null : toCatalogRow(row), input, scopeKey);\n\t\t},\n\t\t/** Artifact resolution: one batch read of both bundles and one unique read of their patch. */\n\t\tasync getArtifactInfo(targetBundleId, currentBundleId, artifactProtocolVersion) {\n\t\t\tconst { readStorageText } = storage;\n\t\t\tif (artifactProtocolVersion !== ARTIFACT_PROTOCOL_VERSION || readStorageText === void 0) return null;\n\t\t\tconst withCurrent = currentBundleId !== NIL_UUID;\n\t\t\tconst [[target, current], patch] = await Promise.all([db.findByKeys(\"bundles\", withCurrent ? [{ id: targetBundleId }, { id: currentBundleId }] : [{ id: targetBundleId }]), withCurrent ? db.findOne(\"bundle_patches\", {\n\t\t\t\tbundle_id: targetBundleId,\n\t\t\t\tbase_bundle_id: currentBundleId\n\t\t\t}) : null]);\n\t\t\tif (target === null || target === void 0) return null;\n\t\t\treturn resolveManifestArtifacts({\n\t\t\t\tcurrentBundle: current ? rowToBundle(toBundleRow(current)) : null,\n\t\t\t\treadStorageText,\n\t\t\t\tresolveFileUrl: storage.resolveFileUrl,\n\t\t\t\ttargetBundle: rowToBundle(toBundleRow(target), patch === null ? [] : [toPatchRow(patch)])\n\t\t\t});\n\t\t},\n\t\t/** A bundle, its patches, and how many patches start from it. */\n\t\tasync getBundle(id) {\n\t\t\tconst row = await db.findOne(\"bundles\", { id });\n\t\t\treturn row === null ? null : detail(row);\n\t\t},\n\t\t/** One page of the patches that start from a bundle, by target bundle id. */\n\t\t/** Each base bundle's reference counter: one batch read of the bundle rows, and no patches. */\n\t\tasync countBundleChildren(baseBundleIds) {\n\t\t\tconst ids = [...new Set(baseBundleIds)];\n\t\t\tif (ids.length === 0) return {};\n\t\t\tconst rows = await db.findByKeys(\"bundles\", ids.map((id) => ({ id })));\n\t\t\treturn Object.fromEntries(ids.map((id, position) => [id, rows[position]?._refs_bundle_patches_base_bundle_id ?? 0]));\n\t\t},\n\t\tasync listPatchesFromBase(baseBundleId, input) {\n\t\t\treturn (await db.findMany(\"bundle_patches\", {\n\t\t\t\tindex: \"byBase\",\n\t\t\t\twhere: { base_bundle_id: baseBundleId },\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t})).rows.map(toPatchRow);\n\t\t},\n\t\t/** One page of bundles with their patches, oldest or newest first, optionally for one platform. */\n\t\tasync listBundles(input) {\n\t\t\tconst page = input.platform === void 0 ? await db.findMany(\"bundles\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t}) : await db.findMany(\"bundles\", {\n\t\t\t\tindex: \"byPlatform\",\n\t\t\t\twhere: { platform: input.platform },\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t});\n\t\t\treturn Promise.all(page.rows.map(detail));\n\t\t},\n\t\t/** Bundles in total or for one platform: one counter row. */\n\t\tasync countBundles(platform) {\n\t\t\tconst { rows } = await db.findAggregates(\"bundle_totals\", {\n\t\t\t\tindex: \"byPlatform\",\n\t\t\t\twhere: { platform_key: platform ?? \"*\" },\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn rows[0]?.bundles ?? 0;\n\t\t},\n\t\t/** Auto-patch bases for a new bundle: one point read of its scope's catalog. */\n\t\tasync findBaseBundleIds(candidateKey, bundleId, limit) {\n\t\t\tconst query = parseBaseCandidateKey(candidateKey);\n\t\t\tif (query === null) return [];\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: query.scopeKey });\n\t\t\treturn row === null ? [] : baseBundleIdsOf(toCatalogRow(row), query.range, bundleId, limit);\n\t\t},\n\t\tasync getRelease(id) {\n\t\t\tconst row = await db.findOne(\"releases\", { id });\n\t\t\treturn row === null ? null : toReleaseRow(row);\n\t\t},\n\t\t/** One page of releases through the index its filter names. */\n\t\tasync listReleases(input) {\n\t\t\tconst { filter } = input;\n\t\t\tconst options = {\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t};\n\t\t\treturn (filter.kind === \"all\" ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\t...options\n\t\t\t}) : filter.kind === \"bundle\" ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: { bundle_id: filter.bundleId },\n\t\t\t\t...options\n\t\t\t}) : filter.kind === \"scope\" ? filter.enabled === void 0 ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScope\",\n\t\t\t\twhere: { scope_key: filter.scopeKey },\n\t\t\t\t...options\n\t\t\t}) : await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScopeEnabled\",\n\t\t\t\twhere: {\n\t\t\t\t\tscope_key: filter.scopeKey,\n\t\t\t\t\tenabled: filter.enabled\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t}) : filter.enabled === void 0 ? await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byChannelPlatform\",\n\t\t\t\twhere: {\n\t\t\t\t\tchannel_id: filter.channelId,\n\t\t\t\t\tplatform: filter.platform\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t}) : await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byChannelPlatformEnabled\",\n\t\t\t\twhere: {\n\t\t\t\t\tchannel_id: filter.channelId,\n\t\t\t\t\tplatform: filter.platform,\n\t\t\t\t\tenabled: filter.enabled\n\t\t\t\t},\n\t\t\t\t...options\n\t\t\t})).rows.map(toReleaseRow);\n\t\t},\n\t\t/** A scope's newest release id: `byScope` descending, limit 1. */\n\t\tasync latestReleaseId(scopeKey) {\n\t\t\tconst { rows } = await db.findMany(\"releases\", {\n\t\t\t\tindex: \"byScope\",\n\t\t\t\twhere: { scope_key: scopeKey },\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit: 1\n\t\t\t});\n\t\t\treturn rows[0]?.id ?? null;\n\t\t},\n\t\tasync getReleaseCatalogRow(scopeKey) {\n\t\t\tconst row = await db.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\t\t\treturn row === null ? null : toCatalogRow(row);\n\t\t},\n\t\tasync listReleaseCatalogs(input) {\n\t\t\treturn (await db.findMany(\"release_catalogs\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\torder: input.order ?? \"asc\",\n\t\t\t\tlimit: input.limit,\n\t\t\t\t...after(input)\n\t\t\t})).rows.map(toCatalogRow);\n\t\t},\n\t\t/** Every channel, by name. */\n\t\tasync listChannels() {\n\t\t\treturn (await drain((page) => db.findMany(\"channels\", {\n\t\t\t\tindex: \"all\",\n\t\t\t\twhere: {},\n\t\t\t\tlimit: PAGE,\n\t\t\t\t...page\n\t\t\t}))).map(toChannelRow);\n\t\t},\n\t\tasync findChannelByName(name) {\n\t\t\tconst row = await db.findOne(\"channels\", { name });\n\t\t\treturn row === null ? null : toChannelRow(row);\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreReads, drain, toBundleRow, toCatalogRow, toChannelRow, toPatchRow, toReleaseRow };\n", "import { toChannelRow } from \"./reads.mjs\";\nimport { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/core/writes.ts\nconst PAGE = 500;\n/** Moves one bundle into or out of its platform's total and the overall total. */\nconst countBundle = (tx, platform, delta) => {\n\tfor (const key of [platform, \"*\"]) tx.aggregate(\"bundle_totals\", { platform_key: key }, { bundles: delta });\n};\nconst insertBundle = (tx, row) => {\n\ttx.create(\"bundles\", row);\n\tcountBundle(tx, row.platform, 1);\n};\nconst updateBundle = (tx, current, set) => {\n\ttx.update(\"bundles\", current, set);\n\tif (set.platform !== void 0 && set.platform !== current.platform) {\n\t\tcountBundle(tx, current.platform, -1);\n\t\tcountBundle(tx, set.platform, 1);\n\t}\n};\n/** Deletes a bundle and, by cascade, every patch to or from it; a release on it refuses. */\nconst deleteBundle = async (tx, current) => {\n\tawait tx.delete(\"bundles\", current);\n\tcountBundle(tx, current.platform, -1);\n};\n/**\n* Replaces a bundle's patches with `rows`: kept patches are updated where\n* they changed, others deleted or created, so no key is written twice.\n*/\nconst replaceBundlePatches = async (tx, bundle, rows) => {\n\tconst wanted = new Map(rows.map((row) => [row.id, row]));\n\tconst count = bundle._refs_bundle_patches_bundle_id ?? 0;\n\tlet cursor;\n\tfor (let seen = 0; seen < count;) {\n\t\tconst page = await tx.findMany(\"bundle_patches\", {\n\t\t\tindex: \"byBundle\",\n\t\t\twhere: { bundle_id: bundle.id },\n\t\t\tlimit: Math.min(count - seen, PAGE),\n\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t});\n\t\tfor (const stored of page.rows) {\n\t\t\tconst next = wanted.get(stored.id);\n\t\t\twanted.delete(stored.id);\n\t\t\tif (next === void 0) {\n\t\t\t\tawait tx.delete(\"bundle_patches\", stored);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst set = Object.fromEntries(Object.entries(next).filter(([field, value]) => field !== \"id\" && stored[field] !== value));\n\t\t\tif (Object.keys(set).length > 0) tx.update(\"bundle_patches\", stored, set);\n\t\t}\n\t\tseen += page.rows.length;\n\t\tif (page.next === void 0) break;\n\t\tcursor = page.next;\n\t}\n\tfor (const row of wanted.values()) tx.create(\"bundle_patches\", row);\n};\n/** A channel by name, created when missing; a concurrent creator's row is returned instead. */\nconst insertChannel = async (db, row) => {\n\tfor (let attempt = 1;; attempt += 1) try {\n\t\treturn await db.transaction(async (tx) => {\n\t\t\tconst existing = await tx.findOne(\"channels\", { name: row.name });\n\t\t\tif (existing !== null) return {\n\t\t\t\trow: toChannelRow(existing),\n\t\t\t\tinserted: false\n\t\t\t};\n\t\t\ttx.create(\"channels\", row);\n\t\t\treturn {\n\t\t\t\trow,\n\t\t\t\tinserted: true\n\t\t\t};\n\t\t});\n\t} catch (error) {\n\t\tif (attempt < 3 && error instanceof DatabaseConstraintError && (error.reason === \"unique\" || error.reason === \"exists\")) continue;\n\t\tthrow error;\n\t}\n};\n/** Deletes a channel no release uses: 1 read + 1 write. */\nconst deleteChannel = (db, id) => db.transaction(async (tx) => {\n\tconst row = await tx.findOne(\"channels\", { id });\n\tif (row === null) return {\n\t\tdeleted: false,\n\t\treason: \"not_found\"\n\t};\n\tif ((row._refs_releases_channel_id ?? 0) > 0) return {\n\t\tdeleted: false,\n\t\treason: \"not_empty\"\n\t};\n\tawait tx.delete(\"channels\", row);\n\treturn { deleted: true };\n});\n//#endregion\nexport { deleteBundle, deleteChannel, insertBundle, insertChannel, replaceBundlePatches, updateBundle };\n", "import { toCatalogRow, toReleaseRow } from \"./reads.mjs\";\nimport { insertBundle } from \"./writes.mjs\";\nimport { ReleaseCatalogMutationError, compileReleaseCatalog, createUUIDv7, createUUIDv7After, isUUIDv7, releaseRowToRelease } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey, encodeChannelKey } from \"@hot-updater/protocol\";\n//#region src/core/releases.ts\nconst PAGE = 500;\nconst fail = (code, message) => {\n\tthrow new ReleaseCatalogMutationError(code, message);\n};\nconst checkScope = (scope) => {\n\tconst channelKey = encodeChannelKey(scope.channelName);\n\tconst expected = scope.strategy === \"APP_VERSION\" ? createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tplatform: scope.platform,\n\t\tstrategy: \"APP_VERSION\"\n\t}) : createReleaseCatalogScopeKey({\n\t\tchannelKey,\n\t\tfingerprintHash: scope.fingerprintHash ?? \"\",\n\t\tplatform: scope.platform,\n\t\tstrategy: \"FINGERPRINT\"\n\t});\n\tif (scope.strategy === \"FINGERPRINT\" !== (scope.fingerprintHash !== null) || scope.scopeKey !== expected) fail(\"INVALID_SCOPE\", \"Release catalog scope metadata is inconsistent\");\n};\n/** A scope's enabled releases, all of them, under the catalog's guard. */\nconst enabledReleases = async (tx, scopeKey) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await tx.findMany(\"releases\", {\n\t\t\tindex: \"byScopeEnabled\",\n\t\t\twhere: {\n\t\t\t\tscope_key: scopeKey,\n\t\t\t\tenabled: true\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t});\n\t\trows.push(...page.rows.map(toReleaseRow));\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\n/** The scope's newest release id: `byScope` descending, limit 1. */\nconst latestReleaseId = async (tx, scopeKey) => {\n\tconst { rows } = await tx.findMany(\"releases\", {\n\t\tindex: \"byScope\",\n\t\twhere: { scope_key: scopeKey },\n\t\torder: \"desc\",\n\t\tlimit: 1\n\t});\n\treturn rows[0]?.id ?? null;\n};\n/** Compiles `enabled` and writes it as the scope's next catalog generation. */\nconst writeCatalog = async (tx, scope, stored, enabled, updatedAtMs) => {\n\tconst compilation = await compileReleaseCatalog({\n\t\tstrategy: scope.strategy,\n\t\treleases: enabled.map(releaseRowToRelease)\n\t});\n\tconst generation = (stored.generation ?? 0) + 1;\n\tif (!Number.isSafeInteger(generation)) fail(\"CATALOG_GENERATION_EXHAUSTED\", `Catalog \"${scope.scopeKey}\" exhausted its generation counter`);\n\tconst catalog = {\n\t\tscope_key: scope.scopeKey,\n\t\tcatalog_id: stored.catalog?.catalog_id ?? createUUIDv7(),\n\t\tstrategy: scope.strategy,\n\t\tchannel_id: scope.channelId,\n\t\tchannel_key: encodeChannelKey(scope.channelName),\n\t\tplatform: scope.platform,\n\t\tfingerprint_hash: scope.fingerprintHash,\n\t\tgeneration,\n\t\tpayload: compilation.canonicalPayload,\n\t\tcatalog_hash: compilation.catalogHash,\n\t\tbyte_size: compilation.byteSize,\n\t\tis_tombstone: compilation.payload.releaseDescriptors.length === 0,\n\t\tupdated_at_ms: updatedAtMs\n\t};\n\tconst { scope_key: _scopeKey, ...set } = catalog;\n\tif (stored.row === null) tx.create(\"release_catalogs\", catalog);\n\telse tx.update(\"release_catalogs\", stored.row, set);\n\treturn {\n\t\tcatalog,\n\t\tcompilation\n\t};\n};\n/** The scope's catalog row, and its compiled catalog and generation if it has one. */\nconst readCatalog = async (tx, scopeKey) => {\n\tconst row = await tx.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\treturn {\n\t\trow,\n\t\tgeneration: row?.generation ?? null,\n\t\tcatalog: row === null ? null : toCatalogRow(row)\n\t};\n};\n/** A scope with releases and no compiled catalog lost its history. */\nconst assertHistory = (stored, hasReleases) => {\n\tif (stored.catalog === null && hasReleases) fail(\"CATALOG_IDENTITY_MISSING\", \"Catalog history is missing. Restore its catalog row from backup before rebuilding or deploying.\");\n};\n/** One release change and its scope's next catalog, inside `tx`. */\nconst changeRelease = async (tx, { scope, change, bundle, updatedAtMs }) => {\n\tcheckScope(scope);\n\tconst stored = await readCatalog(tx, scope.scopeKey);\n\tconst enabled = await enabledReleases(tx, scope.scopeKey);\n\tif (bundle !== void 0) {\n\t\tinsertBundle(tx, bundle.row);\n\t\tfor (const patch of bundle.patches) tx.create(\"bundle_patches\", patch);\n\t}\n\tlet before = null;\n\tlet release;\n\tif (change.operation === \"insert\") {\n\t\tconst latest = await latestReleaseId(tx, scope.scopeKey);\n\t\tassertHistory(stored, latest !== null);\n\t\tconst floor = [latest, bundle && isUUIDv7(bundle.row.id) ? bundle.row.id : null].filter((id) => id !== null).sort().at(-1);\n\t\tconst id = change.row.id ?? createUUIDv7After(floor ?? null);\n\t\tif (latest !== null && id <= latest) fail(\"NON_MONOTONIC_RELEASE_ID\", `Release \"${id}\" must sort after \"${latest}\"`);\n\t\trelease = {\n\t\t\t...change.row,\n\t\t\tid\n\t\t};\n\t\tif (release.scope_key !== scope.scopeKey || release.channel_id !== scope.channelId || release.platform !== scope.platform || release.strategy !== scope.strategy || release.fingerprint_hash !== scope.fingerprintHash || release.revision !== 1) fail(\"INVALID_SCOPE\", \"Inserted Release does not match its catalog scope\");\n\t\ttx.create(\"releases\", release);\n\t} else {\n\t\tconst row = await tx.findOne(\"releases\", { id: change.id });\n\t\tif (row === null || row.scope_key !== scope.scopeKey) return fail(\"RELEASE_NOT_FOUND\", `Release \"${change.id}\" was not found in scope \"${scope.scopeKey}\"`);\n\t\tassertHistory(stored, true);\n\t\tbefore = toReleaseRow(row);\n\t\tif (change.operation === \"delete\") {\n\t\t\tawait tx.delete(\"releases\", row);\n\t\t\trelease = null;\n\t\t} else {\n\t\t\tconst set = {\n\t\t\t\t...change.update,\n\t\t\t\trevision: before.revision + 1\n\t\t\t};\n\t\t\ttx.update(\"releases\", row, set);\n\t\t\trelease = {\n\t\t\t\t...before,\n\t\t\t\t...set\n\t\t\t};\n\t\t}\n\t}\n\tconst changedId = before?.id ?? release?.id;\n\tconst next = [...enabled.filter(({ id }) => id !== changedId), ...release?.enabled ? [release] : []].sort((left, right) => left.id < right.id ? -1 : 1);\n\tconst { catalog, compilation } = await writeCatalog(tx, scope, stored, next, updatedAtMs);\n\treturn {\n\t\tcatalog,\n\t\trelease,\n\t\tdiagnostics: compilation.diagnostics\n\t};\n};\n/**\n* Release changes rooted at their catalogs: each reads its scope's catalog\n* and enabled releases, applies the change, and writes the next catalog\n* generation, all in one transaction. A concurrent change in a scope bumps\n* its catalog row, so this transaction reruns instead of publishing a stale\n* catalog.\n*/\nconst changeReleases = (db, inputs) => {\n\tif (new Set(inputs.map(({ scope }) => scope.scopeKey)).size !== inputs.length) fail(\"INVALID_SCOPE\", \"A batch cannot change one catalog scope twice\");\n\treturn db.transaction(async (tx) => {\n\t\tconst results = [];\n\t\tfor (const input of inputs) results.push(await changeRelease(tx, input));\n\t\treturn results;\n\t});\n};\n/** Recompiles a scope's catalog from its enabled releases inside `tx`; an unchanged catalog is not rewritten. */\nconst rebuildScope = async (tx, scope, updatedAtMs) => {\n\tcheckScope(scope);\n\tconst stored = await readCatalog(tx, scope.scopeKey);\n\tassertHistory(stored, await latestReleaseId(tx, scope.scopeKey) !== null);\n\tconst enabled = await enabledReleases(tx, scope.scopeKey);\n\tconst compilation = await compileReleaseCatalog({\n\t\tstrategy: scope.strategy,\n\t\treleases: enabled.map(releaseRowToRelease)\n\t});\n\tconst current = stored.catalog;\n\tif (current !== null && current.strategy === scope.strategy && current.channel_id === scope.channelId && current.channel_key === encodeChannelKey(scope.channelName) && current.platform === scope.platform && current.fingerprint_hash === scope.fingerprintHash && current.catalog_hash === compilation.catalogHash) return {\n\t\tcatalog: current,\n\t\tcurrent,\n\t\tchanged: false,\n\t\tdiagnostics: compilation.diagnostics\n\t};\n\tconst written = await writeCatalog(tx, scope, stored, enabled, updatedAtMs);\n\treturn {\n\t\tcatalog: written.catalog,\n\t\tcurrent,\n\t\tchanged: true,\n\t\tdiagnostics: written.compilation.diagnostics\n\t};\n};\n//#endregion\nexport { changeRelease, changeReleases, readCatalog, rebuildScope };\n", "import { toBundleRow, toReleaseRow } from \"./reads.mjs\";\nimport { deleteBundle, deleteChannel, insertChannel, replaceBundlePatches, updateBundle } from \"./writes.mjs\";\nimport { changeRelease, changeReleases, readCatalog, rebuildScope } from \"./releases.mjs\";\nimport { DatabaseBundleNotFoundError, DatabaseConstraintError, DatabaseRowReferencedError, ReleaseCatalogMutationError, ReleaseManagementError, bundleToPatchRows, bundleToRow, createUUIDv7After, isUUIDv7, rowToBundle } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey, decodeChannelKey, encodeChannelKey } from \"@hot-updater/protocol\";\n//#region src/core/operations.ts\n/** Carries a preflight's result out of the transaction it stops, so nothing is written. */\nvar Preflight = class extends Error {\n\tresult;\n\tconstructor(result) {\n\t\tsuper(\"preflight\");\n\t\tthis.result = result;\n\t}\n};\nconst dryRun = async (db, read) => {\n\ttry {\n\t\tawait db.transaction(async (tx) => {\n\t\t\tthrow new Preflight(await read(tx));\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof Preflight) return error.result;\n\t\tthrow error;\n\t}\n\tthrow new Error(\"A preflight transaction returned without its result.\");\n};\n/** A channel's catalog scope for a platform, and a fingerprint when it has one. */\nconst scopeOf = (channel, platform, fingerprintHash) => {\n\tconst channelKey = encodeChannelKey(channel.name);\n\treturn fingerprintHash === null ? {\n\t\tchannelId: channel.id,\n\t\tchannelName: channel.name,\n\t\tfingerprintHash,\n\t\tplatform,\n\t\tscopeKey: createReleaseCatalogScopeKey({\n\t\t\tchannelKey,\n\t\t\tplatform,\n\t\t\tstrategy: \"APP_VERSION\"\n\t\t}),\n\t\tstrategy: \"APP_VERSION\"\n\t} : {\n\t\tchannelId: channel.id,\n\t\tchannelName: channel.name,\n\t\tfingerprintHash,\n\t\tplatform,\n\t\tscopeKey: createReleaseCatalogScopeKey({\n\t\t\tchannelKey,\n\t\t\tfingerprintHash,\n\t\t\tplatform,\n\t\t\tstrategy: \"FINGERPRINT\"\n\t\t}),\n\t\tstrategy: \"FINGERPRINT\"\n\t};\n};\n/** A release and its scope, checked against the revision the caller saw. */\nconst loadTarget = async (tx, { releaseId, expectedRevision }) => {\n\tconst row = await tx.findOne(\"releases\", { id: releaseId });\n\tif (row === null) throw new ReleaseManagementError(\"RELEASE_NOT_FOUND\", `Release \"${releaseId}\" was not found.`);\n\tconst release = toReleaseRow(row);\n\tif (expectedRevision !== void 0 && expectedRevision !== release.revision) throw new ReleaseManagementError(\"VERSION_CONFLICT\", `Release \"${release.id}\" is revision ${release.revision}; expected ${expectedRevision}.`);\n\tconst catalog = await tx.findOne(\"release_catalogs\", { scope_key: release.scope_key });\n\tif (catalog === null) throw new ReleaseCatalogMutationError(\"INVALID_SCOPE\", `Release \"${release.id}\" has no catalog projection.`);\n\treturn {\n\t\trelease,\n\t\tscope: {\n\t\t\tchannelId: release.channel_id,\n\t\t\tchannelName: decodeChannelKey(catalog.channel_key),\n\t\t\tfingerprintHash: release.fingerprint_hash,\n\t\t\tplatform: release.platform,\n\t\t\tscopeKey: release.scope_key,\n\t\t\tstrategy: release.strategy\n\t\t}\n\t};\n};\nconst policyUpdate = (release, patch, updatedAtMs) => {\n\tif (patch.fingerprintHash !== void 0 && patch.fingerprintHash !== release.fingerprint_hash) throw new ReleaseManagementError(\"SCOPE_MOVE_UNSUPPORTED\", \"Changing a fingerprint target requires an atomic Release scope move.\");\n\treturn {\n\t\t...patch.enabled === void 0 ? {} : { enabled: patch.enabled },\n\t\t...patch.message === void 0 ? {} : { message: patch.message },\n\t\t...patch.rolloutCohortCount === void 0 ? {} : { rollout_cohort_count: patch.rolloutCohortCount },\n\t\t...patch.shouldForceUpdate === void 0 ? {} : { should_force_update: patch.shouldForceUpdate },\n\t\t...patch.targetAppVersion === void 0 ? {} : { target_app_version: patch.targetAppVersion },\n\t\t...patch.targetCohorts === void 0 ? {} : { target_cohorts: [...patch.targetCohorts] },\n\t\tupdated_at_ms: updatedAtMs\n\t};\n};\nconst mutationResult = ({ catalog, release }) => ({\n\tattempts: 1,\n\tcatalog,\n\trelease\n});\n/** The scope a catalog row names, for a rebuild. */\nconst catalogScope = async (tx, scopeKey) => {\n\tconst row = await tx.findOne(\"release_catalogs\", { scope_key: scopeKey });\n\tif (row === null) throw new Error(`Release catalog \"${scopeKey}\" was not found.`);\n\treturn {\n\t\tchannelId: row.channel_id,\n\t\tchannelName: decodeChannelKey(row.channel_key),\n\t\tfingerprintHash: row.fingerprint_hash,\n\t\tplatform: row.platform,\n\t\tscopeKey: row.scope_key,\n\t\tstrategy: row.strategy\n\t};\n};\n/**\n* Core's typed writes: each runs in one engine transaction rooted at the\n* catalogs it changes, so a concurrent change reruns it instead of\n* publishing a stale catalog.\n*/\nconst createCoreOperations = (db, { now = Date.now } = {}) => {\n\tconst ensureChannel = async (name) => (await insertChannel(db, {\n\t\tid: `channel:${encodeChannelKey(name)}`,\n\t\tname\n\t})).row;\n\t/**\n\t* Runs a write that ensured its channels first. A channel deleted between\n\t* that and the write refuses the write, so it runs again and ensures it anew.\n\t*/\n\tconst withChannels = async (write) => {\n\t\tfor (let attempt = 1;; attempt += 1) try {\n\t\t\treturn await write();\n\t\t} catch (error) {\n\t\t\tif (attempt < 3 && error instanceof DatabaseConstraintError && error.reason === \"not_found\" && error.model === \"channels\") continue;\n\t\t\tthrow error;\n\t\t}\n\t};\n\tconst deployOnce = async (deployments) => {\n\t\tconst channels = /* @__PURE__ */ new Map();\n\t\tfor (const { release } of deployments) if (!channels.has(release.channel)) channels.set(release.channel, await ensureChannel(release.channel));\n\t\tconst platforms = /* @__PURE__ */ new Map();\n\t\tfor (const deployment of deployments) {\n\t\t\tif (!(\"bundleId\" in deployment) || platforms.has(deployment.bundleId)) continue;\n\t\t\tconst row = await db.findOne(\"bundles\", { id: deployment.bundleId });\n\t\t\tif (row === null) throw new DatabaseBundleNotFoundError(deployment.bundleId);\n\t\t\tplatforms.set(deployment.bundleId, toBundleRow(row).platform);\n\t\t}\n\t\tconst updatedAtMs = now();\n\t\treturn (await changeReleases(db, deployments.map((deployment) => {\n\t\t\tconst { release: policy } = deployment;\n\t\t\tconst stored = \"bundleId\" in deployment;\n\t\t\tconst bundleId = stored ? deployment.bundleId : deployment.bundle.id;\n\t\t\tconst platform = stored ? platforms.get(deployment.bundleId) : deployment.bundle.platform;\n\t\t\tconst scope = scopeOf(channels.get(policy.channel), platform, policy.fingerprintHash);\n\t\t\treturn {\n\t\t\t\tscope,\n\t\t\t\t...stored ? {} : { bundle: {\n\t\t\t\t\trow: bundleToRow(deployment.bundle),\n\t\t\t\t\tpatches: bundleToPatchRows(deployment.bundle)\n\t\t\t\t} },\n\t\t\t\tchange: {\n\t\t\t\t\toperation: \"insert\",\n\t\t\t\t\trow: {\n\t\t\t\t\t\tbundle_id: bundleId,\n\t\t\t\t\t\tchannel_id: scope.channelId,\n\t\t\t\t\t\tcreated_at_ms: updatedAtMs,\n\t\t\t\t\t\tenabled: policy.enabled,\n\t\t\t\t\t\tfingerprint_hash: policy.fingerprintHash,\n\t\t\t\t\t\tkind: \"BUNDLE\",\n\t\t\t\t\t\tmessage: policy.message,\n\t\t\t\t\t\toperation: \"DEPLOY\",\n\t\t\t\t\t\tplatform,\n\t\t\t\t\t\trevision: 1,\n\t\t\t\t\t\trollout_cohort_count: policy.rolloutCohortCount ?? 1e3,\n\t\t\t\t\t\tscope_key: scope.scopeKey,\n\t\t\t\t\t\tshould_force_update: policy.shouldForceUpdate,\n\t\t\t\t\t\tsource_release_id: null,\n\t\t\t\t\t\tstrategy: scope.strategy,\n\t\t\t\t\t\ttarget_app_version: policy.targetAppVersion,\n\t\t\t\t\t\ttarget_cohorts: policy.targetCohorts ?? [],\n\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdatedAtMs\n\t\t\t};\n\t\t}))).map(mutationResult);\n\t};\n\treturn {\n\t\tdeploy: (deployments) => withChannels(() => deployOnce(deployments)),\n\t\tupdateReleasePolicy: (input) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\t\treturn mutationResult(await changeRelease(tx, {\n\t\t\t\t\tscope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: release.id,\n\t\t\t\t\t\tupdate: policyUpdate(release, input.patch, updatedAtMs)\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t}));\n\t\t\t});\n\t\t},\n\t\tpreflightReleasePolicy: (input) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn dryRun(db, async (tx) => {\n\t\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\t\tconst stored = await readCatalog(tx, scope.scopeKey);\n\t\t\t\tconst changed = await changeRelease(tx, {\n\t\t\t\t\tscope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: release.id,\n\t\t\t\t\t\tupdate: policyUpdate(release, input.patch, updatedAtMs)\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tcatalog: changed.catalog,\n\t\t\t\t\tcurrentCatalog: stored.catalog,\n\t\t\t\t\tdiagnostics: changed.diagnostics,\n\t\t\t\t\texpectedReleaseRevision: release.revision,\n\t\t\t\t\trelease: changed.release\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tdeleteRelease: (input) => db.transaction(async (tx) => {\n\t\t\tconst { release, scope } = await loadTarget(tx, input);\n\t\t\tif (release.enabled) throw new ReleaseManagementError(\"ENABLED_RELEASE\", `Disable Release \"${release.id}\" before hard deletion.`);\n\t\t\tconst bundle = release.bundle_id === null ? null : await tx.findOne(\"bundles\", { id: release.bundle_id });\n\t\t\tconst result = mutationResult(await changeRelease(tx, {\n\t\t\t\tscope,\n\t\t\t\tchange: {\n\t\t\t\t\toperation: \"delete\",\n\t\t\t\t\tid: release.id\n\t\t\t\t},\n\t\t\t\tupdatedAtMs: now()\n\t\t\t}));\n\t\t\tif (bundle !== null && (bundle._refs_releases_bundle_id ?? 0) <= 1) await deleteBundle(tx, bundle);\n\t\t\treturn result;\n\t\t}),\n\t\tpromoteRelease: (input) => withChannels(async () => {\n\t\t\tconst checkSource = (source) => {\n\t\t\t\tif (source.bundle_id === null) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Only a Bundle Release can be promoted.\");\n\t\t\t};\n\t\t\tcheckSource((await db.transaction((tx) => loadTarget(tx, input))).release);\n\t\t\tconst targetChannel = input.targetChannel.trim();\n\t\t\tif (targetChannel.length === 0) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Promotion requires a target channel.\");\n\t\t\tconst channel = await ensureChannel(targetChannel);\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { release: source, scope: sourceScope } = await loadTarget(tx, input);\n\t\t\t\tcheckSource(source);\n\t\t\t\tconst targetScope = scopeOf(channel, source.platform, source.fingerprint_hash);\n\t\t\t\tif (targetScope.scopeKey === sourceScope.scopeKey) throw new ReleaseManagementError(\"TARGET_RELEASE_INVALID\", \"Source and target Release scopes are the same.\");\n\t\t\t\tconst { rows } = await tx.findMany(\"releases\", {\n\t\t\t\t\tindex: \"byScope\",\n\t\t\t\t\twhere: { scope_key: targetScope.scopeKey },\n\t\t\t\t\torder: \"desc\",\n\t\t\t\t\tlimit: 1\n\t\t\t\t});\n\t\t\t\tconst floor = [\n\t\t\t\t\trows[0]?.id ?? null,\n\t\t\t\t\tsource.id,\n\t\t\t\t\tsource.bundle_id\n\t\t\t\t].filter((id) => id !== null && isUUIDv7(id)).sort().at(-1);\n\t\t\t\tconst moved = input.action === \"move\" ? await changeRelease(tx, {\n\t\t\t\t\tscope: sourceScope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"update\",\n\t\t\t\t\t\tid: source.id,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t}) : null;\n\t\t\t\tconst target = await changeRelease(tx, {\n\t\t\t\t\tscope: targetScope,\n\t\t\t\t\tchange: {\n\t\t\t\t\t\toperation: \"insert\",\n\t\t\t\t\t\trow: {\n\t\t\t\t\t\t\t...source,\n\t\t\t\t\t\t\tid: createUUIDv7After(floor ?? null, updatedAtMs),\n\t\t\t\t\t\t\trevision: 1,\n\t\t\t\t\t\t\tscope_key: targetScope.scopeKey,\n\t\t\t\t\t\t\tchannel_id: targetScope.channelId,\n\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\trollout_cohort_count: 1e3,\n\t\t\t\t\t\t\ttarget_cohorts: [],\n\t\t\t\t\t\t\toperation: \"PROMOTE\",\n\t\t\t\t\t\t\tsource_release_id: source.id,\n\t\t\t\t\t\t\tcreated_at_ms: updatedAtMs,\n\t\t\t\t\t\t\tupdated_at_ms: updatedAtMs\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tupdatedAtMs\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tsource: moved === null ? null : mutationResult(moved),\n\t\t\t\t\ttarget: mutationResult(target)\n\t\t\t\t};\n\t\t\t});\n\t\t}),\n\t\trebuildReleaseCatalog: (scopeKey) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn db.transaction(async (tx) => {\n\t\t\t\tconst { current: _current, ...rebuilt } = await rebuildScope(tx, await catalogScope(tx, scopeKey), updatedAtMs);\n\t\t\t\treturn {\n\t\t\t\t\tattempts: 1,\n\t\t\t\t\t...rebuilt\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tpreflightReleaseCatalogRebuild: (scopeKey) => {\n\t\t\tconst updatedAtMs = now();\n\t\t\treturn dryRun(db, async (tx) => {\n\t\t\t\tconst rebuilt = await rebuildScope(tx, await catalogScope(tx, scopeKey), updatedAtMs);\n\t\t\t\treturn {\n\t\t\t\t\tchanged: rebuilt.changed,\n\t\t\t\t\tcurrentCatalog: rebuilt.current,\n\t\t\t\t\tdiagnostics: rebuilt.diagnostics,\n\t\t\t\t\tprojectedCatalog: rebuilt.catalog\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tensureChannel,\n\t\tdeleteChannel: (id) => deleteChannel(db, id),\n\t\tupdateBundle: (id, update) => db.transaction(async (tx) => {\n\t\t\tconst current = await tx.findOne(\"bundles\", { id });\n\t\t\tif (current === null) throw new DatabaseBundleNotFoundError(id);\n\t\t\tconst { patches, ...fields } = update;\n\t\t\tconst next = {\n\t\t\t\t...rowToBundle(toBundleRow(current)),\n\t\t\t\t...fields,\n\t\t\t\tid\n\t\t\t};\n\t\t\tconst { id: _id, ...set } = bundleToRow(next);\n\t\t\tupdateBundle(tx, current, set);\n\t\t\tif (patches !== void 0) await replaceBundlePatches(tx, current, bundleToPatchRows({\n\t\t\t\t...next,\n\t\t\t\tpatches\n\t\t\t}));\n\t\t}),\n\t\tdeleteBundles: async (ids) => {\n\t\t\ttry {\n\t\t\t\tawait db.transaction(async (tx) => {\n\t\t\t\t\tfor (const id of new Set(ids)) {\n\t\t\t\t\t\tconst current = await tx.findOne(\"bundles\", { id });\n\t\t\t\t\t\tif (current !== null) await deleteBundle(tx, current);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DatabaseConstraintError && error.reason === \"referenced\") throw new DatabaseRowReferencedError();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreOperations };\n", "import { createCoreReads } from \"./reads.mjs\";\nimport { createCoreOperations } from \"./operations.mjs\";\n//#region src/core/api.ts\n/**\n* The update check answers from one Release Catalog row, so a transaction\n* changes what the cacheable client routes answer only when it writes one.\n* The purge runs once, after the attempt that commits.\n*/\nconst purgingCachedRoutes = (db, onCachedRoutesChange) => {\n\tif (onCachedRoutesChange === void 0) return db;\n\treturn {\n\t\t...db,\n\t\tasync transaction(fn) {\n\t\t\tlet changed = false;\n\t\t\tconst result = await db.transaction((tx) => {\n\t\t\t\tchanged = false;\n\t\t\t\treturn fn({\n\t\t\t\t\t...tx,\n\t\t\t\t\tcreate: (model, row) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\ttx.create(model, row);\n\t\t\t\t\t},\n\t\t\t\t\tupdate: (model, row, set) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\ttx.update(model, row, set);\n\t\t\t\t\t},\n\t\t\t\t\tdelete: (model, row) => {\n\t\t\t\t\t\tchanged ||= model === \"release_catalogs\";\n\t\t\t\t\t\treturn tx.delete(model, row);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (changed) await onCachedRoutesChange();\n\t\t\treturn result;\n\t\t}\n\t};\n};\n/** Core's reads and typed writes over one database handle. */\nconst createCoreApi = (db, storage, options = {}) => {\n\tconst reads = createCoreReads(db, storage);\n\treturn {\n\t\t...reads,\n\t\t...createCoreOperations(purgingCachedRoutes(db, options.onCachedRoutesChange), options),\n\t\t/** One read, which checks the schema settings first. */\n\t\tready: async () => {\n\t\t\tawait reads.listReleaseCatalogs({ limit: 1 });\n\t\t}\n\t};\n};\n//#endregion\nexport { createCoreApi };\n", "import { createCoreReads } from \"../core/reads.mjs\";\nimport { createCoreApi } from \"../core/api.mjs\";\nimport { HotUpdaterConfigError } from \"./configError.mjs\";\nimport { checkReservedId } from \"../plugins/official.mjs\";\nimport { clientPluginsOf } from \"./clientPlugins.mjs\";\nimport { createEngine } from \"@hot-updater/plugin-core\";\n//#region src/assembly/assemblePlugins.ts\nconst PLUGIN_KEYS = /* @__PURE__ */ new Set([\n\t\"id\",\n\t\"provides\",\n\t\"schemaVersion\",\n\t\"schema\",\n\t\"namespace\",\n\t\"init\",\n\t\"cli\"\n]);\nconst CLI_KEYS = /* @__PURE__ */ new Set([\"clientCredential\", \"clientPlugin\"]);\nconst INSTANCE_KEYS = /* @__PURE__ */ new Set([\n\t\"api\",\n\t\"endpoints\",\n\t\"clientAuth\"\n]);\nconst METHODS = /* @__PURE__ */ new Set([\n\t\"GET\",\n\t\"POST\",\n\t\"PUT\",\n\t\"PATCH\",\n\t\"DELETE\"\n]);\n/** An id that prefixes table names is a SQL name; one that does not may use camelCase. */\nconst PREFIX_ID = /^[a-z][a-z0-9_]*$/u;\nconst UNPREFIXED_ID = /^[a-z][A-Za-z0-9_]*$/u;\nconst PATH = /^(\\/(:?[A-Za-z0-9_.~-]+))+$/u;\nconst fail = (message) => {\n\tthrow new HotUpdaterConfigError(message);\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst checkPlugin = (value, at) => {\n\tif (!isRecord(value)) return fail(`${at} is not a plugin.`);\n\tconst unknown = Object.keys(value).find((key) => !PLUGIN_KEYS.has(key));\n\tif (unknown !== void 0) fail(`${at} has an unknown key \"${unknown}\".`);\n\tconst plugin = value;\n\tif (plugin.namespace !== void 0 && plugin.namespace !== false) fail(`${at} may only set namespace: false.`);\n\tconst pattern = plugin.namespace === false ? UNPREFIXED_ID : PREFIX_ID;\n\tif (typeof plugin.id !== \"string\" || !pattern.test(plugin.id)) fail(`${at} needs an id matching ${pattern.source}.`);\n\tif (plugin.id === \"core\") fail(`${at} uses the id \"core\", which is core's own.`);\n\tcheckReservedId(value, at);\n\tif (typeof plugin.schemaVersion !== \"string\" || !isRecord(plugin.schema) || typeof plugin.init !== \"function\") fail(`Plugin \"${plugin.id}\" needs a schemaVersion, a schema, and init.`);\n\tconst provides = plugin.provides;\n\tif (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 }.`);\n\tconst cli = value.cli;\n\tif (cli !== void 0) {\n\t\tif (!isRecord(cli) || Object.keys(cli).some((key) => !CLI_KEYS.has(key))) fail(`Plugin \"${plugin.id}\" cli may only hold clientCredential and clientPlugin.`);\n\t\tif (cli.clientCredential !== void 0 && plugin.provides?.clientAuth !== true) fail(`Plugin \"${plugin.id}\" adds cli.clientCredential without declaring provides: { clientAuth: true }.`);\n\t}\n\treturn plugin;\n};\nconst checkEndpoint = (id, value) => {\n\tconst endpoint = isRecord(value) ? value : {};\n\tif (!METHODS.has(endpoint.method) || typeof endpoint.path !== \"string\" || !PATH.test(endpoint.path) || endpoint.access !== \"client\" && endpoint.access !== \"admin\" || typeof endpoint.handler !== \"function\") fail(`Plugin \"${id}\" has an endpoint that needs a method, a path like /name/:param, access \"client\" or \"admin\", and a handler.`);\n\treturn {\n\t\t...endpoint,\n\t\tplugin: id\n\t};\n};\nconst checkInstance = (plugin, instance) => {\n\tconst { id } = plugin;\n\tif (!isRecord(instance)) return fail(`Plugin \"${id}\" init returned no instance.`);\n\tif (typeof instance.then === \"function\") fail(`Plugin \"${id}\" init returned a promise; init must be synchronous.`);\n\tconst unknown = Object.keys(instance).find((key) => !INSTANCE_KEYS.has(key));\n\tif (unknown !== void 0 || !(\"api\" in instance)) fail(`Plugin \"${id}\" init must return { api, endpoints?, clientAuth? }${unknown === void 0 ? \"\" : `, not \"${unknown}\"`}.`);\n\tconst declared = plugin.provides?.clientAuth === true;\n\tconst clientAuth = instance.clientAuth;\n\tif (declared !== (clientAuth !== void 0)) fail(declared ? `Plugin \"${id}\" declares provides: { clientAuth: true } but its instance has no clientAuth.` : `Plugin \"${id}\" returns clientAuth without declaring provides: { clientAuth: true }.`);\n\tif (clientAuth !== void 0 && (typeof clientAuth.authenticate !== \"function\" || !Array.isArray(clientAuth.varyHeaders) || !clientAuth.varyHeaders.every((header) => typeof header === \"string\"))) fail(`Plugin \"${id}\" clientAuth needs varyHeaders and authenticate.`);\n\tconst endpoints = instance.endpoints ?? [];\n\tif (!Array.isArray(endpoints)) fail(`Plugin \"${id}\" endpoints must be an array.`);\n\treturn {\n\t\tapi: instance.api,\n\t\tclientAuth,\n\t\tendpoints: endpoints.map((endpoint) => checkEndpoint(id, endpoint))\n\t};\n};\n/**\n* Checks every plugin, runs each `init` once against one engine over the\n* database, and collects APIs, endpoints, and clientAuth. Core's reads run\n* on the same engine, so plugins read core through `ctx.core`.\n*/\nconst assemblePlugins = (value, database, { now = Date.now, storage = { resolveFileUrl: async () => null } } = {}) => {\n\tif (!Array.isArray(value)) return fail(\"plugins must be an array of plugins.\");\n\tconst plugins = value.map((plugin, position) => checkPlugin(plugin, `plugins[${position}]`));\n\tconst ids = /* @__PURE__ */ new Set();\n\tfor (const { id } of plugins) {\n\t\tif (ids.has(id)) fail(`Plugin \"${id}\" is registered twice.`);\n\t\tids.add(id);\n\t}\n\tclientPluginsOf(plugins);\n\tconst engine = createEngine(database, {\n\t\tplugins,\n\t\tnow\n\t});\n\tconst { onCachedRoutesChange } = database;\n\tconst core = createCoreApi(engine.core, storage, {\n\t\tnow,\n\t\t...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange: () => onCachedRoutesChange.call(database) }\n\t});\n\tconst reads = createCoreReads(engine.core, storage);\n\tconst api = {};\n\tconst endpoints = [];\n\tlet clientAuth;\n\tfor (const plugin of plugins) {\n\t\tconst instance = checkInstance(plugin, plugin.init({\n\t\t\tdb: engine.database(plugin),\n\t\t\tcore: reads,\n\t\t\tnow\n\t\t}));\n\t\tif (instance.clientAuth !== void 0) {\n\t\t\tif (clientAuth !== void 0) fail(`Plugins \"${clientAuth.plugin}\" and \"${plugin.id}\" both provide clientAuth; keep one.`);\n\t\t\tconst provided = instance.clientAuth;\n\t\t\tclientAuth = {\n\t\t\t\tplugin: plugin.id,\n\t\t\t\tvaryHeaders: provided.varyHeaders,\n\t\t\t\tauthenticate: (headers) => provided.authenticate(headers)\n\t\t\t};\n\t\t}\n\t\tendpoints.push(...instance.endpoints);\n\t\tapi[plugin.id] = instance.api;\n\t}\n\treturn {\n\t\tcore,\n\t\tapi,\n\t\tendpoints,\n\t\t...clientAuth === void 0 ? {} : { clientAuth },\n\t\tflush: engine.flush\n\t};\n};\n//#endregion\nexport { HotUpdaterConfigError, assemblePlugins };\n", "//#region src/handlerErrors.ts\nvar HandlerBadRequestError = class extends Error {\n\tname = \"HandlerBadRequestError\";\n\tconstructor(message) {\n\t\tsuper(message);\n\t}\n};\n//#endregion\nexport { HandlerBadRequestError };\n", "import { HandlerBadRequestError } from \"./handlerErrors.mjs\";\n//#region src/handlerParameters.ts\nconst decodeMaybe = (value) => {\n\tif (value === void 0) return void 0;\n\ttry {\n\t\treturn decodeURIComponent(value);\n\t} catch {\n\t\treturn value;\n\t}\n};\nconst isPlatform = (value) => value === \"ios\" || value === \"android\";\nconst requireRouteParam = (params, key) => {\n\tconst value = params[key];\n\tif (!value) throw new HandlerBadRequestError(`Missing route parameter: ${key}`);\n\treturn value;\n};\nconst requirePlatformParam = (params) => {\n\tconst platform = requireRouteParam(params, \"platform\");\n\tif (!isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);\n\treturn platform;\n};\nconst parseBooleanSearchParam = (url, key) => {\n\tconst value = url.searchParams.get(key);\n\tif (value === null) return void 0;\n\tif (value === \"true\") return true;\n\tif (value === \"false\") return false;\n\tthrow new HandlerBadRequestError(`The '${key}' query parameter must be 'true' or 'false'.`);\n};\n//#endregion\nexport { decodeMaybe, isPlatform, parseBooleanSearchParam, requirePlatformParam, requireRouteParam };\n", "import { HandlerBadRequestError } from \"./handlerErrors.mjs\";\nimport { decodeMaybe, isPlatform, parseBooleanSearchParam, requireRouteParam } from \"./handlerParameters.mjs\";\nimport { DatabaseBundleNotFoundError, DatabaseRowReferencedError, ReleaseCatalogMutationError, ReleaseManagementError } from \"@hot-updater/plugin-core\";\n//#region src/handlerAdminRoutes.ts\nconst json = (body, status = 200) => Response.json(body, { status });\nconst notFound = () => json({ error: \"Not found\" }, 404);\nconst noContent = () => new Response(null, { status: 204 });\n/** Runs `route` on core, answering its refusals. */\nconst onCore = (route) => async (params, request, api) => answer(() => route(api.core, request, params));\n/** Core's refusals as HTTP answers; anything else is a server error. */\nconst answer = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof ReleaseManagementError || error instanceof ReleaseCatalogMutationError) {\n\t\t\tconst status = error.code === \"RELEASE_NOT_FOUND\" ? 404 : error.code === \"VERSION_CONFLICT\" ? 409 : 400;\n\t\t\treturn json({\n\t\t\t\tcode: error.code,\n\t\t\t\terror: error.message\n\t\t\t}, status);\n\t\t}\n\t\tif (error instanceof DatabaseBundleNotFoundError) return json({\n\t\t\tcode: \"BUNDLE_NOT_FOUND\",\n\t\t\terror: error.message\n\t\t}, 404);\n\t\tif (error instanceof DatabaseRowReferencedError) return json({\n\t\t\tcode: \"REFERENCED\",\n\t\t\terror: error.message\n\t\t}, 409);\n\t\tthrow error;\n\t}\n};\nconst LIMITS = {\n\tdefaultValue: 50,\n\tmaxValue: 500\n};\n/** `order`, `cursor`, and `limit`: one keyset page. */\nconst keyset = (url, maxValue = LIMITS.maxValue) => {\n\tconst order = url.searchParams.get(\"order\") ?? \"desc\";\n\tif (order !== \"asc\" && order !== \"desc\") throw new HandlerBadRequestError(\"order must be 'asc' or 'desc'.\");\n\tconst limitParam = url.searchParams.get(\"limit\");\n\tconst limit = limitParam === null ? Math.min(LIMITS.defaultValue, maxValue) : Number(limitParam);\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxValue) throw new HandlerBadRequestError(`limit must be between 1 and ${maxValue}.`);\n\tconst cursor = url.searchParams.get(\"cursor\");\n\treturn {\n\t\torder,\n\t\tlimit,\n\t\t...cursor === null ? {} : { after: cursor }\n\t};\n};\n/** A page and the cursor of the next one, when the page is full. */\nconst page = (rows, { limit }, keyOf, extra = {}) => json({\n\tdata: rows,\n\t...rows.length === limit && rows.length > 0 ? { next: keyOf(rows.at(-1)) } : {},\n\t...extra\n});\nconst platformOf = (url) => {\n\tconst platform = url.searchParams.get(\"platform\");\n\tif (platform === null) return void 0;\n\tif (!isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);\n\treturn platform;\n};\n/** The one filter set a release list names; any other mix of filters is refused. */\nconst releaseFilter = (url) => {\n\tconst params = url.searchParams;\n\tconst named = [\n\t\t\"channelId\",\n\t\t\"platform\",\n\t\t\"bundleId\",\n\t\t\"scopeKey\"\n\t].filter((name) => params.has(name));\n\tconst enabled = parseBooleanSearchParam(url, \"enabled\");\n\tconst withEnabled = enabled === void 0 ? {} : { enabled };\n\tconst set = named.join(\",\");\n\tif (set === \"\" && enabled === void 0) return { kind: \"all\" };\n\tif (set === \"channelId,platform\") {\n\t\tconst platform = platformOf(url);\n\t\treturn {\n\t\t\tkind: \"channelPlatform\",\n\t\t\tchannelId: params.get(\"channelId\"),\n\t\t\tplatform,\n\t\t\t...withEnabled\n\t\t};\n\t}\n\tif (set === \"bundleId\" && enabled === void 0) return {\n\t\tkind: \"bundle\",\n\t\tbundleId: params.get(\"bundleId\")\n\t};\n\tif (set === \"scopeKey\") return {\n\t\tkind: \"scope\",\n\t\tscopeKey: params.get(\"scopeKey\"),\n\t\t...withEnabled\n\t};\n\tthrow new HandlerBadRequestError(\"Releases filter by none, channelId and platform (with enabled), bundleId, or scopeKey (with enabled).\");\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst body = async (request) => {\n\tconst value = await request.json();\n\tif (!isRecord(value)) throw new HandlerBadRequestError(\"Invalid body\");\n\treturn value;\n};\nconst isText = (value) => typeof value === \"string\" && value.length > 0;\nconst isTextOrNull = (value) => value === null || isText(value);\nconst isBundle = (bundle) => isRecord(bundle) && isText(bundle.id) && typeof bundle.platform === \"string\" && isPlatform(bundle.platform) && isTextOrNull(bundle.gitCommitHash) && isText(bundle.manifestStorageUri) && isText(bundle.manifestFileHash) && isText(bundle.assetBaseStorageUri) && (bundle.metadata === void 0 || isRecord(bundle.metadata)) && (bundle.patches === void 0 || bundle.patches === null || Array.isArray(bundle.patches));\nconst isReleasePolicy = (release) => isRecord(release) && isText(release.channel) && typeof release.enabled === \"boolean\" && typeof release.shouldForceUpdate === \"boolean\" && isTextOrNull(release.fingerprintHash) && isTextOrNull(release.targetAppVersion) && (release.message === null || typeof release.message === \"string\") && (release.rolloutCohortCount === void 0 || Number.isSafeInteger(release.rolloutCohortCount) && release.rolloutCohortCount >= 0 && release.rolloutCohortCount <= 1e3) && (release.targetCohorts === void 0 || Array.isArray(release.targetCohorts) && release.targetCohorts.every(isText));\n/** A deployment's shape: a new bundle or a stored bundle's id, and its release policy. */\nconst isDeployment = (value) => isRecord(value) && isReleasePolicy(value.release) && (\"bundleId\" in value ? isText(value.bundleId) && !(\"bundle\" in value) : isBundle(value.bundle));\n/** An expected release revision from a body number or a query string. */\nconst revisionOf = (value) => {\n\tif (value === void 0 || value === null || value === \"\") return void 0;\n\tconst revision = typeof value === \"string\" ? Number(value) : value;\n\tif (typeof revision !== \"number\" || !Number.isSafeInteger(revision) || revision < 1) throw new HandlerBadRequestError(\"Invalid expected Release revision\");\n\treturn revision;\n};\n/** A policy change's body: `{ expectedRevision?, patch }`. */\nconst policyInput = async (request) => {\n\tconst input = await body(request);\n\tif (!isRecord(input.patch)) throw new HandlerBadRequestError(\"Invalid Release policy mutation\");\n\tconst expectedRevision = revisionOf(input.expectedRevision);\n\treturn {\n\t\tpatch: input.patch,\n\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t};\n};\n/** A bundle update's body: the fields it changes, never another bundle's id. */\nconst bundleUpdateOf = (value, bundleId) => {\n\tif (!isRecord(value)) throw new HandlerBadRequestError(\"Invalid bundle payload\");\n\tconst { id, ...update } = value;\n\tif (id !== void 0 && id !== bundleId) throw new HandlerBadRequestError(\"Bundle id mismatch\");\n\treturn update;\n};\nconst scopeKeyOf = (params) => decodeMaybe(requireRouteParam(params, \"scopeKey\")) ?? \"\";\n/** Every admin route's handler, by the name `ADMIN_ROUTES` mounts it under. */\nconst createAdminRouteHandlers = () => ({\n\tlistBundles: onCore(async (core, request) => {\n\t\tconst url = new URL(request.url);\n\t\tconst input = keyset(url, 100);\n\t\tconst platform = platformOf(url);\n\t\tconst withTotal = parseBooleanSearchParam(url, \"total\") === true;\n\t\tconst [rows, total] = await Promise.all([core.listBundles({\n\t\t\t...input,\n\t\t\t...platform ? { platform } : {}\n\t\t}), withTotal ? core.countBundles(platform) : void 0]);\n\t\treturn page(rows, input, (row) => row.bundle.id, total === void 0 ? {} : { total });\n\t}),\n\tgetBundle: onCore(async (core, _request, params) => {\n\t\tconst detail = await core.getBundle(requireRouteParam(params, \"id\"));\n\t\treturn detail === null ? notFound() : json({ data: detail });\n\t}),\n\tlistReleases: onCore(async (core, request) => {\n\t\tconst url = new URL(request.url);\n\t\tconst input = keyset(url);\n\t\tconst rows = await core.listReleases({\n\t\t\t...input,\n\t\t\tfilter: releaseFilter(url)\n\t\t});\n\t\treturn page(rows, input, (row) => row.id);\n\t}),\n\tlistReleaseCatalogs: onCore(async (core, request) => {\n\t\tconst input = keyset(new URL(request.url));\n\t\tconst rows = await core.listReleaseCatalogs(input);\n\t\treturn page(rows, input, (row) => row.scope_key);\n\t}),\n\t/** With `name`, the one channel of that name: 1 read. */\n\tgetChannels: onCore(async (core, request) => {\n\t\tconst name = new URL(request.url).searchParams.get(\"name\");\n\t\tif (name === null) return json({ data: await core.listChannels() });\n\t\tconst channel = await core.findChannelByName(name);\n\t\treturn channel === null ? notFound() : json({ data: channel });\n\t}),\n\t/** The channel named in the body, created when missing. */\n\tcreateChannel: onCore(async (core, request) => {\n\t\tconst { name } = await body(request);\n\t\tif (typeof name !== \"string\" || name.trim().length === 0) throw new HandlerBadRequestError(\"Invalid channel name\");\n\t\treturn json({ data: await core.ensureChannel(name) });\n\t}),\n\t/** 204 when deleted; 404 or 409 with the reason otherwise. */\n\tdeleteChannel: onCore(async (core, _request, params) => {\n\t\tconst result = await core.deleteChannel(decodeMaybe(requireRouteParam(params, \"id\")) ?? \"\");\n\t\tif (result.deleted) return noContent();\n\t\treturn json({ data: result }, result.reason === \"not_found\" ? 404 : 409);\n\t}),\n\tgetRelease: onCore(async (core, _request, params) => {\n\t\tconst row = await core.getRelease(requireRouteParam(params, \"id\"));\n\t\treturn row === null ? notFound() : json({ data: row });\n\t}),\n\tupdateRelease: onCore(async (core, request, params) => json({ data: await core.updateReleasePolicy({\n\t\t...await policyInput(request),\n\t\treleaseId: requireRouteParam(params, \"id\")\n\t}) })),\n\tpreflightRelease: onCore(async (core, request, params) => json({ data: await core.preflightReleasePolicy({\n\t\t...await policyInput(request),\n\t\treleaseId: requireRouteParam(params, \"id\")\n\t}) })),\n\t/** Hard deletion names the release twice: in the path and as `confirm`. */\n\tdeleteRelease: onCore(async (core, request, params) => {\n\t\tconst releaseId = requireRouteParam(params, \"id\");\n\t\tconst url = new URL(request.url);\n\t\tif (url.searchParams.get(\"confirm\") !== releaseId) throw new HandlerBadRequestError(\"Release hard deletion requires confirm=<release-id>\");\n\t\tconst expectedRevision = revisionOf(url.searchParams.get(\"expectedRevision\"));\n\t\treturn json({ data: await core.deleteRelease({\n\t\t\treleaseId,\n\t\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t\t}) });\n\t}),\n\tgetReleaseCatalogRow: onCore(async (core, _request, params) => {\n\t\tconst row = await core.getReleaseCatalogRow(scopeKeyOf(params));\n\t\treturn row === null ? notFound() : json({ data: row });\n\t}),\n\trebuildReleaseCatalog: onCore(async (core, _request, params) => json({ data: await core.rebuildReleaseCatalog(scopeKeyOf(params)) })),\n\tupdateBundle: onCore(async (core, request, params) => {\n\t\tconst bundleId = requireRouteParam(params, \"id\");\n\t\tawait core.updateBundle(bundleId, bundleUpdateOf(await request.json(), bundleId));\n\t\treturn noContent();\n\t}),\n\tcountBundles: onCore(async (core, request) => json({ data: await core.countBundles(platformOf(new URL(request.url))) })),\n\tcountBundleChildren: onCore(async (core, request) => {\n\t\tconst ids = (new URL(request.url).searchParams.get(\"ids\") ?? \"\").split(\",\").filter((id) => id.length > 0);\n\t\tif (ids.length === 0 || ids.length > 100) throw new HandlerBadRequestError(\"Bundle child counts take ids=<bundle id>,... with 1 to 100 ids.\");\n\t\treturn json({ data: await core.countBundleChildren(ids) });\n\t}),\n\tlistBundleChildren: onCore(async (core, request, params) => {\n\t\tconst input = keyset(new URL(request.url));\n\t\tconst rows = await core.listPatchesFromBase(requireRouteParam(params, \"id\"), input);\n\t\treturn page(rows, input, (row) => row.bundle_id);\n\t}),\n\tfindBaseCandidates: onCore(async (core, request, params) => {\n\t\tconst url = new URL(request.url);\n\t\tconst before = url.searchParams.get(\"before\");\n\t\tconst limit = Number(url.searchParams.get(\"limit\") ?? \"3\");\n\t\tif (before === null || !Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new HandlerBadRequestError(\"Base candidates need before=<bundle id> and a limit between 1 and 100.\");\n\t\treturn json({ data: await core.findBaseBundleIds(decodeMaybe(requireRouteParam(params, \"candidateKey\")) ?? \"\", before, limit) });\n\t}),\n\tdeployReleases: onCore(async (core, request) => {\n\t\tconst { deployments } = await body(request);\n\t\tif (!Array.isArray(deployments) || deployments.length === 0 || !deployments.every(isDeployment)) throw new HandlerBadRequestError(\"Deploy needs deployments, each a bundle and its release policy.\");\n\t\treturn json({ data: await core.deploy(deployments) }, 201);\n\t}),\n\tpromoteRelease: onCore(async (core, request, params) => {\n\t\tconst input = await body(request);\n\t\tif (typeof input.targetChannel !== \"string\" || input.action !== void 0 && input.action !== \"copy\" && input.action !== \"move\") throw new HandlerBadRequestError(\"Invalid Release promotion\");\n\t\tconst expectedRevision = revisionOf(input.expectedRevision);\n\t\treturn json({ data: await core.promoteRelease({\n\t\t\treleaseId: requireRouteParam(params, \"id\"),\n\t\t\ttargetChannel: input.targetChannel,\n\t\t\t...input.action === void 0 ? {} : { action: input.action },\n\t\t\t...expectedRevision === void 0 ? {} : { expectedRevision }\n\t\t}) });\n\t}),\n\tpreflightReleaseCatalogRebuild: onCore(async (core, _request, params) => json({ data: await core.preflightReleaseCatalogRebuild(scopeKeyOf(params)) })),\n\tdeleteBundles: onCore(async (core, request) => {\n\t\tconst { ids } = await body(request);\n\t\tif (!Array.isArray(ids) || !ids.every((id) => typeof id === \"string\" && id.length > 0)) throw new HandlerBadRequestError(\"Bundle deletion needs ids\");\n\t\tawait core.deleteBundles(ids);\n\t\treturn noContent();\n\t})\n});\n/** The admin mount's routes, by the handler that serves each. */\nconst ADMIN_ROUTES = [\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases\",\n\t\thandler: \"deployReleases\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases/:id/promote\",\n\t\thandler: \"promoteRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"getRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/releases\",\n\t\thandler: \"listReleases\"\n\t},\n\t{\n\t\tmethod: \"PATCH\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"updateRelease\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/releases/:id/preflight\",\n\t\thandler: \"preflightRelease\"\n\t},\n\t{\n\t\tmethod: \"DELETE\",\n\t\tpath: \"/releases/:id\",\n\t\thandler: \"deleteRelease\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/release-catalogs/:scopeKey\",\n\t\thandler: \"getReleaseCatalogRow\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/release-catalogs\",\n\t\thandler: \"listReleaseCatalogs\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/release-catalogs/:scopeKey/rebuild\",\n\t\thandler: \"rebuildReleaseCatalog\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/release-catalogs/:scopeKey/preflight\",\n\t\thandler: \"preflightReleaseCatalogRebuild\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/channels\",\n\t\thandler: \"getChannels\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/channels\",\n\t\thandler: \"createChannel\"\n\t},\n\t{\n\t\tmethod: \"DELETE\",\n\t\tpath: \"/channels/:id\",\n\t\thandler: \"deleteChannel\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/count\",\n\t\thandler: \"countBundles\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/child-counts\",\n\t\thandler: \"countBundleChildren\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/:id\",\n\t\thandler: \"getBundle\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles\",\n\t\thandler: \"listBundles\"\n\t},\n\t{\n\t\tmethod: \"PATCH\",\n\t\tpath: \"/bundles/:id\",\n\t\thandler: \"updateBundle\"\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: \"/bundles/delete\",\n\t\thandler: \"deleteBundles\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/bundles/:id/children\",\n\t\thandler: \"listBundleChildren\"\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: \"/base-candidates/:candidateKey\",\n\t\thandler: \"findBaseCandidates\"\n\t}\n];\n//#endregion\nexport { ADMIN_ROUTES, answer, createAdminRouteHandlers };\n", "import { requirePlatformParam, requireRouteParam } from \"./handlerParameters.mjs\";\nimport { canonicalizeAppVersion } from \"@hot-updater/plugin-core\";\nimport { createReleaseCatalogScopeKey } from \"@hot-updater/protocol\";\n//#region src/handlerReleaseCatalogRoutes.ts\nconst CATALOG_CONTENT_TYPE = \"application/vnd.hot-updater.release-catalog+json; version=1\";\nconst ARTIFACT_CONTENT_TYPE = \"application/vnd.hot-updater.artifact+json; version=1\";\nconst ORIGIN_CACHE_TTL_MS = 5e3;\nconst ORIGIN_CACHE_MAX_ENTRIES = 128;\n/** Marks the 404 of a scope that has no catalog. */\nconst NO_CATALOG_HEADER = \"x-hot-updater-catalog\";\n/** A shared cache keeps a catalog, or a scope's lack of one, five seconds. */\nconst CATALOG_CACHE_CONTROL = \"public, max-age=0, s-maxage=5\";\n/**\n* The same five seconds for a CDN that reads `CDN-Cache-Control` (RFC 9213),\n* such as Cloudflare's Workers Cache, which then ignores `Cache-Control`.\n* `s-maxage` forbids serving stale, so there an expired catalog held requests\n* at that location until the origin answered. Here, for five more seconds,\n* the CDN answers with the expired copy while it revalidates in the\n* background. `stale-if-error=0` keeps origin errors visible: without it,\n* Cloudflare serves a stale copy on error indefinitely.\n*\n* A device can see a catalog up to 15 seconds after a deploy or a Roll back\n* replaced it: the origin's 5-second catalog memo, then 5 seconds fresh and\n* 5 stale at the CDN. A revoked API key can read a cached catalog up to\n* 10 seconds. Devices and caches that don't read the header keep\n* `Cache-Control`.\n*/\nconst CATALOG_CDN_CACHE_CONTROL = \"public, max-age=5, stale-while-revalidate=5, stale-if-error=0\";\nconst privateNotFound = () => Response.json({ error: \"Not found\" }, {\n\tstatus: 404,\n\theaders: { \"cache-control\": \"private, no-store\" }\n});\nconst badRequest = (error) => Response.json({ error }, {\n\tstatus: 400,\n\theaders: { \"cache-control\": \"private, no-store\" }\n});\n/**\n* A 400 for a catalog path whose scope is malformed, such as a channel name\n* where its base64url key belongs; null for a well-formed scope.\n*/\nconst invalidScope = (input) => {\n\ttry {\n\t\tcreateReleaseCatalogScopeKey(input);\n\t\treturn null;\n\t} catch (error) {\n\t\treturn badRequest(error instanceof Error ? error.message : \"Invalid Release Catalog scope\");\n\t}\n};\n/**\n* A scope with no catalog yet, such as a store version before its first\n* OTA release: cached like a catalog, so its update checks don't all reach\n* the origin, and it holds nothing an API key protects. The header tells it\n* apart from a 404 for a wrong URL: clients read it as \"no update\", and\n* doctor as a live catalog route.\n*/\nconst missingCatalog = () => Response.json({ error: \"Not found\" }, {\n\tstatus: 404,\n\theaders: {\n\t\t\"cache-control\": CATALOG_CACHE_CONTROL,\n\t\t\"cdn-cache-control\": CATALOG_CDN_CACHE_CONTROL,\n\t\tvary: \"Accept-Encoding\",\n\t\t[NO_CATALOG_HEADER]: \"none\"\n\t}\n});\nconst responseHash = async (body) => {\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(body));\n\treturn [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n};\nconst catalogResponse = async (catalog, request) => {\n\tif (catalog === null) return missingCatalog();\n\tconst body = JSON.stringify(catalog);\n\tconst etag = `\"sha256:${await responseHash(body)}\"`;\n\tconst headers = {\n\t\t\"cache-control\": CATALOG_CACHE_CONTROL,\n\t\t\"cdn-cache-control\": CATALOG_CDN_CACHE_CONTROL,\n\t\t\"content-type\": CATALOG_CONTENT_TYPE,\n\t\tetag,\n\t\tvary: \"Accept-Encoding\"\n\t};\n\tif (request.headers.get(\"if-none-match\") === etag) return new Response(null, {\n\t\theaders,\n\t\tstatus: 304\n\t});\n\treturn new Response(body, {\n\t\theaders,\n\t\tstatus: 200\n\t});\n};\nconst createReleaseCatalogRouteHandlers = () => {\n\tconst cache = /* @__PURE__ */ new Map();\n\tconst inFlight = /* @__PURE__ */ new Map();\n\tconst loadCatalog = async (key, load) => {\n\t\tconst cached = cache.get(key);\n\t\tif (cached !== void 0 && cached.expiresAt > Date.now()) {\n\t\t\tcache.delete(key);\n\t\t\tcache.set(key, cached);\n\t\t\treturn cached.catalog;\n\t\t}\n\t\tif (cached !== void 0) cache.delete(key);\n\t\tconst pending = inFlight.get(key);\n\t\tif (pending !== void 0) return pending;\n\t\tconst next = load().then((catalog) => {\n\t\t\tif (catalog !== null) {\n\t\t\t\tcache.set(key, {\n\t\t\t\t\tcatalog,\n\t\t\t\t\texpiresAt: Date.now() + ORIGIN_CACHE_TTL_MS\n\t\t\t\t});\n\t\t\t\twhile (cache.size > ORIGIN_CACHE_MAX_ENTRIES) {\n\t\t\t\t\tconst oldestKey = cache.keys().next().value;\n\t\t\t\t\tif (oldestKey === void 0) break;\n\t\t\t\t\tcache.delete(oldestKey);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn catalog;\n\t\t});\n\t\tinFlight.set(key, next);\n\t\ttry {\n\t\t\treturn await next;\n\t\t} finally {\n\t\t\tinFlight.delete(key);\n\t\t}\n\t};\n\treturn {\n\t\tappVersionReleaseCatalog: async (params, request, { core }) => {\n\t\t\tconst rawAppVersion = requireRouteParam(params, \"appVersion\");\n\t\t\tconst appVersion = canonicalizeAppVersion(rawAppVersion);\n\t\t\tif (appVersion === null || appVersion !== rawAppVersion) return badRequest(\"Invalid app version\");\n\t\t\tconst input = {\n\t\t\t\tappVersion,\n\t\t\t\tchannelKey: requireRouteParam(params, \"channelKey\"),\n\t\t\t\tplatform: requirePlatformParam(params),\n\t\t\t\tstrategy: \"APP_VERSION\"\n\t\t\t};\n\t\t\tconst invalid = invalidScope(input);\n\t\t\tif (invalid) return invalid;\n\t\t\treturn catalogResponse(await loadCatalog(`app-version:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);\n\t\t},\n\t\tfingerprintReleaseCatalog: async (params, request, { core }) => {\n\t\t\tconst input = {\n\t\t\t\tchannelKey: requireRouteParam(params, \"channelKey\"),\n\t\t\t\tfingerprintHash: requireRouteParam(params, \"fingerprintHash\"),\n\t\t\t\tplatform: requirePlatformParam(params),\n\t\t\t\tstrategy: \"FINGERPRINT\"\n\t\t\t};\n\t\t\tconst invalid = invalidScope(input);\n\t\t\tif (invalid) return invalid;\n\t\t\treturn catalogResponse(await loadCatalog(`fingerprint:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);\n\t\t},\n\t\tartifactV1: async (params, _request, { core }) => {\n\t\t\tconst info = await core.getArtifactInfo(requireRouteParam(params, \"targetBundleId\"), requireRouteParam(params, \"currentBundleId\"), 1);\n\t\t\tif (info === null) return privateNotFound();\n\t\t\treturn new Response(JSON.stringify(info), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: {\n\t\t\t\t\t\"cache-control\": \"private, no-store\",\n\t\t\t\t\t\"content-type\": ARTIFACT_CONTENT_TYPE\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n//#endregion\nexport { createReleaseCatalogRouteHandlers };\n", "//#region src/internalRouter.ts\nconst normalizePath = (path) => {\n\tif (!path) return \"/\";\n\tif (path === \"/\") return path;\n\tconst withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\treturn withLeadingSlash.endsWith(\"/\") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;\n};\nconst toSegments = (path) => {\n\tconst normalized = normalizePath(path);\n\treturn normalized === \"/\" ? [] : normalized.slice(1).split(\"/\");\n};\nfunction createRouter() {\n\treturn { routes: [] };\n}\nfunction addRoute(router, method, path, data) {\n\tconst segments = toSegments(path);\n\tconst paramNames = segments.filter((segment) => segment.startsWith(\":\")).map((segment) => segment.slice(1));\n\trouter.routes.push({\n\t\tdata,\n\t\tmethod: method.toUpperCase(),\n\t\tparamNames,\n\t\tsegments\n\t});\n}\nfunction findRoute(router, method, path) {\n\tconst normalizedMethod = method.toUpperCase();\n\tconst pathSegments = toSegments(path);\n\tfor (const route of router.routes) {\n\t\tif (route.method !== normalizedMethod) continue;\n\t\tif (route.segments.length !== pathSegments.length) continue;\n\t\tconst params = {};\n\t\tlet matched = true;\n\t\tfor (let index = 0; index < route.segments.length; index += 1) {\n\t\t\tconst routeSegment = route.segments[index];\n\t\t\tconst pathSegment = pathSegments[index];\n\t\t\tif (routeSegment.startsWith(\":\")) {\n\t\t\t\tparams[routeSegment.slice(1)] = pathSegment;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (routeSegment !== pathSegment) {\n\t\t\t\tmatched = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (matched) return {\n\t\t\tdata: route.data,\n\t\t\tparams\n\t\t};\n\t}\n}\n//#endregion\nexport { addRoute, createRouter, findRoute };\n", "import { HotUpdaterConfigError } from \"./assembly/configError.mjs\";\nimport { HandlerBadRequestError } from \"./handlerErrors.mjs\";\nimport { ADMIN_ROUTES, createAdminRouteHandlers } from \"./handlerAdminRoutes.mjs\";\nimport { createReleaseCatalogRouteHandlers } from \"./handlerReleaseCatalogRoutes.mjs\";\nimport { createVersionRouteHandlers } from \"./handlerVersionRoutes.mjs\";\nimport { addRoute, createRouter, findRoute } from \"./internalRouter.mjs\";\nimport { HotUpdaterSchemaMigrationRequiredError } from \"@hot-updater/plugin-core\";\n//#region src/handler.ts\nconst withPrivateNoStore = (response) => {\n\tconst headers = new Headers(response.headers);\n\theaders.set(\"cache-control\", \"private, no-store\");\n\treturn new Response(response.body, {\n\t\theaders,\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText\n\t});\n};\nconst errorResponse = (error, status) => Response.json({ error }, {\n\theaders: { \"cache-control\": \"private, no-store\" },\n\tstatus\n});\n/** `/version` never passes through the client policy. */\nconst PUBLIC_CLIENT_ROUTES = /* @__PURE__ */ new Set([\"version\"]);\nconst routesOf = Symbol.for(\"@hot-updater/server/routes\");\nconst withVary = (response, varyHeaders) => {\n\tconst cacheControl = response.headers.get(\"cache-control\") ?? \"\";\n\tif (varyHeaders.length === 0 || cacheControl === \"\" || /private|no-store/u.test(cacheControl)) return response;\n\tconst headers = new Headers(response.headers);\n\theaders.set(\"vary\", [response.headers.get(\"vary\"), ...varyHeaders].filter(Boolean).join(\", \"));\n\treturn new Response(response.body, {\n\t\theaders,\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText\n\t});\n};\nconst createRequestHandler = ({ api, clientPolicy, privateResponses = false, routeHandlers, router }) => async (request) => {\n\ttry {\n\t\tconst match = findRoute(router, request.method, new URL(request.url).pathname);\n\t\tif (!match) return errorResponse(\"Not found\", 404);\n\t\tconst guarded = clientPolicy !== void 0 && !PUBLIC_CLIENT_ROUTES.has(match.data);\n\t\tif (guarded) {\n\t\t\tlet authenticated;\n\t\t\ttry {\n\t\t\t\tauthenticated = await clientPolicy.authenticate(request);\n\t\t\t} catch {\n\t\t\t\treturn errorResponse(\"Service unavailable\", 503);\n\t\t\t}\n\t\t\tif (!authenticated) return errorResponse(\"Unauthorized\", 401);\n\t\t}\n\t\tconst handler = routeHandlers[match.data];\n\t\tif (!handler) return errorResponse(\"Handler not found\", 500);\n\t\tconst response = await handler(match.params, request, api);\n\t\tif (privateResponses) return withPrivateNoStore(response);\n\t\treturn guarded ? withVary(response, clientPolicy.varyHeaders) : response;\n\t} catch (error) {\n\t\tif (error instanceof HandlerBadRequestError) return errorResponse(error.message, 400);\n\t\tif (error instanceof HotUpdaterSchemaMigrationRequiredError) {\n\t\t\tconsole.error(error.message);\n\t\t\treturn errorResponse(\"Service unavailable\", 503);\n\t\t}\n\t\tconsole.error(\"Hot Updater handler error:\", error);\n\t\treturn Response.json({ error: \"Internal server error\" }, {\n\t\t\theaders: { \"cache-control\": \"private, no-store\" },\n\t\t\tstatus: 500\n\t\t});\n\t}\n};\nfunction createHotUpdaterHandlers({ api, clientPolicy, endpoints = [], plugins = [] }) {\n\tconst routeHandlers = {\n\t\t...createVersionRouteHandlers(plugins),\n\t\t...createReleaseCatalogRouteHandlers(),\n\t\t...createAdminRouteHandlers()\n\t};\n\tconst routes = [];\n\tconst shapes = /* @__PURE__ */ new Map();\n\tconst mount = (router, admin) => (method, path, handler) => {\n\t\tconst shape = `${admin ? \"admin\" : \"client\"} ${method} ${path.replaceAll(/:[^/]+/gu, \":\")}`;\n\t\tconst taken = shapes.get(shape);\n\t\tif (taken !== void 0) throw new HotUpdaterConfigError(`${handler} (${method} ${path}) collides with ${taken} on handlers.${admin ? \"admin\" : \"client\"}.`);\n\t\tshapes.set(shape, handler);\n\t\taddRoute(router, method, path, handler);\n\t\troutes.push({\n\t\t\tmethod,\n\t\t\tpath,\n\t\t\taccess: admin ? \"admin\" : PUBLIC_CLIENT_ROUTES.has(handler) ? \"public\" : \"client\"\n\t\t});\n\t};\n\tconst clientRouter = createRouter();\n\tconst addClientRoute = mount(clientRouter, false);\n\taddClientRoute(\"GET\", \"/version\", \"version\");\n\taddClientRoute(\"GET\", \"/release-catalogs/app-version/:platform/:channelKey/:appVersion\", \"appVersionReleaseCatalog\");\n\taddClientRoute(\"GET\", \"/release-catalogs/fingerprint/:platform/:channelKey/:fingerprintHash\", \"fingerprintReleaseCatalog\");\n\taddClientRoute(\"GET\", \"/artifacts/v1/:targetBundleId/from/:currentBundleId\", \"artifactV1\");\n\tconst adminRouter = createRouter();\n\tconst addAdminRoute = mount(adminRouter, true);\n\taddAdminRoute(\"GET\", \"/version\", \"adminVersion\");\n\tfor (const route of ADMIN_ROUTES) addAdminRoute(route.method, route.path, route.handler);\n\tfor (const endpoint of endpoints) {\n\t\tconst name = `plugin ${endpoint.plugin}: ${endpoint.method} ${endpoint.path}`;\n\t\trouteHandlers[name] = (params, request) => endpoint.handler(request, params);\n\t\t(endpoint.access === \"admin\" ? addAdminRoute : addClientRoute)(endpoint.method, endpoint.path, name);\n\t}\n\tconst handlers = {\n\t\tclient: createRequestHandler({\n\t\t\tapi,\n\t\t\t...clientPolicy === void 0 ? {} : { clientPolicy },\n\t\t\trouteHandlers,\n\t\t\trouter: clientRouter\n\t\t}),\n\t\tadmin: createRequestHandler({\n\t\t\tapi,\n\t\t\tprivateResponses: true,\n\t\t\trouteHandlers,\n\t\t\trouter: adminRouter\n\t\t})\n\t};\n\tObject.defineProperty(handlers, routesOf, { value: Object.freeze(routes) });\n\treturn Object.freeze(handlers);\n}\n//#endregion\nexport { createHotUpdaterHandlers };\n", "//#region src/storageAccess.ts\n/** A URL devices download from, which only an absolute HTTP(S) URL can be. */\nconst assertRemoteUrl = (value) => {\n\tlet protocol;\n\ttry {\n\t\tprotocol = new URL(value).protocol;\n\t} catch {}\n\tif (protocol !== \"http:\" && protocol !== \"https:\") throw new Error(\"Storage getDownloadUrl must resolve to an absolute HTTP(S) URL.\");\n\treturn value;\n};\nconst getStorageProtocol = (storageUri) => new URL(storageUri).protocol.replace(\":\", \"\");\nconst isRemoteUrlProtocol = (protocol) => protocol === \"http\" || protocol === \"https\";\n/**\n* Reads and download URLs over the server's storage, for the URIs of its\n* protocol; an HTTP(S) URI is used as it is.\n*/\nconst createStorageAccess = (storageAdapter) => {\n\tconst findStorage = (protocol) => storageAdapter.protocol === protocol ? storageAdapter : void 0;\n\tconst readStorageResponse = async (storageUri) => {\n\t\tconst protocol = getStorageProtocol(storageUri);\n\t\tconst storage = findStorage(protocol);\n\t\tif (storage) {\n\t\t\tif (!storage.get) return null;\n\t\t\treturn (await storage.get({ storageUri })).response;\n\t\t}\n\t\tif (isRemoteUrlProtocol(protocol)) {\n\t\t\tconst response = await fetch(storageUri);\n\t\t\treturn response.ok ? response : null;\n\t\t}\n\t\tthrow new Error(`No storage adapter for protocol: ${protocol}`);\n\t};\n\tconst resolveFileUrl = async (storageUri) => {\n\t\tif (!storageUri) return null;\n\t\tconst protocol = getStorageProtocol(storageUri);\n\t\tconst storage = findStorage(protocol);\n\t\tif (!storage) {\n\t\t\tif (isRemoteUrlProtocol(protocol)) return storageUri;\n\t\t\tthrow new Error(`No storage adapter for protocol: ${protocol}`);\n\t\t}\n\t\tif (!storage.getDownloadUrl) return null;\n\t\tconst { url: downloadUrl } = await storage.getDownloadUrl({ storageUri });\n\t\treturn assertRemoteUrl(downloadUrl);\n\t};\n\tconst readStorageText = async (storageUri) => {\n\t\treturn (await readStorageResponse(storageUri))?.text() ?? null;\n\t};\n\treturn {\n\t\treadStorageText,\n\t\tresolveFileUrl\n\t};\n};\n//#endregion\nexport { createStorageAccess };\n", "import { HotUpdaterConfigError } from \"./assembly/configError.mjs\";\nimport { clientPluginsOf } from \"./assembly/clientPlugins.mjs\";\nimport { assemblePlugins } from \"./assembly/assemblePlugins.mjs\";\nimport { createHotUpdaterHandlers } from \"./handler.mjs\";\nimport { createStorageAccess } from \"./storageAccess.mjs\";\nimport { assertStorageOperations } from \"@hot-updater/plugin-core\";\n//#region src/createHotUpdaterCore.ts\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\nconst isAdapter = (value) => isRecord(value) && [\n\t\"fits\",\n\t\"get\",\n\t\"query\",\n\t\"write\"\n].every((method) => typeof value[method] === \"function\");\n/** The configured database, when it runs on the storage engine. */\nconst databaseOf = (value) => {\n\tif (isRecord(value) && typeof value.name === \"string\") {\n\t\tif (isAdapter(value.adapter)) return value;\n\t\tif (\"core\" in value && \"fetchAdmin\" in value) throw new HotUpdaterConfigError(\"standaloneRepository reaches a server's admin API from the CLI and console. createHotUpdater needs the server's own database, such as kyselyAdapter(...).\");\n\t}\n\tthrow new HotUpdaterConfigError(\"database must be a Hot Updater database adapter, such as kyselyAdapter(...) or postgres(...).\");\n};\n/** The configured storage, when it is a storage adapter. */\nconst storageOf = (value) => {\n\tif (isRecord(value) && typeof value.name === \"string\" && typeof value.protocol === \"string\") return value;\n\tthrow new HotUpdaterConfigError(\"storage must be a storage adapter, such as s3Storage(...): the one hot-updater.config.ts uploads with.\");\n};\n/** `\"public\"`, or nothing. */\nconst isPublic = (value) => {\n\tif (value === void 0) return false;\n\tif (value === \"public\") return true;\n\tthrow new HotUpdaterConfigError(\"clientAccess must be \\\"public\\\"; to protect client routes, add a plugin that provides clientAuth to plugins.\");\n};\nfunction createHotUpdater(options) {\n\tconst database = databaseOf(options.database);\n\tconst storage = storageOf(options.storage);\n\tconst { readStorageText, resolveFileUrl } = createStorageAccess(storage);\n\tconst publicClients = isPublic(options.clientAccess);\n\tconst configured = Object.freeze([...options.plugins ?? []]);\n\tconst plugins = assemblePlugins(configured, database, { storage: {\n\t\treadStorageText,\n\t\tresolveFileUrl\n\t} });\n\tconst clientPlugins = Object.freeze(clientPluginsOf(configured));\n\tconst clientAuth = plugins.clientAuth;\n\tif (clientAuth !== void 0 && publicClients) throw new HotUpdaterConfigError(`Plugin \"${clientAuth.plugin}\" provides clientAuth, so remove clientAccess.`);\n\tif (clientAuth === void 0 && !publicClients) throw new HotUpdaterConfigError(\"Set clientAccess to \\\"public\\\", or add a plugin that provides clientAuth.\");\n\tconst varyHeaders = Object.freeze((clientAuth?.varyHeaders ?? []).map((header) => header.toLowerCase()));\n\tconst clientPolicy = clientAuth === void 0 ? void 0 : {\n\t\tvaryHeaders,\n\t\tauthenticate: (request) => clientAuth.authenticate(request.headers)\n\t};\n\tconst handlers = createHotUpdaterHandlers({\n\t\tapi: { core: plugins.core },\n\t\t...clientPolicy === void 0 ? {} : { clientPolicy },\n\t\tendpoints: plugins.endpoints,\n\t\tplugins: Object.keys(plugins.api)\n\t});\n\tlet serving = false;\n\treturn {\n\t\tadapterName: database.name,\n\t\tget handlers() {\n\t\t\tif (!serving) {\n\t\t\t\tassertStorageOperations(storage, [\"get\", \"getDownloadUrl\"]);\n\t\t\t\tserving = true;\n\t\t\t}\n\t\t\treturn handlers;\n\t\t},\n\t\tcore: plugins.core,\n\t\tapi: plugins.api,\n\t\tflush: plugins.flush,\n\t\tdatabase,\n\t\tstorage,\n\t\tplugins: configured,\n\t\tclientPlugins,\n\t\tclientEndpoints: Object.freeze(plugins.endpoints.filter((endpoint) => endpoint.access === \"client\").map(({ plugin, method, path }) => Object.freeze({\n\t\t\tplugin,\n\t\t\tmethod,\n\t\t\tpath\n\t\t}))),\n\t\t...clientAuth === void 0 ? {} : { clientAuth: Object.freeze({\n\t\t\tplugin: clientAuth.plugin,\n\t\t\tvaryHeaders\n\t\t}) }\n\t};\n}\n//#endregion\nexport { createHotUpdater };\n", "//#region src/server/apiKeys.ts\nconst API_KEY_HEADER_NAME = \"x-api-key\";\nconst BASE64URL_32_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst bytesToBase64Url = (bytes) => {\n\tlet binary = \"\";\n\tfor (const byte of bytes) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst isApiKey = (value) => {\n\tif (!BASE64URL_32_PATTERN.test(value)) return false;\n\ttry {\n\t\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\t\tconst binary = atob(`${base64}=`);\n\t\tconst bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));\n\t\treturn bytes.byteLength === 32 && bytesToBase64Url(bytes) === value;\n\t} catch {\n\t\treturn false;\n\t}\n};\nconst normalizeApiKeyHeaderName = (value = API_KEY_HEADER_NAME) => {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(\"apiKeys({ headerName }) must name a valid header.\");\n\ttry {\n\t\tconst headers = new Headers();\n\t\theaders.set(value, \"\");\n\t\treturn headers.keys().next().value;\n\t} catch {\n\t\tthrow new TypeError(\"apiKeys({ headerName }) must name a valid header.\");\n\t}\n};\nconst hashApiKey = async (apiKey) => {\n\tif (!isApiKey(apiKey)) throw new TypeError(\"API key must be a canonical 32-byte base64url value.\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(apiKey));\n\treturn bytesToBase64Url(new Uint8Array(digest));\n};\nconst apiKeyId = () => {\n\tconst bytes = /* @__PURE__ */ new Uint8Array(16);\n\tcrypto.getRandomValues(bytes);\n\treturn `api-${bytesToBase64Url(bytes)}`;\n};\nconst normalizeApiKeyName = (name) => {\n\tconst normalized = name.trim();\n\tif (normalized.length === 0 || normalized.length > 64 || /[\\p{Cc}\\p{Cf}]/u.test(normalized)) throw new TypeError(\"API key names must contain 1-64 visible characters.\");\n\treturn normalized;\n};\nconst toApiKeyMetadata = ({ hash: _hash, ...metadata }) => Object.freeze(metadata);\nconst registerApiKey = async (input) => {\n\tconst hash = await hashApiKey(input.apiKey);\n\tconst createdAtMs = input.createdAtMs ?? Date.now();\n\tif (!Number.isSafeInteger(createdAtMs) || createdAtMs < 0) throw new TypeError(\"API key creation time must be non-negative.\");\n\tconst record = Object.freeze({\n\t\tcreated_at_ms: createdAtMs,\n\t\thash,\n\t\tid: apiKeyId(),\n\t\tname: normalizeApiKeyName(input.name),\n\t\tprefix: input.apiKey.slice(0, 6),\n\t\trevoked_at_ms: null,\n\t\trole: \"client\"\n\t});\n\tif (await input.apiKeys.create(record) === \"existing\") {\n\t\tconst existing = await input.apiKeys.findByHash(hash);\n\t\tif (existing === null || existing.revoked_at_ms !== null) throw new Error(\"The API key has been revoked.\");\n\t\treturn Object.freeze({\n\t\t\tapiKey: input.apiKey,\n\t\t\trecord: toApiKeyMetadata(existing)\n\t\t});\n\t}\n\treturn Object.freeze({\n\t\tapiKey: input.apiKey,\n\t\trecord: toApiKeyMetadata(record)\n\t});\n};\nconst createApiKey = (input) => {\n\tconst bytes = /* @__PURE__ */ new Uint8Array(32);\n\tcrypto.getRandomValues(bytes);\n\treturn registerApiKey({\n\t\tapiKey: bytesToBase64Url(bytes),\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t});\n};\n/**\n* Provisions the client API key used by managed init.\n*\n* A saved plaintext key is registered idempotently; otherwise a new key is\n* created. Callers must persist or display the returned plaintext because the\n* database stores only its hash.\n*/\nconst provisionApiKey = (input) => {\n\tconst existingApiKey = input.existingApiKey?.trim();\n\treturn existingApiKey ? registerApiKey({\n\t\tapiKey: existingApiKey,\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t}) : createApiKey({\n\t\tapiKeys: input.apiKeys,\n\t\tname: input.name\n\t});\n};\nconst authenticateApiKey = async (input) => {\n\tconst apiKey = input.request.headers.get(normalizeApiKeyHeaderName(input.headerName));\n\tif (apiKey === null || !isApiKey(apiKey)) return false;\n\tconst hash = await hashApiKey(apiKey);\n\tconst record = await input.apiKeys.findByHash(hash);\n\treturn record !== null && record.hash === hash && record.role === \"client\" && record.revoked_at_ms === null;\n};\nconst createApiKeyManagement = (input) => Object.freeze({\n\tasync create({ name }) {\n\t\tconst created = await createApiKey({\n\t\t\tapiKeys: input.apiKeys,\n\t\t\tname\n\t\t});\n\t\treturn Object.freeze({\n\t\t\tapiKey: created.apiKey,\n\t\t\trecord: created.record\n\t\t});\n\t},\n\tasync list() {\n\t\treturn Object.freeze((await input.apiKeys.list()).map(toApiKeyMetadata));\n\t},\n\tasync revoke({ id }) {\n\t\tconst record = await input.apiKeys.revoke({\n\t\t\tid,\n\t\t\trevokedAtMs: Date.now()\n\t\t});\n\t\treturn record === null ? null : toApiKeyMetadata(record);\n\t}\n});\n//#endregion\nexport { API_KEY_HEADER_NAME, apiKeyId, authenticateApiKey, createApiKey, createApiKeyManagement, hashApiKey, isApiKey, normalizeApiKeyHeaderName, normalizeApiKeyName, provisionApiKey, registerApiKey };\n", "//#region src/server/cli.ts\n/** The environment variable init stores the app's API key in. */\nconst API_KEY_ENV = \"HOT_UPDATER_API_KEY\";\n/** A new API key: 32 random bytes, base64url, as the plugin creates them. */\nconst generateApiKey = () => {\n\tconst bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));\n\treturn btoa(String.fromCharCode(...bytes)).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\n/** The API key that init provisions for an app, sent in `headerName`. */\nconst apiKeysCli = (headerName) => ({ clientCredential: {\n\tlabel: \"API key\",\n\theader: headerName,\n\tenv: API_KEY_ENV,\n\tgenerate: generateApiKey,\n\tprovision: async (api, { existing, name }) => (await api.provision({\n\t\t...existing === void 0 ? {} : { existingApiKey: existing },\n\t\tname\n\t})).apiKey\n} });\n//#endregion\nexport { API_KEY_ENV, apiKeysCli };\n", "import { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/server/model.ts\nconst toRow = (row) => ({\n\tid: row.id,\n\thash: row.hash,\n\tname: row.name,\n\tprefix: row.prefix,\n\trole: row.role,\n\tcreated_at_ms: row.created_at_ms,\n\trevoked_at_ms: row.revoked_at_ms\n});\n/** Today's `ApiKeyModel` on the engine: one unique read by hash, keyed writes. */\nconst createApiKeyModel = (db) => ({\n\tasync create(row) {\n\t\ttry {\n\t\t\treturn await db.transaction(async (tx) => {\n\t\t\t\tif (await tx.findOne(\"api_keys\", { hash: row.hash }) !== null) return \"existing\";\n\t\t\t\ttx.create(\"api_keys\", row);\n\t\t\t\treturn \"created\";\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseConstraintError && error.reason === \"unique\") return \"existing\";\n\t\t\tthrow error;\n\t\t}\n\t},\n\tasync findByHash(hash) {\n\t\tconst row = await db.findOne(\"api_keys\", { hash });\n\t\treturn row === null ? null : toRow(row);\n\t},\n\t/** Every key, newest first, then by id; the whole list is the result. */\n\tasync list() {\n\t\tconst rows = [];\n\t\tlet cursor;\n\t\tdo {\n\t\t\tconst page = await db.findMany(\"api_keys\", {\n\t\t\t\tindex: \"byCreated\",\n\t\t\t\twhere: {},\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit: 500,\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\trows.push(...page.rows.map(toRow));\n\t\t\tcursor = page.next;\n\t\t} while (cursor !== void 0);\n\t\treturn rows.sort((left, right) => right.created_at_ms - left.created_at_ms || (left.id < right.id ? -1 : left.id > right.id ? 1 : 0));\n\t},\n\trevoke: ({ id, revokedAtMs }) => db.transaction(async (tx) => {\n\t\tconst row = await tx.findOne(\"api_keys\", { id });\n\t\tif (row === null) return null;\n\t\ttx.update(\"api_keys\", row, { revoked_at_ms: revokedAtMs });\n\t\treturn toRow({\n\t\t\t...row,\n\t\t\trevoked_at_ms: revokedAtMs\n\t\t});\n\t})\n});\n//#endregion\nexport { createApiKeyModel };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"apiKeys\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "import { defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\n/** v1's `api_keys` columns; the plaintext key is never stored, only its SHA-256 digest. */\nconst apiKeysSchema = { api_keys: defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\thash: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64,\n\t\tunique: true\n\t},\n\tname: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64\n\t},\n\tprefix: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\trole: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tcreated_at_ms: { type: \"integer\" },\n\trevoked_at_ms: {\n\t\ttype: \"integer\",\n\t\trequired: false\n\t}\n}, {\n\tkey: [\"id\"],\n\tindexes: { byCreated: {\n\t\teq: [],\n\t\tsort: [\"created_at_ms\"]\n\t} }\n}) };\n//#endregion\nexport { apiKeysSchema };\n", "import { API_KEY_HEADER_NAME, authenticateApiKey, createApiKeyManagement, normalizeApiKeyHeaderName, provisionApiKey, registerApiKey } from \"./apiKeys.mjs\";\nimport { apiKeysCli } from \"./cli.mjs\";\nimport { createApiKeyModel } from \"./model.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { apiKeysSchema } from \"./schema.mjs\";\nimport { definePlugin } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\n/**\n* API keys: protects client routes with keys whose SHA-256 digests\n* are stored, and manages them in-process.\n*/\nconst apiKeys = (options = {}) => {\n\tconst headerName = normalizeApiKeyHeaderName(options.headerName ?? \"x-api-key\");\n\tconst plugin = definePlugin({\n\t\tid: \"apiKeys\",\n\t\tnamespace: false,\n\t\tprovides: { clientAuth: true },\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: apiKeysSchema,\n\t\tinit: ({ db }) => {\n\t\t\tconst model = createApiKeyModel(db);\n\t\t\treturn {\n\t\t\t\tapi: {\n\t\t\t\t\t...createApiKeyManagement({ apiKeys: model }),\n\t\t\t\t\t/** Registers a known plaintext key idempotently, for managed init. */\n\t\t\t\t\tregister: (input) => registerApiKey({\n\t\t\t\t\t\t...input,\n\t\t\t\t\t\tapiKeys: model\n\t\t\t\t\t}),\n\t\t\t\t\t/** Reuses a saved key or creates one, for managed init. */\n\t\t\t\t\tprovision: (input) => provisionApiKey({\n\t\t\t\t\t\t...input,\n\t\t\t\t\t\tapiKeys: model\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\tclientAuth: {\n\t\t\t\t\tvaryHeaders: [headerName],\n\t\t\t\t\tauthenticate: (headers) => authenticateApiKey({\n\t\t\t\t\t\tapiKeys: model,\n\t\t\t\t\t\theaderName,\n\t\t\t\t\t\trequest: { headers }\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcli: apiKeysCli(headerName)\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { API_KEY_HEADER_NAME, apiKeys, apiKeysSchema, createApiKeyModel };\n", "import { defineAggregate, defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\nconst HOUR_MS = 36e5;\nconst DAY_MS = 864e5;\nconst DEFAULT_INSIGHTS_RETENTION = {\n\trawDays: 90,\n\tdailyDays: 400\n};\nconst bucketRetention = (days) => ({\n\tfield: \"bucket_start_ms\",\n\tdays\n});\n/** Every kind of row the table keeps belongs in installation history. */\nconst MOVEMENTS = /* @__PURE__ */ new Set([\n\t\"UPDATE_DOWNLOADED\",\n\t\"UPDATE_APPLIED\",\n\t\"RECOVERED\",\n\t\"UPDATE_FAILED\",\n\t\"UNCHANGED\"\n]);\n/** A failed update check: it names no target bundle, so no bundle list shows it. */\nconst isFailedCheck = (row) => row.type === \"UPDATE_FAILED\" && row.metadata?.failure?.stage === \"check\";\nconst metadataOf = (row) => row.metadata ?? {};\n/** A download or apply that arrived after its target ran: it counts nothing. */\nconst isLateEvent = (row) => metadataOf(row).late === true;\n/**\n* Whether a stored row launched its installation into a bundle release: an\n* apply, or a kept UNCHANGED row that moved the installation to another\n* bundle of a release, as when the apply report never arrived or a rollback\n* to the built-in bundle took it there. A first report, a release change of\n* the bundle already running, and a late row launch nothing.\n*/\nconst isLaunch = (row) => {\n\tif (isLateEvent(row)) return false;\n\tif (row.type === \"UPDATE_APPLIED\") return true;\n\tif (row.type !== \"UNCHANGED\") return false;\n\tconst kinds = metadataOf(row).change?.kinds ?? [];\n\treturn kinds.includes(\"bundle\") && !kinds.includes(\"first_seen\") && row.to_release_id !== null;\n};\n/**\n* The bundle a stored row's bundle filter matches: `from:<bundle>` for a\n* recovery; `to:<bundle>` for a download, an apply, and an update failure;\n* `on:<bundle>` for an UNCHANGED row that launched a bundle (`isLaunch`), a\n* key no other row uses. None for a failed check, which targets no bundle, a\n* late row, or any other UNCHANGED row.\n*/\nconst bundleRefsOf = (row) => {\n\tif (isFailedCheck(row) || isLateEvent(row)) return [];\n\tif (row.type === \"RECOVERED\") return [`from:${row.from_bundle_id}`];\n\tif (row.type === \"UNCHANGED\") return isLaunch(row) ? [`on:${row.to_bundle_id}`] : [];\n\treturn [`to:${row.to_bundle_id}`];\n};\n/** The key a bundle filter reads, as `bundleRefsOf` writes it. */\nconst bundleRefOfFilter = (filter) => filter.type === \"RECOVERED\" ? `from:${filter.fromBundleId}` : filter.type === \"UNCHANGED\" ? `on:${filter.toBundleId}` : `to:${filter.toBundleId}`;\n/**\n* Downloads, applies, recoveries, update failures, and the UNCHANGED\n* reports that changed what their installation runs, whole. An UNCHANGED\n* report that changes nothing counts as a launch and moves its\n* installation's head, but no row keeps it.\n*/\nconst bundleEvents = (days) => defineTable({\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tinstall_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\tuser_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255,\n\t\trequired: false\n\t},\n\tfrom_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tfrom_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\tchannel: { type: \"string\" },\n\tmetadata: { type: \"json\" },\n\treceived_at_ms: { type: \"integer\" }\n}, {\n\tkey: [\"id\"],\n\tderived: {\n\t\t/** The UTC day the event was received in. */\n\t\tday: {\n\t\t\ttype: \"integer\",\n\t\t\tcompute: (row) => row.received_at_ms - row.received_at_ms % DAY_MS\n\t\t},\n\t\t/** Every stored event belongs in installation history. */\n\t\tmovement_install_id: {\n\t\t\ttype: \"string\",\n\t\t\tcompute: (row) => MOVEMENTS.has(row.type) ? row.install_id : null\n\t\t},\n\t\t/** The bundle a bundle filter matches (`bundleRefsOf`). */\n\t\tbundle_ref: {\n\t\t\ttype: \"string\",\n\t\t\tmulti: true,\n\t\t\tcompute: (row) => bundleRefsOf(row)\n\t\t}\n\t},\n\tindexes: {\n\t\tmovementsByInstall: {\n\t\t\teq: [\"movement_install_id\"],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t},\n\t\tbyBundle: {\n\t\t\teq: [\n\t\t\t\t\"platform\",\n\t\t\t\t\"channel\",\n\t\t\t\t\"type\",\n\t\t\t\t\"bundle_ref\",\n\t\t\t\t\"day\"\n\t\t\t],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t},\n\t\t/** Events of every scope by day, for the console's unfiltered event list. */\n\t\tbyDay: {\n\t\t\teq: [\"day\"],\n\t\t\tsort: [\"received_at_ms\"]\n\t\t}\n\t},\n\tretention: {\n\t\tfield: \"day\",\n\t\tdays\n\t}\n});\n/**\n* Each installation's latest event, whole, so reading it is one point read.\n* Its gauges count it in the UTC day of that event. An update failure moves\n* nothing, so no head holds one.\n*/\nconst bundleEventHeads = (days) => defineTable({\n\tinstall_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255\n\t},\n\tid: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tuser_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 255,\n\t\trequired: false\n\t},\n\tfrom_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tfrom_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_release_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36,\n\t\trequired: false\n\t},\n\tto_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\tchannel: { type: \"string\" },\n\tmetadata: { type: \"json\" },\n\treceived_at_ms: { type: \"integer\" }\n}, {\n\tkey: [\"install_id\"],\n\tindexes: { byUser: {\n\t\teq: [\"user_id\"],\n\t\tsort: [\"install_id\"]\n\t} },\n\tretention: {\n\t\tfield: \"received_at_ms\",\n\t\tdays\n\t}\n});\n/**\n* Shards are keyed by install id. Counters are blind increments and never\n* conflict, so they keep 8. Gauges and sketches are read, merged, and written\n* back. B3's rollout gate on PostgreSQL retried 2.4% of transactions at 8\n* shards and 1.3% at 16. DynamoDB's transactions take longer, so D8's gate\n* on DynamoDB Local retried 2\u201324% at 16, almost all on gauge rows, and 1\u20135%\n* with gauges at 32. Sketches stay at 16: each shard row carries 2 KB of\n* registers that every read merges.\n*\n* Every Insights aggregate is `batched`: on DynamoDB and Firestore, which\n* bill each write, an event's changes apply after it commits, merged with\n* other events' into one write per row, on one shard per writer.\n*/\nconst COUNTER_SHARDS = 8;\nconst GAUGE_SHARDS = 32;\nconst SKETCH_SHARDS = 16;\n/** Rows keyed by a hashed identity (scope and period) and a bucket. */\nconst identityFields = {\n\tidentity: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n};\nconst window = {\n\teq: [\"identity\"],\n\tsort: [\"bucket_start_ms\"]\n};\n/** What a release or channel row counts in every period kind. */\nconst WINDOW_COUNTERS = [\n\t\"downloads\",\n\t\"failed_launches\",\n\t\"patch_downloads\",\n\t\"patch_fallbacks\"\n];\n/**\n* Hourly or daily counters: a release or channel row counts downloads,\n* launches that crashed and recovered (`failed_launches`), and downloads a\n* patch delivered and those that fell back from one.\n*/\nconst counters = (retention) => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tcounters: WINDOW_COUNTERS,\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { window },\n\tretention\n});\n/**\n* A release's counters since its first report, at bucket 0: the windowed\n* counters, its applies, which the bundle list reads, and its failed updates\n* (`failed_updates`), since no breakdown row outlives the raw period; windowed\n* reads sum `insights_failures` instead.\n*/\nconst lifetimeCounters = () => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tcounters: [\n\t\t...WINDOW_COUNTERS,\n\t\t\"applies\",\n\t\t\"failed_updates\"\n\t],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { window }\n});\n/**\n* Unique-installation sketches of one period kind: a usage row's active\n* installations (`activity_users`), and a `failure` or `check` row's\n* installations whose update or update check failed (`failed_users`).\n*/\nconst sketches = (retention) => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tdistinct: [\"activity_users\", \"failed_users\"],\n\tshards: SKETCH_SHARDS,\n\tbatched: true,\n\tindexes: { window },\n\tretention\n});\n/** Installations whose update to a release failed, since its first failure: kept, at bucket 0. */\nconst lifetimeSketches = () => defineAggregate(identityFields, {\n\tkey: [\"identity\", \"bucket_start_ms\"],\n\tdistinct: [\"failed_users\"],\n\tshards: SKETCH_SHARDS,\n\tbatched: true,\n\tindexes: { window }\n});\n/**\n* Update failures by what failed, a row an hour. `release_id` is the failed\n* update's target release, or empty for a failed check or an unknown target.\n* `stage` and `reason` say where and why it failed, and `detail` what else\n* the client knew, as the JSON array `[resource, httpStatus, originCode,\n* transport]`. Every index is in key order, so its counters stay blind\n* increments.\n*/\nconst insightsFailures = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\tbucket_start_ms: { type: \"integer\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tstage: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\treason: {\n\t\ttype: \"string\",\n\t\tmaxLength: 64\n\t},\n\tdetail: {\n\t\ttype: \"string\",\n\t\tmaxLength: 160\n\t}\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"bucket_start_ms\",\n\t\t\"release_id\",\n\t\t\"stage\",\n\t\t\"reason\",\n\t\t\"detail\"\n\t],\n\tcounters: [\"events\"],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { byScope: {\n\t\teq: [\"platform\", \"channel\"],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/** Installations counted in the UTC day of their latest event, so reads sum whole UTC days. */\nconst insightsDistribution = (retention) => defineAggregate({\n\tchannel: { type: \"string\" },\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"channel\",\n\t\t\"platform\",\n\t\t\"app_version\",\n\t\t\"release_id\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"latest_installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: {\n\t\tbyScope: {\n\t\t\teq: [\"channel\", \"platform\"],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t},\n\t\tbyVersion: {\n\t\t\teq: [\n\t\t\t\t\"channel\",\n\t\t\t\t\"platform\",\n\t\t\t\t\"app_version\"\n\t\t\t],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t}\n\t},\n\tretention\n});\n/**\n* The installations of `insights_distribution` that run their native build's\n* built-in bundle, by its ID (`builtin_bundle_id`), within the same rows:\n* reads move them out of the row of their release, or of no release.\n*/\nconst insightsBuiltinDistribution = (retention) => defineAggregate({\n\tchannel: { type: \"string\" },\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tapp_version: { type: \"string\" },\n\trelease_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbuiltin_bundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"channel\",\n\t\t\"platform\",\n\t\t\"app_version\",\n\t\t\"release_id\",\n\t\t\"builtin_bundle_id\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"latest_installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: {\n\t\tbyScope: {\n\t\t\teq: [\"channel\", \"platform\"],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t},\n\t\tbyVersion: {\n\t\t\teq: [\n\t\t\t\t\"channel\",\n\t\t\t\t\"platform\",\n\t\t\t\t\"app_version\"\n\t\t\t],\n\t\t\tsort: [\"bucket_start_ms\"]\n\t\t}\n\t},\n\tretention\n});\n/** Latest events by the bundle they came from or went to, bucketed like the distribution. */\nconst insightsLatestByBundle = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\tbundle_field: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tbundle_id: {\n\t\ttype: \"string\",\n\t\tmaxLength: 36\n\t},\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"bundle_field\",\n\t\t\"bundle_id\",\n\t\t\"type\",\n\t\t\"bucket_start_ms\"\n\t],\n\tgauges: [\"installations\"],\n\tshards: GAUGE_SHARDS,\n\tbatched: true,\n\tindexes: { byBundle: {\n\t\teq: [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"bundle_field\",\n\t\t\t\"bundle_id\",\n\t\t\t\"type\"\n\t\t],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/**\n* Stored events by outcome and the bundle a bundle filter matches, a row an\n* hour, which a failed check has none of; and every stored event, a row a UTC\n* day (`DAILY_EVENTS`). Bundle counts sum the hourly rows, and event lists\n* read either to skip days without events.\n*/\nconst insightsOutcomes = (retention) => defineAggregate({\n\tplatform: {\n\t\ttype: \"string\",\n\t\tmaxLength: 16\n\t},\n\tchannel: { type: \"string\" },\n\ttype: {\n\t\ttype: \"string\",\n\t\tmaxLength: 32\n\t},\n\tbundle_ref: {\n\t\ttype: \"string\",\n\t\tmaxLength: 41\n\t},\n\tbucket_start_ms: { type: \"integer\" }\n}, {\n\tkey: [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"type\",\n\t\t\"bundle_ref\",\n\t\t\"bucket_start_ms\"\n\t],\n\tcounters: [\"events\"],\n\tshards: COUNTER_SHARDS,\n\tbatched: true,\n\tindexes: { byRef: {\n\t\teq: [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"type\",\n\t\t\t\"bundle_ref\"\n\t\t],\n\t\tsort: [\"bucket_start_ms\"]\n\t} },\n\tretention\n});\n/**\n* The `insights_outcomes` identity that counts every stored event, for the\n* global event list. Its bucket is a UTC day, not an hour. Every event's\n* platform is ios or android, so no outcome row of a bundle filter shares it.\n*/\nconst DAILY_EVENTS = {\n\tplatform: \"*\",\n\tchannel: \"\",\n\ttype: \"\",\n\tbundle_ref: \"\"\n};\n/**\n* Insights' tables, each expiring after its period. The periods are values\n* the engine applies at runtime; the tables and indexes are the same for\n* any periods.\n*/\nconst createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTION) => {\n\tconst hourly = bucketRetention(rawDays);\n\tconst daily = bucketRetention(dailyDays);\n\treturn {\n\t\tbundle_events: bundleEvents(rawDays),\n\t\tbundle_event_heads: bundleEventHeads(dailyDays),\n\t\t/** Hourly counters and sketches: the raw period. */\n\t\tinsights_overview: counters(hourly),\n\t\tinsights_sketches: sketches(hourly),\n\t\t/** Daily counters and sketches: the daily period. */\n\t\tinsights_overview_daily: counters(daily),\n\t\tinsights_sketches_daily: sketches(daily),\n\t\t/** A release's counters since its first event, and its failed installations: kept. */\n\t\tinsights_overview_lifetime: lifetimeCounters(),\n\t\tinsights_sketches_lifetime: lifetimeSketches(),\n\t\tinsights_distribution: insightsDistribution(daily),\n\t\tinsights_builtin_distribution: insightsBuiltinDistribution(daily),\n\t\tinsights_latest_by_bundle: insightsLatestByBundle(daily),\n\t\tinsights_outcomes: insightsOutcomes(hourly),\n\t\tinsights_failures: insightsFailures(hourly)\n\t};\n};\nconst insightsSchema = createInsightsSchema();\n//#endregion\nexport { DAILY_EVENTS, DAY_MS, DEFAULT_INSIGHTS_RETENTION, HOUR_MS, bundleRefOfFilter, bundleRefsOf, createInsightsSchema, insightsSchema, isFailedCheck, isLateEvent, isLaunch };\n", "import { DatabaseAdapterInputError, isDatabaseJsonObject } from \"@hot-updater/plugin-core\";\n//#region src/server/eventRow.ts\nconst CHANGE_KINDS = /* @__PURE__ */ new Set([\n\t\"first_seen\",\n\t\"bundle\",\n\t\"release\",\n\t\"app_version\",\n\t\"channel\",\n\t\"native_build\"\n]);\nconst isBundleEventChange = (value) => isDatabaseJsonObject(value) && Array.isArray(value.kinds) && value.kinds.length > 0 && value.kinds.every((kind) => CHANGE_KINDS.has(kind)) && (value.previous === null || isDatabaseJsonObject(value.previous) && typeof value.previous.bundle_id === \"string\" && (value.previous.release_id === null || typeof value.previous.release_id === \"string\") && typeof value.previous.app_version === \"string\" && typeof value.previous.channel === \"string\" && isOptional(value.previous, \"min_bundle_id\", isString));\nconst isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);\nconst isString = (value) => typeof value === \"string\";\nconst isDatabaseHttpResponse = (value) => isDatabaseJsonObject(value) && (value.resource === \"catalog\" || value.resource === \"artifact\") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === \"boolean\" && Number.isSafeInteger(value.received_at_ms);\n/** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */\nconst isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, \"resource\", isString) && isOptional(value, \"http_status\", (status) => Number.isSafeInteger(status)) && isOptional(value, \"transport\", isString) && isOptional(value, \"origin_code\", isString) && isOptional(value, \"error_message\", isString) && isOptional(value, \"error_stack\", isString);\nconst isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === \"string\" && (value.update_strategy === null || value.update_strategy === \"fingerprint\" || value.update_strategy === \"appVersion\") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === \"string\") && (value.sdk_version === null || typeof value.sdk_version === \"string\") && isOptional(value, \"min_bundle_id\", isString) && isOptional(value, \"failure\", isDatabaseBundleEventFailure) && isOptional(value, \"http_response\", isDatabaseHttpResponse) && isOptional(value, \"delivery\", isString) && isOptional(value, \"patch_fallback\", (flag) => typeof flag === \"boolean\") && isOptional(value, \"change\", isBundleEventChange) && isOptional(value, \"late\", (flag) => flag === true) && isOptional(value, \"implied_download\", (flag) => flag === true);\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/**\n* The built-in bundle a report says its installation runs: the running\n* bundle, which a download leaves at its source, when it is the native\n* build's built-in bundle, whatever Release selected it. Null for any other\n* bundle, and for a report without the build's built-in bundle ID.\n*/\nconst runningBuiltinBundleId = (row) => {\n\tconst running = row.type === \"UPDATE_DOWNLOADED\" ? row.from_bundle_id : row.to_bundle_id;\n\tconst builtin = isRecord(row.metadata) ? row.metadata.min_bundle_id : null;\n\treturn typeof builtin === \"string\" && running === builtin ? builtin : null;\n};\nconst isIdentity = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 255;\nconst isTextOrNull = (value) => value === null || typeof value === \"string\";\n/** Each bundle event field and what it holds. */\nconst BUNDLE_EVENT_FIELDS = {\n\tid: (value) => typeof value === \"string\",\n\ttype: (value) => value === \"UPDATE_DOWNLOADED\" || value === \"UPDATE_APPLIED\" || value === \"RECOVERED\" || value === \"UPDATE_FAILED\" || value === \"UNCHANGED\",\n\tinstall_id: isIdentity,\n\tuser_id: (value) => value === null || isIdentity(value),\n\tfrom_bundle_id: isTextOrNull,\n\tfrom_release_id: isTextOrNull,\n\tto_release_id: isTextOrNull,\n\tto_bundle_id: (value) => typeof value === \"string\",\n\tplatform: (value) => value === \"ios\" || value === \"android\",\n\tapp_version: (value) => typeof value === \"string\",\n\tchannel: (value) => typeof value === \"string\",\n\tmetadata: isDatabaseBundleEventMetadata,\n\treceived_at_ms: (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0\n};\nconst hasMetadata = (row, key) => isRecord(row.metadata) && Object.hasOwn(row.metadata, key);\nconst updateStrategyOf = (row) => isRecord(row.metadata) ? row.metadata.update_strategy : void 0;\n/**\n* A movement, or a failed update, names the bundle it left and how the\n* device updates, and a failed update says what failed; an unchanged report\n* names neither.\n*/\nconst hasEventInvariants = (row) => (row.type === \"UPDATE_DOWNLOADED\" || row.type === \"UPDATE_APPLIED\" || row.type === \"RECOVERED\" || row.type === \"UPDATE_FAILED\") && typeof row.from_bundle_id === \"string\" && (updateStrategyOf(row) === \"fingerprint\" || updateStrategyOf(row) === \"appVersion\") && (row.type !== \"UPDATE_FAILED\" || isRecord(row.metadata) && isRecord(row.metadata.failure)) && !hasMetadata(row, \"change\") && (!hasMetadata(row, \"late\") || row.type === \"UPDATE_DOWNLOADED\" || row.type === \"UPDATE_APPLIED\") && (!hasMetadata(row, \"implied_download\") || row.type === \"UPDATE_APPLIED\" || row.type === \"RECOVERED\") || row.type === \"UNCHANGED\" && !hasMetadata(row, \"late\") && row.from_bundle_id === null && updateStrategyOf(row) === null;\n/**\n* Throws unless `row` has exactly the bundle event fields, each of its type,\n* and the invariants of its event type: `invalid-field` for an unknown field,\n* `invalid-data` for anything else.\n*/\nconst validateBundleEventFields = (row) => {\n\tif (!isRecord(row)) throw new DatabaseAdapterInputError(\"invalid-data\");\n\tfor (const field of Object.keys(row)) if (!Object.hasOwn(BUNDLE_EVENT_FIELDS, field)) throw new DatabaseAdapterInputError(\"invalid-field\");\n\tfor (const [field, valid] of Object.entries(BUNDLE_EVENT_FIELDS)) if (!Object.hasOwn(row, field) || !valid(row[field])) throw new DatabaseAdapterInputError(\"invalid-data\");\n\tif (!hasEventInvariants(row)) throw new DatabaseAdapterInputError(\"invalid-data\");\n};\n//#endregion\nexport { isDatabaseBundleEventMetadata, isRecord, runningBuiltinBundleId, validateBundleEventFields };\n", "import { isRecord, validateBundleEventFields } from \"./eventRow.mjs\";\nimport { bundleRefOfFilter, bundleRefsOf } from \"./schema.mjs\";\nimport { DatabaseAdapterInputError, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/contract.ts\nconst encoder = new TextEncoder();\n/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */\nconst compareInsightsText = (left, right) => {\n\tconst a = encoder.encode(left);\n\tconst b = encoder.encode(right);\n\tfor (let index = 0; index < Math.min(a.length, b.length); index += 1) if (a[index] !== b[index]) return a[index] - b[index];\n\treturn a.length - b.length;\n};\nconst isWellFormedText = (value) => {\n\tfor (const character of value) {\n\t\tconst point = character.codePointAt(0);\n\t\tif (point >= 55296 && point <= 57343) return false;\n\t}\n\treturn true;\n};\nconst isIdentity = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 255 && isWellFormedText(value);\nconst isText = (value) => typeof value === \"string\" && value.length > 0 && isWellFormedText(value);\nconst isTimestamp = (value) => typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\nconst isLimit = (value) => isTimestamp(value) && value >= 1 && value <= 101;\nconst hasOnlyKeys = (value, keys) => Object.keys(value).every((key) => keys.includes(key));\nconst hasScope = (value) => (value.platform === \"ios\" || value.platform === \"android\") && isText(value.channel);\nconst isBundleFilter = (value, withKind = false) => {\n\tif (!isRecord(value) || !hasScope(value)) return false;\n\tconst keys = [\n\t\t\"platform\",\n\t\t\"channel\",\n\t\t\"type\",\n\t\t...withKind ? [\"kind\"] : []\n\t];\n\treturn value.type === \"RECOVERED\" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, \"fromBundleId\"]) : (value.type === \"UPDATE_DOWNLOADED\" || value.type === \"UPDATE_APPLIED\" || value.type === \"UPDATE_FAILED\" || value.type === \"UNCHANGED\") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, \"toBundleId\"]);\n};\nconst isEventFilter = (value) => {\n\tif (!isRecord(value)) return false;\n\tif (value.kind === \"all\") return hasOnlyKeys(value, [\"kind\"]);\n\tif (value.kind === \"installationMovement\") return isIdentity(value.installId) && hasOnlyKeys(value, [\"kind\", \"installId\"]);\n\treturn value.kind === \"bundle\" && isBundleFilter(value, true);\n};\nconst validateRow = (model, row, result = false) => {\n\ttry {\n\t\tvalidateBundleEventFields(row);\n\t\tif (!isRecord(row) || typeof row.id !== \"string\" || !isUUIDv7(row.id) || [...Object.values(row), ...isRecord(row.metadata) ? Object.values(row.metadata) : []].some((value) => typeof value === \"string\" && !isWellFormedText(value))) throw new DatabaseAdapterInputError(\"invalid-data\");\n\t} catch (error) {\n\t\tif (result) throw new DatabaseAdapterInputError(\"invalid-result\");\n\t\tthrow error;\n\t}\n};\n/** Throws `invalid-data` unless `row` is a complete, well-formed bundle event row. */\nconst assertBundleEventRow = (row) => validateRow(\"bundle_events\", row);\n/**\n* Downloads, applies, recoveries, failed updates, and the UNCHANGED rows\n* kept for a change belong in installation history.\n*/\nconst isInsightsMovementEvent = (event) => event.type === \"UPDATE_DOWNLOADED\" || event.type === \"UPDATE_APPLIED\" || event.type === \"RECOVERED\" || event.type === \"UPDATE_FAILED\" || event.type === \"UNCHANGED\";\nconst matchesInsightsEventFilter = (event, filter) => {\n\tif (filter.kind === \"all\") return true;\n\tif (filter.kind === \"installationMovement\") return event.install_id === filter.installId && isInsightsMovementEvent(event);\n\treturn event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && bundleRefsOf(event).includes(bundleRefOfFilter(filter));\n};\nconst invalidQuery = () => {\n\tthrow new DatabaseAdapterInputError(\"invalid-query\");\n};\nconst invalidResult = () => {\n\tthrow new DatabaseAdapterInputError(\"invalid-result\");\n};\nconst validateCount = (count) => isTimestamp(count) ? count : invalidResult();\nconst isTimeRange = (value) => isRecord(value) && hasOnlyKeys(value, [\"start\", \"end\"]) && isTimestamp(value.start) && isTimestamp(value.end) && value.start < value.end;\nconst isReleaseReference = (value) => isRecord(value) && hasOnlyKeys(value, [\n\t\"releaseId\",\n\t\"platform\",\n\t\"channel\"\n]) && isIdentity(value.releaseId) && hasScope(value);\nconst validateAggregateResult = (value) => {\n\tconst result = isRecord(value) ? value : invalidResult();\n\tif (!isTimestamp(result.measuredAtMs)) invalidResult();\n\tconst coverage = result.coverage;\n\tif (!isRecord(coverage) || coverage.kind !== \"complete\" && coverage.kind !== \"partial\" || coverage.sinceMs !== null && !isTimestamp(coverage.sinceMs)) invalidResult();\n};\n/** Validate custom and bundled providers at the same public boundary. */\nconst createValidatedInsightsModel = (model) => ({\n\tasync recordEvent(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\"event\"])) throw new DatabaseAdapterInputError(\"invalid-data\");\n\t\tvalidateRow(\"bundle_events\", input.event);\n\t\tawait model.recordEvent(input);\n\t},\n\tasync listEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"sinceMs\",\n\t\t\t\"beforeReceivedAtMs\",\n\t\t\t\"after\",\n\t\t\t\"limit\"\n\t\t]) || !isEventFilter(input.filter) || !isLimit(input.limit) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs !== void 0 && !isTimestamp(input.sinceMs)) invalidQuery();\n\t\tconst sinceMs = input.sinceMs ?? 0;\n\t\tif (sinceMs > input.beforeReceivedAtMs || input.after !== void 0 && (!isRecord(input.after) || !hasOnlyKeys(input.after, [\"receivedAtMs\", \"id\"]) || !isTimestamp(input.after.receivedAtMs) || typeof input.after.id !== \"string\" || !isUUIDv7(input.after.id) || input.after.receivedAtMs < sinceMs || input.after.receivedAtMs >= input.beforeReceivedAtMs)) invalidQuery();\n\t\tconst rows = await model.listEvents(input);\n\t\tif (!Array.isArray(rows) || rows.length > input.limit) invalidResult();\n\t\tlet previous = input.after;\n\t\tfor (const row of rows) {\n\t\t\tvalidateRow(\"bundle_events\", row, true);\n\t\t\tif (row.received_at_ms < sinceMs || row.received_at_ms >= input.beforeReceivedAtMs || !matchesInsightsEventFilter(row, input.filter) || previous !== void 0 && (row.received_at_ms > previous.receivedAtMs || row.received_at_ms === previous.receivedAtMs && row.id >= previous.id)) invalidResult();\n\t\t\tprevious = {\n\t\t\t\treceivedAtMs: row.received_at_ms,\n\t\t\t\tid: row.id\n\t\t\t};\n\t\t}\n\t\treturn rows;\n\t},\n\tasync findLatestEvents(input) {\n\t\tif (!isRecord(input)) invalidQuery();\n\t\tif (\"installId\" in input) {\n\t\t\tif (!hasOnlyKeys(input, [\"installId\"]) || !isIdentity(input.installId)) invalidQuery();\n\t\t} else if (!hasOnlyKeys(input, [\n\t\t\t\"userId\",\n\t\t\t\"afterInstallId\",\n\t\t\t\"limit\"\n\t\t]) || !isIdentity(input.userId) || !isLimit(input.limit) || input.afterInstallId !== void 0 && !isIdentity(input.afterInstallId)) invalidQuery();\n\t\tconst rows = await model.findLatestEvents(input);\n\t\tif (!Array.isArray(rows) || rows.length > (\"installId\" in input ? 1 : input.limit)) invalidResult();\n\t\tlet previous = \"installId\" in input ? void 0 : input.afterInstallId;\n\t\tfor (const row of rows) {\n\t\t\tvalidateRow(\"bundle_events\", row, true);\n\t\t\tif (\"installId\" in input ? row.install_id !== input.installId : row.user_id !== input.userId || previous !== void 0 && compareInsightsText(row.install_id, previous) <= 0) invalidResult();\n\t\t\tprevious = row.install_id;\n\t\t}\n\t\treturn rows;\n\t},\n\tasync countLatestEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"platform\",\n\t\t\t\"channel\",\n\t\t\t\"sinceMs\",\n\t\t\t\"bundle\"\n\t\t]) || !hasScope(input) || !isTimestamp(input.sinceMs) || input.bundle !== void 0 && (!Array.isArray(input.bundle) || input.bundle.length < 1 || input.bundle.length > 2 || input.bundle.some((bundle) => !isRecord(bundle) || !hasOnlyKeys(bundle, [\n\t\t\t\"field\",\n\t\t\t\"value\",\n\t\t\t\"types\"\n\t\t]) || bundle.field !== \"from_bundle_id\" && bundle.field !== \"to_bundle_id\" || !isText(bundle.value) || !Array.isArray(bundle.types) || bundle.types.length === 0 || bundle.types.some((type) => ![\n\t\t\t\"UNCHANGED\",\n\t\t\t\"UPDATE_DOWNLOADED\",\n\t\t\t\"UPDATE_APPLIED\",\n\t\t\t\"RECOVERED\"\n\t\t].includes(type))))) invalidQuery();\n\t\treturn validateCount(await model.countLatestEvents(input));\n\t},\n\tasync countEvents(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"sinceMs\",\n\t\t\t\"beforeReceivedAtMs\"\n\t\t]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();\n\t\treturn validateCount(await model.countEvents(input));\n\t},\n\tasync countEventSeries(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"filter\",\n\t\t\t\"timeRange\",\n\t\t\t\"intervalMs\"\n\t\t]) || !isBundleFilter(input.filter) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs)) invalidQuery();\n\t\tconst { start, end } = input.timeRange;\n\t\tconst { intervalMs } = input;\n\t\tif (intervalMs === 0 || intervalMs % 36e5 !== 0 || start % 36e5 !== 0 || (end - start) % intervalMs !== 0 || end - start > 7776e6) invalidQuery();\n\t\tconst points = await model.countEventSeries(input);\n\t\tif (!Array.isArray(points) || points.length !== (end - start) / intervalMs || points.some((point, index) => !isRecord(point) || !hasOnlyKeys(point, [\"startMs\", \"events\"]) || point.startMs !== start + index * intervalMs || !isTimestamp(point.events))) invalidResult();\n\t\treturn points;\n\t},\n\tasync getReleaseActivity(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\"releases\"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();\n\t\tconst result = await model.getReleaseActivity(input);\n\t\tif (!isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord(item) || !isReleaseReference(item.release) || !isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();\n\t\treturn result;\n\t},\n\tasync getAppUsage(input) {\n\t\tif (!isRecord(input) || !hasOnlyKeys(input, [\n\t\t\t\"channel\",\n\t\t\t\"platform\",\n\t\t\t\"appVersion\",\n\t\t\t\"timeRange\",\n\t\t\t\"intervalMs\"\n\t\t]) || !isText(input.channel) || ![\n\t\t\t\"all\",\n\t\t\t\"ios\",\n\t\t\t\"android\"\n\t\t].includes(input.platform) || input.appVersion !== void 0 && !isText(input.appVersion) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs) || input.intervalMs < 36e5) invalidQuery();\n\t\tconst result = await model.getAppUsage(input);\n\t\tvalidateAggregateResult(result);\n\t\tif (!isTimestamp(result.activeInstallations) || !Array.isArray(result.points) || !Array.isArray(result.appVersions) || !Array.isArray(result.versions) || !Array.isArray(result.platforms) || !Array.isArray(result.bundleDistribution)) invalidResult();\n\t\treturn result;\n\t}\n});\n//#endregion\nexport { assertBundleEventRow, compareInsightsText, createValidatedInsightsModel, isInsightsMovementEvent, matchesInsightsEventFilter };\n", "import { createValidatedInsightsModel } from \"./contract.mjs\";\n//#region src/server/model.ts\n/**\n* The plugin's API as `InsightsModel`, validated at its boundary: what the\n* Insights routes, the console, and the e2e harness read through.\n*/\nconst createInsightsModel = (api) => createValidatedInsightsModel({\n\trecordEvent: ({ event }) => api.recordEvent(event),\n\tlistEvents: api.listEvents,\n\tfindLatestEvents: api.findLatestEvents,\n\tcountLatestEvents: api.countLatestEvents,\n\tcountEvents: api.countEvents,\n\tcountEventSeries: api.countEventSeries,\n\tgetReleaseActivity: api.getReleaseActivity,\n\tgetAppUsage: api.getAppUsage\n});\n//#endregion\nexport { createInsightsModel };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"insights\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "//#region src/server/errors.ts\n/**\n* What Insights' API throws for an input it refuses, such as an unknown\n* event field or a malformed cursor; its routes answer 400 for it.\n*/\nvar InsightsBadRequestError = class extends Error {\n\tname = \"InsightsBadRequestError\";\n};\nvar InsightsPayloadTooLargeError = class extends Error {\n\tmaximumBytes;\n\tname = \"InsightsPayloadTooLargeError\";\n\tconstructor(maximumBytes) {\n\t\tsuper(`Event payload exceeds ${maximumBytes} bytes`);\n\t\tthis.maximumBytes = maximumBytes;\n\t}\n};\n//#endregion\nexport { InsightsBadRequestError, InsightsPayloadTooLargeError };\n", "import { InsightsBadRequestError, InsightsPayloadTooLargeError } from \"./errors.mjs\";\nimport { createUUIDv7, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/eventInput.ts\nconst MAX_EVENT_STRING_LENGTH = 1024;\nconst MAX_IDENTITY_LENGTH = 255;\nconst EVENT_BODY_MAX_BYTES = 16384;\nfunction isRecord(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction requireStringField(payload, key) {\n\tconst value = payload[key];\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH || new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new InsightsBadRequestError(`Invalid event field: ${key}`);\n\treturn value;\n}\nfunction requireNullableStringField(payload, key) {\n\tif (payload[key] === null) return null;\n\treturn requireStringField(payload, key);\n}\nfunction requireIdentityField(payload, key) {\n\tconst value = requireStringField(payload, key);\n\tif (value.length > MAX_IDENTITY_LENGTH) throw new InsightsBadRequestError(`Invalid event field: ${key}`);\n\treturn value;\n}\n/**\n* The report's idempotency key, when the client sends one: it creates the\n* UUIDv7 once and repeats it on every retry of that report.\n*/\nfunction readEventId(payload) {\n\tconst value = payload.eventId;\n\tif (value === void 0) return void 0;\n\tif (!isUUIDv7(value)) throw new InsightsBadRequestError(\"Invalid event field: eventId\");\n\treturn value;\n}\n/**\n* The native build's built-in bundle ID: a bundle ID's length at most, and\n* left out when it is missing or malformed, so the report still records.\n*/\nconst readMinBundleId = (value) => typeof value === \"string\" && value.length > 0 && value.length <= 36 ? value : null;\n/** One value of an open set: any other value reads as `unknown`. */\nconst oneOf = (values, value) => values.includes(value) ? value : \"unknown\";\nconst STAGES = [\n\t\"check\",\n\t\"download\",\n\t\"install\"\n];\nconst REASONS = [\n\t\"network\",\n\t\"http\",\n\t\"invalid_response\",\n\t\"hash_mismatch\",\n\t\"signature\",\n\t\"patch\",\n\t\"extract\",\n\t\"storage\"\n];\nconst RESOURCES = [\n\t\"catalog\",\n\t\"artifact\",\n\t\"manifest\",\n\t\"file\",\n\t\"patch\",\n\t\"archive\"\n];\nconst TRANSPORTS = [\n\t\"timeout\",\n\t\"dns\",\n\t\"tls\",\n\t\"connection\",\n\t\"offline\",\n\t\"cancelled\"\n];\nconst DELIVERIES = [\n\t\"patch\",\n\t\"manifest\",\n\t\"archive\"\n];\n/** A storage error code: letters, digits, and `._-`. */\nconst CODE = /^[A-Za-z0-9._-]{1,64}$/;\nconst readCode = (value) => typeof value === \"string\" && CODE.test(value) ? value : void 0;\nconst readMetadata = (payload) => isRecord(payload.metadata) ? payload.metadata : {};\n/**\n* What an UPDATE_FAILED report says failed. It never refuses the report: an\n* unknown value of a set reads as `unknown`, a missing or malformed failure\n* as an unknown stage and reason, and a malformed optional field is left out,\n* as is a null one.\n*/\nfunction readFailure(value) {\n\tconst failure = isRecord(value) ? value : {};\n\tconst httpStatus = failure.httpStatus;\n\tconst originCode = readCode(failure.originCode);\n\tconst errorMessage = typeof failure.errorMessage === \"string\" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;\n\tconst errorStack = typeof failure.errorStack === \"string\" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;\n\treturn {\n\t\tstage: oneOf(STAGES, failure.stage),\n\t\treason: oneOf(REASONS, failure.reason),\n\t\t...failure.resource == null ? {} : { resource: oneOf(RESOURCES, failure.resource) },\n\t\t...Number.isSafeInteger(httpStatus) && httpStatus >= 100 && httpStatus <= 599 ? { httpStatus } : {},\n\t\t...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },\n\t\t...originCode === void 0 ? {} : { originCode },\n\t\t...errorMessage === void 0 ? {} : { errorMessage },\n\t\t...errorStack === void 0 ? {} : { errorStack }\n\t};\n}\nfunction readHttpResponse(value) {\n\tif (!isRecord(value) || value.resource !== \"catalog\" && value.resource !== \"artifact\" || typeof value.path !== \"string\" || value.path.length > 1024 || !Number.isSafeInteger(value.status) || value.status < 100 || value.status > 599 || value.body !== null && (typeof value.body !== \"string\" || new TextEncoder().encode(JSON.stringify(value.body)).byteLength > 4096) || typeof value.bodyTruncated !== \"boolean\" || !Number.isSafeInteger(value.receivedAtMs) || value.receivedAtMs < 0) throw new InsightsBadRequestError(\"Invalid HTTP response details\");\n\treturn {\n\t\tresource: value.resource,\n\t\tpath: value.path,\n\t\tstatus: value.status,\n\t\tbody: value.body,\n\t\tbodyTruncated: value.bodyTruncated,\n\t\treceivedAtMs: value.receivedAtMs\n\t};\n}\nasync function readBoundedText(request) {\n\tconst contentLength = request.headers.get(\"content-length\");\n\tconst declaredByteLength = Number(contentLength);\n\tif (contentLength !== null && Number.isSafeInteger(declaredByteLength) && declaredByteLength > 16384) throw new InsightsPayloadTooLargeError(EVENT_BODY_MAX_BYTES);\n\tif (request.body === null) return \"\";\n\tconst reader = request.body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet byteLength = 0;\n\tlet text = \"\";\n\twhile (true) {\n\t\tconst result = await reader.read();\n\t\tif (result.done) break;\n\t\tbyteLength += result.value.byteLength;\n\t\tif (byteLength > 16384) {\n\t\t\tawait reader.cancel();\n\t\t\tthrow new InsightsPayloadTooLargeError(EVENT_BODY_MAX_BYTES);\n\t\t}\n\t\ttext += decoder.decode(result.value, { stream: true });\n\t}\n\treturn text + decoder.decode();\n}\nasync function parseJson(request) {\n\tconst text = await readBoundedText(request);\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) throw new InsightsBadRequestError(\"Invalid event payload\");\n\t\tthrow error;\n\t}\n}\nfunction requireEvent(payload) {\n\tif (!isRecord(payload)) throw new InsightsBadRequestError(\"Invalid event payload\");\n\tconst platform = requireStringField(payload, \"platform\");\n\tif (platform !== \"ios\" && platform !== \"android\") throw new InsightsBadRequestError(\"Invalid event field: platform\");\n\tconst eventId = readEventId(payload);\n\tconst metadata = readMetadata(payload);\n\tconst httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };\n\tconst base = {\n\t\t...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },\n\t\t...eventId === void 0 ? {} : { eventId },\n\t\tinstallId: requireIdentityField(payload, \"installId\"),\n\t\ttoBundleId: requireStringField(payload, \"toBundleId\"),\n\t\t...payload.userId === void 0 ? {} : { userId: requireIdentityField(payload, \"userId\") },\n\t\tplatform,\n\t\tappVersion: requireStringField(payload, \"appVersion\"),\n\t\tchannel: requireStringField(payload, \"channel\"),\n\t\tcohort: requireStringField(payload, \"cohort\"),\n\t\tfingerprintHash: requireNullableStringField(payload, \"fingerprintHash\"),\n\t\tsdkVersion: payload.sdkVersion === void 0 ? null : requireNullableStringField(payload, \"sdkVersion\"),\n\t\tminBundleId: readMinBundleId(payload.minBundleId),\n\t\tfromReleaseId: requireNullableStringField(payload, \"fromReleaseId\"),\n\t\ttoReleaseId: requireNullableStringField(payload, \"toReleaseId\")\n\t};\n\tconst type = requireStringField(payload, \"type\");\n\tconst movement = () => {\n\t\tconst updateStrategy = requireStringField(payload, \"updateStrategy\");\n\t\tif (updateStrategy !== \"fingerprint\" && updateStrategy !== \"appVersion\") throw new InsightsBadRequestError(\"Invalid event field: updateStrategy\");\n\t\treturn {\n\t\t\t...base,\n\t\t\tfromBundleId: requireStringField(payload, \"fromBundleId\"),\n\t\t\tupdateStrategy\n\t\t};\n\t};\n\tswitch (type) {\n\t\tcase \"UPDATE_DOWNLOADED\": {\n\t\t\tconst delivery = metadata.delivery;\n\t\t\tconst read = {\n\t\t\t\t...httpMetadata,\n\t\t\t\t...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },\n\t\t\t\t...metadata.patchFallback === true ? { patchFallback: true } : {}\n\t\t\t};\n\t\t\treturn {\n\t\t\t\t...movement(),\n\t\t\t\ttype,\n\t\t\t\t...Object.keys(read).length === 0 ? {} : { metadata: read }\n\t\t\t};\n\t\t}\n\t\tcase \"UPDATE_APPLIED\":\n\t\tcase \"RECOVERED\": return {\n\t\t\t...movement(),\n\t\t\ttype\n\t\t};\n\t\tcase \"UPDATE_FAILED\": return {\n\t\t\t...movement(),\n\t\t\ttype,\n\t\t\tmetadata: {\n\t\t\t\t...httpMetadata,\n\t\t\t\tfailure: readFailure(metadata.failure)\n\t\t\t}\n\t\t};\n\t\tcase \"UNCHANGED\":\n\t\t\tif (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new InsightsBadRequestError(\"Invalid unchanged event shape\");\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\ttype,\n\t\t\t\tfromBundleId: null,\n\t\t\t\tupdateStrategy: null\n\t\t\t};\n\t\tdefault: throw new InsightsBadRequestError(\"Invalid event field: type\");\n\t}\n}\nasync function parseBundleEventRequest(request) {\n\treturn requireEvent(await parseJson(request));\n}\nfunction createBundleEventRow(input) {\n\tinput = requireEvent(input);\n\tconst base = {\n\t\tapp_version: input.appVersion,\n\t\tchannel: input.channel,\n\t\tfrom_release_id: input.fromReleaseId,\n\t\tid: input.eventId ?? createUUIDv7(),\n\t\tinstall_id: input.installId,\n\t\tplatform: input.platform,\n\t\treceived_at_ms: Date.now(),\n\t\tto_bundle_id: input.toBundleId,\n\t\tto_release_id: input.toReleaseId,\n\t\tuser_id: input.userId ?? null\n\t};\n\tconst response = input.metadata?.httpResponse;\n\tconst metadata = {\n\t\t...response ? { http_response: {\n\t\t\tresource: response.resource,\n\t\t\tpath: response.path,\n\t\t\tstatus: response.status,\n\t\t\tbody: response.body,\n\t\t\tbody_truncated: response.bodyTruncated,\n\t\t\treceived_at_ms: response.receivedAtMs\n\t\t} } : {},\n\t\tcohort: input.cohort,\n\t\tfingerprint_hash: input.fingerprintHash,\n\t\tsdk_version: input.sdkVersion ?? null,\n\t\t...input.minBundleId ? { min_bundle_id: input.minBundleId } : {},\n\t\tupdate_strategy: input.updateStrategy\n\t};\n\tswitch (input.type) {\n\t\tcase \"UPDATE_DOWNLOADED\": {\n\t\t\tconst { delivery, patchFallback } = input.metadata ?? {};\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\t\ttype: input.type,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...metadata,\n\t\t\t\t\t...delivery === void 0 ? {} : { delivery },\n\t\t\t\t\t...patchFallback ? { patch_fallback: true } : {}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tcase \"UPDATE_APPLIED\":\n\t\tcase \"RECOVERED\": return {\n\t\t\t...base,\n\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\ttype: input.type,\n\t\t\tmetadata\n\t\t};\n\t\tcase \"UPDATE_FAILED\": {\n\t\t\tconst { failure } = input.metadata;\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tfrom_bundle_id: input.fromBundleId,\n\t\t\t\ttype: input.type,\n\t\t\t\tmetadata: {\n\t\t\t\t\t...metadata,\n\t\t\t\t\tfailure: {\n\t\t\t\t\t\tstage: failure.stage,\n\t\t\t\t\t\treason: failure.reason,\n\t\t\t\t\t\t...failure.errorMessage === void 0 ? {} : { error_message: failure.errorMessage },\n\t\t\t\t\t\t...failure.errorStack === void 0 ? {} : { error_stack: failure.errorStack },\n\t\t\t\t\t\t...failure.resource === void 0 ? {} : { resource: failure.resource },\n\t\t\t\t\t\t...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },\n\t\t\t\t\t\t...failure.transport === void 0 ? {} : { transport: failure.transport },\n\t\t\t\t\t\t...failure.originCode === void 0 ? {} : { origin_code: failure.originCode }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tcase \"UNCHANGED\": return {\n\t\t\t...base,\n\t\t\tfrom_bundle_id: null,\n\t\t\ttype: input.type,\n\t\t\tmetadata\n\t\t};\n\t}\n}\n//#endregion\nexport { EVENT_BODY_MAX_BYTES, createBundleEventRow, parseBundleEventRequest };\n", "import { compareInsightsText, isInsightsMovementEvent } from \"./contract.mjs\";\nimport { InsightsBadRequestError } from \"./errors.mjs\";\nimport { createBundleEventRow } from \"./eventInput.mjs\";\nimport { isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/provider.ts\nconst DEFAULT_PAGE_LIMIT = 50;\nconst MAX_PAGE_LIMIT = 100;\nconst MAX_EVENT_ID_LENGTH = 1024;\nconst MAX_IDENTITY_LENGTH = 255;\nconst MAX_CURSOR_LENGTH = 8192;\nconst HOUR_MS = 36e5;\nconst DAY_MS = 24 * HOUR_MS;\nconst WINDOW_MS = {\n\t\"24h\": 864e5,\n\t\"7d\": 6048e5,\n\t\"30d\": 2592e6\n};\n/**\n* The longest receipt range, `[sinceMs, beforeReceivedAtMs)`, of a global or\n* bundle event list, and the range one covers without `sinceMs`: raw events\n* are listed inside a time range, as analytics products list them. It is a\n* duration, so a range that ends mid-day touches 91 UTC days. Installation\n* history is one index range and reads back to `sinceMs`.\n*/\nconst EVENT_LIST_RANGE_MS = 2160 * HOUR_MS;\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst requireString = (value, label, maximumLength) => {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > maximumLength || new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new InsightsBadRequestError(`Invalid ${label}.`);\n\treturn value;\n};\nconst requireTimestamp = (value, label) => {\n\tif (!Number.isSafeInteger(value) || Number(value) < 0) throw new InsightsBadRequestError(`Invalid ${label}.`);\n\treturn Number(value);\n};\nconst readLimit = (value) => {\n\tconst limit = value ?? DEFAULT_PAGE_LIMIT;\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_PAGE_LIMIT) throw new InsightsBadRequestError(\"Invalid page limit.\");\n\treturn limit;\n};\nconst encodeBase64Url = (value) => {\n\tconst bytes = new TextEncoder().encode(value);\n\tlet binary = \"\";\n\tfor (const byte of bytes) binary += String.fromCharCode(byte);\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/u, \"\");\n};\nconst decodeBase64Url = (value) => {\n\tif (value.length === 0 || value.length > MAX_CURSOR_LENGTH) throw new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\ttry {\n\t\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\t\tconst padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n\t\tconst binary = atob(padded);\n\t\tconst bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));\n\t\treturn new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n\t} catch {\n\t\tthrow new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\t}\n};\nconst encodeCursor = (value) => encodeBase64Url(JSON.stringify(value));\nconst decodeCursor = (value) => {\n\ttry {\n\t\treturn JSON.parse(decodeBase64Url(value));\n\t} catch (error) {\n\t\tif (error instanceof InsightsBadRequestError) throw error;\n\t\tthrow new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\t}\n};\nconst readScope = (input) => {\n\tif (input.platform !== \"ios\" && input.platform !== \"android\") throw new InsightsBadRequestError(\"Invalid Insights platform.\");\n\treturn {\n\t\tplatform: input.platform,\n\t\tchannel: requireString(input.channel, \"channel\", MAX_EVENT_ID_LENGTH)\n\t};\n};\nconst bundleFilter = (input) => {\n\tconst scope = readScope(input);\n\tconst bundleId = requireString(input.bundleId, \"bundle ID\", MAX_EVENT_ID_LENGTH);\n\tswitch (input.outcome) {\n\t\tcase \"downloaded\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_DOWNLOADED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tcase \"applied\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_APPLIED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tcase \"recovered\": return {\n\t\t\t...scope,\n\t\t\ttype: \"RECOVERED\",\n\t\t\tfromBundleId: bundleId\n\t\t};\n\t\tcase \"failed\": return {\n\t\t\t...scope,\n\t\t\ttype: \"UPDATE_FAILED\",\n\t\t\ttoBundleId: bundleId\n\t\t};\n\t\tdefault: throw new InsightsBadRequestError(\"Invalid Insights outcome.\");\n\t}\n};\nconst sameFilter = (left, right) => {\n\tif (!isRecord(left) || left.kind !== right.kind) return false;\n\tswitch (right.kind) {\n\t\tcase \"all\": return true;\n\t\tcase \"installationMovement\": return left.installId === right.installId;\n\t\tcase \"bundle\": return left.platform === right.platform && left.channel === right.channel && left.type === right.type && (right.type === \"RECOVERED\" ? left.fromBundleId === right.fromBundleId : left.toBundleId === right.toBundleId);\n\t}\n};\nconst readEventCursor = (value, filter) => {\n\tconst cursor = decodeCursor(value);\n\tif (!isRecord(cursor) || cursor.version !== 2 || cursor.kind !== \"events\" || !isRecord(cursor.filter) || !isRecord(cursor.after)) throw new InsightsBadRequestError(\"Invalid Insights cursor.\");\n\tif (!sameFilter(cursor.filter, filter)) throw new InsightsBadRequestError(\"Insights cursor does not match the requested events.\");\n\tif (typeof cursor.after.id !== \"string\" || !isUUIDv7(cursor.after.id)) throw new InsightsBadRequestError(\"Invalid Insights event cursor ID.\");\n\treturn {\n\t\tafter: {\n\t\t\tid: cursor.after.id,\n\t\t\treceivedAtMs: requireTimestamp(cursor.after.receivedAtMs, \"event cursor\")\n\t\t},\n\t\tbeforeReceivedAtMs: requireTimestamp(cursor.beforeReceivedAtMs, \"event cutoff\"),\n\t\tkind: \"events\",\n\t\tsinceMs: requireTimestamp(cursor.sinceMs, \"event start\"),\n\t\tfilter,\n\t\tversion: 2\n\t};\n};\nconst readUserInstallationCursor = (value, userId) => {\n\tconst cursor = decodeCursor(value);\n\tif (!isRecord(cursor) || cursor.version !== 1 || cursor.kind !== \"user-installations\" || cursor.userId !== userId) throw new InsightsBadRequestError(\"Insights cursor does not match the requested user ID.\");\n\treturn {\n\t\tafterInstallId: requireString(cursor.afterInstallId, \"installation cursor\", MAX_IDENTITY_LENGTH),\n\t\tkind: \"user-installations\",\n\t\tuserId,\n\t\tversion: 1\n\t};\n};\nconst compareEventNewest = (left, right) => right.received_at_ms - left.received_at_ms || compareInsightsText(right.id, left.id);\nconst isAfterEventCursor = (row, after) => row.received_at_ms < after.receivedAtMs || row.received_at_ms === after.receivedAtMs && compareInsightsText(row.id, after.id) < 0;\nconst assertEventRows = (rows, input) => {\n\tif (rows.length > input.limit) throw new Error(\"Insights database returned too many event rows.\");\n\tfor (let index = 0; index < rows.length; index += 1) {\n\t\tconst row = rows[index];\n\t\tconst previous = rows[index - 1];\n\t\tif (!row || typeof row.id !== \"string\" || !isUUIDv7(row.id) || !Number.isSafeInteger(row.received_at_ms) || row.received_at_ms >= input.beforeReceivedAtMs || row.received_at_ms < input.sinceMs || previous !== void 0 && compareEventNewest(previous, row) >= 0 || input.after !== void 0 && !isAfterEventCursor(row, input.after) || input.filter.kind === \"installationMovement\" && (row.install_id !== input.filter.installId || !isInsightsMovementEvent(row)) || input.filter.kind === \"bundle\" && (row.platform !== input.filter.platform || row.channel !== input.filter.channel || row.type !== input.filter.type || (input.filter.type === \"RECOVERED\" ? row.from_bundle_id !== input.filter.fromBundleId : row.to_bundle_id !== input.filter.toBundleId))) throw new Error(\"Insights database returned invalid event rows.\");\n\t}\n};\n/** An `UPDATE_FAILED` row's failure, as the event lists show it. */\nconst toFailure = (failure) => ({\n\tstage: failure.stage,\n\treason: failure.reason,\n\t...failure.error_message === void 0 ? {} : { errorMessage: failure.error_message },\n\t...failure.error_stack === void 0 ? {} : { errorStack: failure.error_stack },\n\t...failure.resource === void 0 ? {} : { resource: failure.resource },\n\t...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },\n\t...failure.transport === void 0 ? {} : { transport: failure.transport },\n\t...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code }\n});\n/** What a row's metadata adds for its type: a failure or a delivery. */\nconst eventDetails = ({ type, metadata }) => ({\n\t...metadata.http_response !== void 0 ? { httpResponse: {\n\t\tresource: metadata.http_response.resource,\n\t\tpath: metadata.http_response.path,\n\t\tstatus: metadata.http_response.status,\n\t\tbody: metadata.http_response.body,\n\t\tbodyTruncated: metadata.http_response.body_truncated,\n\t\treceivedAtMs: metadata.http_response.received_at_ms\n\t} } : {},\n\t...type === \"UPDATE_FAILED\" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},\n\t...type === \"UPDATE_DOWNLOADED\" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},\n\t...type === \"UPDATE_DOWNLOADED\" && metadata.patch_fallback === true ? { patchFallback: true } : {},\n\t...type === \"UNCHANGED\" && metadata.change !== void 0 ? { change: {\n\t\tkinds: metadata.change.kinds,\n\t\t...metadata.change.previous === null ? {} : { previous: {\n\t\t\tbundleId: metadata.change.previous.bundle_id,\n\t\t\treleaseId: metadata.change.previous.release_id,\n\t\t\tappVersion: metadata.change.previous.app_version,\n\t\t\tchannel: metadata.change.previous.channel,\n\t\t\t...metadata.change.previous.min_bundle_id === void 0 ? {} : { minBundleId: metadata.change.previous.min_bundle_id }\n\t\t} }\n\t} } : {},\n\t...metadata.late === true ? { late: true } : {},\n\t...metadata.implied_download === true ? { impliedDownload: true } : {}\n});\nconst toEventHistoryRow = (row) => ({\n\t...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },\n\t...row.metadata.sdk_version == null ? {} : { sdkVersion: row.metadata.sdk_version },\n\t...row.metadata.min_bundle_id === void 0 ? {} : { minBundleId: row.metadata.min_bundle_id },\n\tappVersion: row.app_version,\n\tchannel: row.channel,\n\tcohort: row.metadata.cohort,\n\tfromBundleId: row.from_bundle_id,\n\tid: row.id,\n\tinstallId: row.install_id,\n\tplatform: row.platform,\n\treceivedAtMs: row.received_at_ms,\n\ttoBundleId: row.to_bundle_id,\n\ttype: row.type,\n\tuserId: row.user_id,\n\t...eventDetails(row)\n});\nconst toInstallationRow = (row) => ({\n\t...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},\n\t...row.metadata.min_bundle_id === void 0 ? {} : { minBundleId: row.metadata.min_bundle_id },\n\tappVersion: row.app_version,\n\tchannel: row.channel,\n\tcohort: row.metadata.cohort,\n\tinstallId: row.install_id,\n\tlastKnownBundleId: row.type === \"UPDATE_DOWNLOADED\" ? row.from_bundle_id : row.to_bundle_id,\n\tpendingBundleId: row.type === \"UPDATE_DOWNLOADED\" ? row.to_bundle_id : null,\n\tpendingReleaseId: row.type === \"UPDATE_DOWNLOADED\" ? row.to_release_id : null,\n\tlatestStatus: row.type,\n\tplatform: row.platform,\n\treceivedAtMs: row.received_at_ms,\n\tuserId: row.user_id\n});\n/**\n* Where a list without `sinceMs` starts: 90 days before its cutoff for the\n* global and bundle lists, at the first event for installation history.\n*/\nconst defaultEventStart = (filter, beforeReceivedAtMs) => filter.kind === \"installationMovement\" ? 0 : Math.max(0, beforeReceivedAtMs - EVENT_LIST_RANGE_MS);\n/** Whether a cursor's row lies inside the list's range. */\nconst isInsideBounds = ({ after }, bounds) => after.receivedAtMs >= bounds.sinceMs && after.receivedAtMs < bounds.beforeReceivedAtMs;\n/** A page's range: its cursor's, which the request may repeat but not change. */\nconst readEventBounds = (input, cursor, filter) => {\n\tconst beforeReceivedAtMs = cursor?.beforeReceivedAtMs ?? (input.beforeReceivedAtMs === void 0 ? Date.now() : requireTimestamp(input.beforeReceivedAtMs, \"event cutoff\"));\n\tif (cursor !== void 0 && input.beforeReceivedAtMs !== void 0 && input.beforeReceivedAtMs !== beforeReceivedAtMs) throw new InsightsBadRequestError(\"Insights cursor does not match the requested event cutoff.\");\n\tconst sinceMs = cursor?.sinceMs ?? (input.sinceMs === void 0 ? defaultEventStart(filter, beforeReceivedAtMs) : requireTimestamp(input.sinceMs, \"event start\"));\n\tconst bounds = {\n\t\tbeforeReceivedAtMs,\n\t\tsinceMs\n\t};\n\tif (sinceMs > beforeReceivedAtMs || input.sinceMs !== void 0 && input.sinceMs !== sinceMs || cursor !== void 0 && !isInsideBounds(cursor, bounds)) throw new InsightsBadRequestError(\"Insights cursor or range does not match the requested event start.\");\n\tif (filter.kind !== \"installationMovement\" && beforeReceivedAtMs - sinceMs > 7776e6) throw new InsightsBadRequestError(\"Insights event lists cover at most 90 days: send a sinceMs no more than 90 days before beforeReceivedAtMs.\");\n\treturn bounds;\n};\nconst pageEventRows = async (model, input, filter, map) => {\n\tconst limit = readLimit(input.limit);\n\tconst cursor = input.cursor === void 0 ? void 0 : readEventCursor(input.cursor, filter);\n\tconst bounds = readEventBounds(input, cursor, filter);\n\tconst query = {\n\t\tfilter,\n\t\t...bounds,\n\t\t...cursor === void 0 ? {} : { after: cursor.after },\n\t\tlimit\n\t};\n\tconst rows = await model.listEvents(query);\n\tassertEventRows(rows, query);\n\tconst last = rows.at(-1);\n\treturn {\n\t\tbeforeReceivedAtMs: bounds.beforeReceivedAtMs,\n\t\tdata: rows.map(map),\n\t\tnextCursor: rows.length === limit && last ? encodeCursor({\n\t\t\tafter: {\n\t\t\t\tid: last.id,\n\t\t\t\treceivedAtMs: last.received_at_ms\n\t\t\t},\n\t\t\t...bounds,\n\t\t\tkind: \"events\",\n\t\t\tfilter,\n\t\t\tversion: 2\n\t\t}) : null\n\t};\n};\nconst assertInstallationRows = (rows, input) => {\n\tif (rows.length > input.limit) throw new Error(\"Insights database returned too many installation rows.\");\n\tfor (let index = 0; index < rows.length; index += 1) {\n\t\tconst row = rows[index];\n\t\tconst previous = rows[index - 1];\n\t\tif (!row || row.user_id !== input.userId || input.afterInstallId !== void 0 && compareInsightsText(row.install_id, input.afterInstallId) <= 0 || previous !== void 0 && compareInsightsText(previous.install_id, row.install_id) >= 0) throw new Error(\"Insights database returned invalid installation rows.\");\n\t}\n};\nconst createInsightsProvider = (model) => Object.freeze({\n\tasync appendBundleEvent(input) {\n\t\tconst event = createBundleEventRow(input);\n\t\tawait model.recordEvent({ event });\n\t},\n\tlistEvents(input) {\n\t\tconst filter = input.bundle === void 0 ? { kind: \"all\" } : {\n\t\t\tkind: \"bundle\",\n\t\t\t...bundleFilter(input.bundle)\n\t\t};\n\t\treturn pageEventRows(model, input, filter, toEventHistoryRow);\n\t},\n\tasync listInstallationEvents(input) {\n\t\tif (\"bundle\" in input && input.bundle !== void 0) throw new InsightsBadRequestError(\"Installation movement queries cannot include a bundle filter.\");\n\t\tconst installId = requireString(input.installId, \"install ID\", MAX_IDENTITY_LENGTH);\n\t\treturn pageEventRows(model, input, {\n\t\t\tkind: \"installationMovement\",\n\t\t\tinstallId\n\t\t}, (row) => toEventHistoryRow(row));\n\t},\n\tasync getInstallation({ installId }) {\n\t\tconst normalizedInstallId = requireString(installId, \"install ID\", MAX_IDENTITY_LENGTH);\n\t\tconst rows = await model.findLatestEvents({ installId: normalizedInstallId });\n\t\tconst row = rows[0] ?? null;\n\t\tif (rows.length > 1 || row !== null && row.install_id !== normalizedInstallId) throw new Error(\"Insights database returned an invalid installation.\");\n\t\treturn row === null ? null : toInstallationRow(row);\n\t},\n\tasync pageInstallationsByCurrentUserId(input) {\n\t\tconst userId = requireString(input.userId, \"user ID\", MAX_IDENTITY_LENGTH);\n\t\tconst limit = readLimit(input.limit);\n\t\tconst cursor = input.cursor === void 0 ? void 0 : readUserInstallationCursor(input.cursor, userId);\n\t\tconst databaseInput = {\n\t\t\tuserId,\n\t\t\t...cursor === void 0 ? {} : { afterInstallId: cursor.afterInstallId },\n\t\t\tlimit\n\t\t};\n\t\tconst rows = await model.findLatestEvents(databaseInput);\n\t\tassertInstallationRows(rows, databaseInput);\n\t\tconst last = rows.at(-1);\n\t\treturn {\n\t\t\tdata: rows.map(toInstallationRow),\n\t\t\tnextCursor: rows.length === limit && last ? encodeCursor({\n\t\t\t\tafterInstallId: last.install_id,\n\t\t\t\tkind: \"user-installations\",\n\t\t\t\tuserId,\n\t\t\t\tversion: 1\n\t\t\t}) : null\n\t\t};\n\t},\n\tasync getReportingOverview(input) {\n\t\tconst scope = readScope(input);\n\t\tconst { window } = input;\n\t\tif (!Object.hasOwn(WINDOW_MS, window)) throw new InsightsBadRequestError(\"Invalid reporting installation window.\");\n\t\tconst now = Date.now();\n\t\tconst beforeReceivedAtMs = now - now % HOUR_MS + (now % HOUR_MS === 0 ? 0 : HOUR_MS);\n\t\tconst reach = Math.max(0, beforeReceivedAtMs - WINDOW_MS[window]);\n\t\tconst sinceMs = reach - reach % DAY_MS;\n\t\tconst measure = async (count) => {\n\t\t\tconst value = await count;\n\t\t\tif (!Number.isSafeInteger(value) || value < 0) throw new Error(\"Insights database returned an invalid count.\");\n\t\t\treturn {\n\t\t\t\tcount: value,\n\t\t\t\tmeasuredAtMs: Date.now()\n\t\t\t};\n\t\t};\n\t\tconst bundleId = input.bundleId === void 0 ? void 0 : requireString(input.bundleId, \"bundle ID\", MAX_EVENT_ID_LENGTH);\n\t\tconst reporting = measure(model.countLatestEvents({\n\t\t\t...scope,\n\t\t\tsinceMs\n\t\t}));\n\t\tif (bundleId === void 0) return {\n\t\t\t...scope,\n\t\t\twindow,\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs,\n\t\t\treportingInstallations: await reporting\n\t\t};\n\t\tconst countOutcome = (outcome) => measure(model.countEvents({\n\t\t\tfilter: bundleFilter({\n\t\t\t\t...scope,\n\t\t\t\tbundleId,\n\t\t\t\toutcome\n\t\t\t}),\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs\n\t\t}));\n\t\tconst [reportingInstallations, bundleInstallations, downloadedReports, appliedReports, recoveredReports, failedReports] = await Promise.all([\n\t\t\treporting,\n\t\t\tmeasure(model.countLatestEvents({\n\t\t\t\t...scope,\n\t\t\t\tsinceMs,\n\t\t\t\tbundle: [{\n\t\t\t\t\tfield: \"from_bundle_id\",\n\t\t\t\t\tvalue: bundleId,\n\t\t\t\t\ttypes: [\"UPDATE_DOWNLOADED\"]\n\t\t\t\t}, {\n\t\t\t\t\tfield: \"to_bundle_id\",\n\t\t\t\t\tvalue: bundleId,\n\t\t\t\t\ttypes: [\n\t\t\t\t\t\t\"UNCHANGED\",\n\t\t\t\t\t\t\"UPDATE_APPLIED\",\n\t\t\t\t\t\t\"RECOVERED\"\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t})),\n\t\t\tcountOutcome(\"downloaded\"),\n\t\t\tcountOutcome(\"applied\"),\n\t\t\tcountOutcome(\"recovered\"),\n\t\t\tcountOutcome(\"failed\")\n\t\t]);\n\t\treturn {\n\t\t\t...scope,\n\t\t\twindow,\n\t\t\tsinceMs,\n\t\t\tbeforeReceivedAtMs,\n\t\t\treportingInstallations,\n\t\t\tbundle: {\n\t\t\t\tbundleId,\n\t\t\t\treportingInstallations: bundleInstallations,\n\t\t\t\tdownloadedReports,\n\t\t\t\tappliedReports,\n\t\t\t\trecoveredReports,\n\t\t\t\tfailedReports\n\t\t\t}\n\t\t};\n\t}\n});\n//#endregion\nexport { EVENT_LIST_RANGE_MS, createInsightsProvider };\n", "import { isLateEvent, isLaunch } from \"./schema.mjs\";\n//#region src/server/overview.ts\nconst encodeIdentity = (identity) => [\n\tidentity.scopeKind,\n\tidentity.releaseKind,\n\tidentity.releaseId,\n\tidentity.channel,\n\tidentity.platform,\n\tidentity.appVersionKind,\n\tidentity.appVersion,\n\tidentity.periodKind,\n\tString(identity.bucketStartMs)\n].map((value) => `${new TextEncoder().encode(value).length}:${value}`).join(\"\");\nconst fnv = (value, seed) => {\n\tlet result = seed;\n\tfor (const byte of new TextEncoder().encode(value)) {\n\t\tresult ^= BigInt(byte);\n\t\tresult = BigInt.asUintN(64, result * 1099511628211n);\n\t}\n\treturn result.toString(16).padStart(16, \"0\");\n};\n/** A 128-bit hex key for a string: two FNV-1a 64 hashes with different seeds. */\nconst insightsKey = (value) => `${fnv(value, 14695981039346656037n)}${fnv(value, 9521211207457086692n)}`;\nconst insightsOverviewId = (identity) => insightsKey(encodeIdentity(identity));\nconst hour = (value) => Math.floor(value / 36e5) * 36e5;\nconst insightsOverviewDeltas = (event) => {\n\tconst bucketStartMs = hour(event.received_at_ms);\n\tconst counters = /* @__PURE__ */ new Map();\n\tconst append = (identity, values) => {\n\t\tconst key = encodeIdentity(identity);\n\t\tconst previous = counters.get(key);\n\t\tcounters.set(key, {\n\t\t\tidentity,\n\t\t\tdownloads: (previous?.downloads ?? 0) + values.downloads,\n\t\t\tapplies: (previous?.applies ?? 0) + values.applies,\n\t\t\tfailedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,\n\t\t\tactivityIdentity: previous?.activityIdentity ?? values.activityIdentity\n\t\t});\n\t};\n\tconst metric = (releaseId, values) => {\n\t\tconst windowed = {\n\t\t\t...values,\n\t\t\tapplies: 0\n\t\t};\n\t\tif (releaseId !== null) for (const [periodKind, start] of [[\"lifetime\", 0], [\"hour\", bucketStartMs]]) append({\n\t\t\tscopeKind: \"release\",\n\t\t\treleaseKind: \"specific\",\n\t\t\treleaseId,\n\t\t\tchannel: event.channel,\n\t\t\tplatform: event.platform,\n\t\t\tappVersionKind: \"all\",\n\t\t\tappVersion: \"\",\n\t\t\tperiodKind,\n\t\t\tbucketStartMs: start\n\t\t}, periodKind === \"lifetime\" ? values : windowed);\n\t\tappend({\n\t\t\tscopeKind: \"channel\",\n\t\t\treleaseKind: \"all\",\n\t\t\treleaseId: \"\",\n\t\t\tchannel: event.channel,\n\t\t\tplatform: event.platform,\n\t\t\tappVersionKind: \"all\",\n\t\t\tappVersion: \"\",\n\t\t\tperiodKind: \"hour\",\n\t\t\tbucketStartMs\n\t\t}, windowed);\n\t};\n\tconst implied = event.metadata.implied_download === true ? 1 : 0;\n\tif (!isLateEvent(event) && event.type === \"UPDATE_DOWNLOADED\") metric(event.to_release_id, {\n\t\tdownloads: 1,\n\t\tapplies: 0,\n\t\tfailedLaunches: 0\n\t});\n\telse if (!isLateEvent(event) && isLaunch(event)) metric(event.to_release_id, {\n\t\tdownloads: implied,\n\t\tapplies: 1,\n\t\tfailedLaunches: 0\n\t});\n\telse if (!isLateEvent(event) && event.type === \"RECOVERED\") metric(event.from_release_id, {\n\t\tdownloads: implied,\n\t\tapplies: 0,\n\t\tfailedLaunches: 1\n\t});\n\tfor (const platform of [event.platform, \"all\"]) for (const appVersionKind of [\"specific\", \"all\"]) append({\n\t\tscopeKind: \"usage\",\n\t\treleaseKind: \"all\",\n\t\treleaseId: \"\",\n\t\tchannel: event.channel,\n\t\tplatform,\n\t\tappVersionKind,\n\t\tappVersion: appVersionKind === \"specific\" ? event.app_version : \"\",\n\t\tperiodKind: \"hour\",\n\t\tbucketStartMs\n\t}, {\n\t\tdownloads: 0,\n\t\tapplies: 0,\n\t\tfailedLaunches: 0,\n\t\tactivityIdentity: event.install_id\n\t});\n\treturn [...counters.values()];\n};\n//#endregion\nexport { insightsKey, insightsOverviewDeltas, insightsOverviewId };\n", "import { runningBuiltinBundleId } from \"./eventRow.mjs\";\nimport { DAILY_EVENTS, DAY_MS, HOUR_MS, bundleRefOfFilter, bundleRefsOf, isLaunch } from \"./schema.mjs\";\nimport { assertBundleEventRow } from \"./contract.mjs\";\nimport { insightsKey, insightsOverviewDeltas, insightsOverviewId } from \"./overview.mjs\";\nimport { addDistinct, compareUtf8, extractTimestampFromUUIDv7, isUUIDv7 } from \"@hot-updater/plugin-core\";\n//#region src/server/recordEvent.ts\nconst hourOf = (ms) => ms - ms % HOUR_MS;\nconst dayOf = (ms) => ms - ms % DAY_MS;\n/** The `identity` of an overview or sketch row: its scope and period, hashed. */\nconst insightsIdentity = (identity) => insightsOverviewId({\n\t...identity,\n\tscopeKind: identity.scopeKind,\n\tperiodKind: identity.periodKind,\n\tbucketStartMs: 0\n});\n/**\n* The bucket a head's gauges count it in, the UTC day of its event, and what\n* its distribution row names: the release it runs, which a download leaves\n* at its source, and the built-in bundle, when it runs the native build's.\n* A head stored without the built-in bundle ID counts in no built-in row, so\n* taking it back moves none.\n*/\nconst gaugeSlot = (head) => ({\n\tbucket: dayOf(head.received_at_ms),\n\treleaseId: head.type === \"UPDATE_DOWNLOADED\" ? head.from_release_id : head.to_release_id,\n\tbuiltinBundleId: runningBuiltinBundleId(head)\n});\n/**\n* The `insights_latest_by_bundle` field of a head's (from, to) pair. A head\n* matches a `from` and a `to` predicate of one type at once only through its\n* pair, so this gauge is what a count subtracts to count it once.\n*/\nconst PAIR_FIELD = \"from_to\";\n/** The pair gauge's `bundle_id`: a hash of the two bundle ids, which fit no single 36-character column. */\nconst bundlePairKey = (from, to) => insightsKey(`${from.length}:${from}${to.length}:${to}`);\n/**\n* Moves a head's gauges: the distribution row, and the built-in one when it\n* runs its build's built-in bundle, one row per bundle it references, and\n* its pair; -1 takes back the head an event replaces.\n*/\nconst countHead = (tx, head, delta) => {\n\tconst { bucket, releaseId, builtinBundleId } = gaugeSlot(head);\n\tconst shardBy = head.install_id;\n\ttx.aggregate(\"insights_distribution\", {\n\t\tchannel: head.channel,\n\t\tplatform: head.platform,\n\t\tapp_version: head.app_version,\n\t\trelease_id: releaseId ?? \"\",\n\t\tbucket_start_ms: bucket\n\t}, { latest_installations: delta }, { shardBy });\n\tif (builtinBundleId !== null) tx.aggregate(\"insights_builtin_distribution\", {\n\t\tchannel: head.channel,\n\t\tplatform: head.platform,\n\t\tapp_version: head.app_version,\n\t\trelease_id: releaseId ?? \"\",\n\t\tbuiltin_bundle_id: builtinBundleId,\n\t\tbucket_start_ms: bucket\n\t}, { latest_installations: delta }, { shardBy });\n\tfor (const field of [\"from_bundle_id\", \"to_bundle_id\"]) {\n\t\tconst bundleId = head[field];\n\t\tif (bundleId === null) continue;\n\t\ttx.aggregate(\"insights_latest_by_bundle\", {\n\t\t\tplatform: head.platform,\n\t\t\tchannel: head.channel,\n\t\t\tbundle_field: field,\n\t\t\tbundle_id: bundleId,\n\t\t\ttype: head.type,\n\t\t\tbucket_start_ms: bucket\n\t\t}, { installations: delta }, { shardBy });\n\t}\n\tif (head.from_bundle_id !== null) tx.aggregate(\"insights_latest_by_bundle\", {\n\t\tplatform: head.platform,\n\t\tchannel: head.channel,\n\t\tbundle_field: PAIR_FIELD,\n\t\tbundle_id: bundlePairKey(head.from_bundle_id, head.to_bundle_id),\n\t\ttype: head.type,\n\t\tbucket_start_ms: bucket\n\t}, { installations: delta }, { shardBy });\n};\n/**\n* Where each period's rows go, each with its retention: hours for 90 days,\n* days for 13 months, and a release's lifetime counters kept.\n*/\nconst PERIOD_MODELS = {\n\thour: {\n\t\tcounters: \"insights_overview\",\n\t\tsketches: \"insights_sketches\"\n\t},\n\tday: {\n\t\tcounters: \"insights_overview_daily\",\n\t\tsketches: \"insights_sketches_daily\"\n\t},\n\tlifetime: {\n\t\tcounters: \"insights_overview_lifetime\",\n\t\tsketches: void 0\n\t}\n};\n/** A download's patch counters: a patch delivered it, or it fell back from one. */\nconst patchCounters = (event) => event.type !== \"UPDATE_DOWNLOADED\" ? {} : {\n\t...event.metadata.delivery === \"patch\" ? { patch_downloads: 1 } : {},\n\t...event.metadata.patch_fallback === true ? { patch_fallbacks: 1 } : {}\n};\n/**\n* Counters and sketches for one event: release, channel, and usage rows, with\n* day rollups for channel and usage. Only usage rows keep a sketch, of active\n* installations, and only for the event's platform, since a read for every\n* platform merges the ios and android sketches. A download's patch counters\n* go in the rows that count it.\n*/\nconst countEvent = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tfor (const delta of insightsOverviewDeltas(event)) {\n\t\tif (delta.identity.platform === \"all\") continue;\n\t\tconst { bucketStartMs, ...parts } = delta.identity;\n\t\tconst periods = parts.scopeKind === \"channel\" || parts.scopeKind === \"usage\" ? [[\"hour\", bucketStartMs], [\"day\", dayOf(event.received_at_ms)]] : [[parts.periodKind, bucketStartMs]];\n\t\tfor (const [periodKind, bucket] of periods) {\n\t\t\tconst models = PERIOD_MODELS[periodKind];\n\t\t\tconst key = {\n\t\t\t\tidentity: insightsIdentity({\n\t\t\t\t\t...parts,\n\t\t\t\t\tperiodKind\n\t\t\t\t}),\n\t\t\t\tbucket_start_ms: bucket\n\t\t\t};\n\t\t\tconst counters = {\n\t\t\t\t...Object.fromEntries([\n\t\t\t\t\t[\"downloads\", delta.downloads],\n\t\t\t\t\t[\"applies\", delta.applies],\n\t\t\t\t\t[\"failed_launches\", delta.failedLaunches]\n\t\t\t\t].filter(([, value]) => value !== 0)),\n\t\t\t\t...delta.downloads === 0 ? {} : patchCounters(event)\n\t\t\t};\n\t\t\tif (Object.keys(counters).length > 0) tx.aggregate(models.counters, key, counters, { shardBy });\n\t\t\tif (models.sketches !== void 0 && delta.activityIdentity !== void 0) tx.aggregate(models.sketches, key, { activity_users: addDistinct(null, delta.activityIdentity) }, { shardBy });\n\t\t}\n\t}\n};\n/**\n* A stored event's outcome rows: its bundle filter's hour, when it has one\n* (`bundleRefsOf`), and every stored event's UTC day. A download that a\n* launch or crash implied counts in its bundle's download hour too, in the\n* hour of that launch or crash, so the download series covers what the\n* release's downloads count; the launch or crash is its row.\n*/\nconst countOutcome = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tconst hour = (type, bundleRef) => tx.aggregate(\"insights_outcomes\", {\n\t\tplatform: event.platform,\n\t\tchannel: event.channel,\n\t\ttype,\n\t\tbundle_ref: bundleRef,\n\t\tbucket_start_ms: hourOf(event.received_at_ms)\n\t}, { events: 1 }, { shardBy });\n\tfor (const bundleRef of bundleRefsOf(event)) hour(event.type, bundleRef);\n\tif (event.metadata.implied_download === true) hour(\"UPDATE_DOWNLOADED\", bundleRefOfFilter({\n\t\ttype: \"UPDATE_DOWNLOADED\",\n\t\ttoBundleId: event.type === \"RECOVERED\" ? event.from_bundle_id : event.to_bundle_id\n\t}));\n\ttx.aggregate(\"insights_outcomes\", {\n\t\t...DAILY_EVENTS,\n\t\tbucket_start_ms: dayOf(event.received_at_ms)\n\t}, { events: 1 }, { shardBy });\n};\n/** The row check requires an UPDATE_FAILED row's failure; its type leaves it optional. */\nconst UNKNOWN_FAILURE = {\n\tstage: \"unknown\",\n\treason: \"unknown\"\n};\n/** A failure's `detail`: what else the client knew, as a JSON array. */\nconst failureDetail = (failure) => JSON.stringify([\n\tfailure.resource ?? null,\n\tfailure.http_status ?? null,\n\tfailure.origin_code ?? null,\n\tfailure.transport ?? null\n]);\n/**\n* An update failure's sketches, breakdown row, and lifetime counter. Its\n* hourly breakdown row is what windowed reads sum, so no hourly or daily\n* counter repeats it. A failed check counts for its channel, in the `check`\n* sketch of installations. Any other failure counts in the channel's\n* `failure` sketch, and for its target release, when it names one, in the\n* release's hourly and lifetime `failure` sketches and its lifetime\n* `failed_updates`, which the bundle detail reads. A failure is no launch\n* and no activity: the installation reports its launch that day.\n*/\nconst countFailure = (tx, event) => {\n\tconst shardBy = event.install_id;\n\tconst failure = event.metadata.failure ?? UNKNOWN_FAILURE;\n\tconst check = failure.stage === \"check\";\n\tconst hour = hourOf(event.received_at_ms);\n\tconst scope = {\n\t\tchannel: event.channel,\n\t\tplatform: event.platform,\n\t\tappVersionKind: \"all\",\n\t\tappVersion: \"\"\n\t};\n\tconst channel = {\n\t\t...scope,\n\t\treleaseKind: \"all\",\n\t\treleaseId: \"\"\n\t};\n\tconst users = { failed_users: addDistinct(null, event.install_id) };\n\tfor (const [periodKind, bucket] of [[\"hour\", hour], [\"day\", dayOf(event.received_at_ms)]]) {\n\t\tconst identity = insightsIdentity({\n\t\t\t...channel,\n\t\t\tscopeKind: check ? \"check\" : \"failure\",\n\t\t\tperiodKind\n\t\t});\n\t\ttx.aggregate(PERIOD_MODELS[periodKind].sketches, {\n\t\t\tidentity,\n\t\t\tbucket_start_ms: bucket\n\t\t}, users, { shardBy });\n\t}\n\tconst releaseId = check ? null : event.to_release_id;\n\tif (releaseId !== null) {\n\t\tconst release = {\n\t\t\t...scope,\n\t\t\treleaseKind: \"specific\",\n\t\t\treleaseId\n\t\t};\n\t\tfor (const [periodKind, bucket, sketches] of [[\n\t\t\t\"hour\",\n\t\t\thour,\n\t\t\t\"insights_sketches\"\n\t\t], [\n\t\t\t\"lifetime\",\n\t\t\t0,\n\t\t\t\"insights_sketches_lifetime\"\n\t\t]]) {\n\t\t\tconst key = (scopeKind) => ({\n\t\t\t\tidentity: insightsIdentity({\n\t\t\t\t\t...release,\n\t\t\t\t\tscopeKind,\n\t\t\t\t\tperiodKind\n\t\t\t\t}),\n\t\t\t\tbucket_start_ms: bucket\n\t\t\t});\n\t\t\ttx.aggregate(sketches, key(\"failure\"), users, { shardBy });\n\t\t}\n\t\ttx.aggregate(\"insights_overview_lifetime\", {\n\t\t\tidentity: insightsIdentity({\n\t\t\t\t...release,\n\t\t\t\tscopeKind: \"release\",\n\t\t\t\tperiodKind: \"lifetime\"\n\t\t\t}),\n\t\t\tbucket_start_ms: 0\n\t\t}, { failed_updates: 1 }, { shardBy });\n\t}\n\ttx.aggregate(\"insights_failures\", {\n\t\tplatform: event.platform,\n\t\tchannel: event.channel,\n\t\tbucket_start_ms: hour,\n\t\trelease_id: releaseId ?? \"\",\n\t\tstage: failure.stage,\n\t\treason: failure.reason,\n\t\tdetail: failureDetail(failure)\n\t}, { events: 1 }, { shardBy });\n};\nconst isNewer = (event, head) => event.received_at_ms !== head.received_at_ms ? event.received_at_ms > head.received_at_ms : compareUtf8(event.id, head.id) > 0;\n/** What a head says its installation runs: a download leaves it at the source. */\nconst runningOf = (head) => head.type === \"UPDATE_DOWNLOADED\" ? {\n\tbundle_id: head.from_bundle_id,\n\trelease_id: head.from_release_id\n} : {\n\tbundle_id: head.to_bundle_id,\n\trelease_id: head.to_release_id\n};\n/** The native build a report or head came from, when its SDK says. */\nconst minBundleIdOf = (row) => row.metadata?.min_bundle_id;\n/** When the client made a report, from the UUIDv7 it gave it. */\nconst madeAt = (id) => isUUIDv7(id) ? extractTimestampFromUUIDv7(id) : null;\n/**\n* A report its installation already moved past, which stays in history but\n* moves and counts nothing:\n* - a download or an apply of the bundle the head already runs, or a\n* download that repeats the head's pending one, from the same bundle to\n* the same bundle: the installation's download or launch already counted;\n* - an UNCHANGED report made, by its UUIDv7, before the head's report, even\n* after a later report replaced the apply it preceded: a reload can cut\n* one runtime's report short and deliver it after the next runtime's.\n*\n* Report IDs are made on the device, so a device whose clock jumps back has\n* its launch reports judged late until its clock passes its latest report.\n*/\nconst isLate = (event, head) => {\n\tif (head === null) return false;\n\tif (event.type === \"UPDATE_DOWNLOADED\" || event.type === \"UPDATE_APPLIED\") return event.to_bundle_id === runningOf(head).bundle_id || event.type === \"UPDATE_DOWNLOADED\" && head.type === \"UPDATE_DOWNLOADED\" && event.from_bundle_id === head.from_bundle_id && event.to_bundle_id === head.to_bundle_id;\n\tif (event.type === \"UNCHANGED\") {\n\t\tconst made = madeAt(event.id);\n\t\tconst latest = madeAt(head.id);\n\t\treturn made !== null && latest !== null && made < latest;\n\t}\n\treturn false;\n};\n/**\n* What an UNCHANGED report changes against its installation's head: the\n* running bundle or release, the app version, the channel, or the native\n* build (when both name it), with the head's values before it; `first_seen`\n* when the installation has no head. A report the head already answers, one\n* older than the head, a user switch and any other event type change\n* nothing, so no row keeps them.\n*/\nconst changeOf = (event, head) => {\n\tif (event.type !== \"UNCHANGED\") return null;\n\tif (head === null) return {\n\t\tkinds: [\"first_seen\"],\n\t\tprevious: null\n\t};\n\tif (!isNewer(event, head)) return null;\n\tconst running = runningOf(head);\n\tconst build = minBundleIdOf(event);\n\tconst headBuild = minBundleIdOf(head);\n\tconst kinds = [];\n\tif (event.to_bundle_id !== running.bundle_id) kinds.push(\"bundle\");\n\tif (event.to_release_id !== running.release_id) kinds.push(\"release\");\n\tif (event.app_version !== head.app_version) kinds.push(\"app_version\");\n\tif (event.channel !== head.channel) kinds.push(\"channel\");\n\tif (build !== void 0 && headBuild !== void 0 && build !== headBuild) kinds.push(\"native_build\");\n\treturn kinds.length === 0 ? null : {\n\t\tkinds,\n\t\tprevious: {\n\t\t\tbundle_id: running.bundle_id,\n\t\t\trelease_id: running.release_id,\n\t\t\tapp_version: head.app_version,\n\t\t\tchannel: head.channel,\n\t\t\t...headBuild === void 0 ? {} : { min_bundle_id: headBuild }\n\t\t}\n\t};\n};\n/**\n* Whether a launch or a crash comes with no download report for its target:\n* its head shows neither that download nor the target already running. The\n* native build's built-in bundle is never downloaded, and without a head the\n* server knows nothing of the installation's past, so it implies nothing.\n*/\nconst impliesDownload = (event, head) => {\n\tconst target = event.type === \"RECOVERED\" ? {\n\t\tbundle: event.from_bundle_id,\n\t\trelease: event.from_release_id\n\t} : isLaunch(event) ? {\n\t\tbundle: event.to_bundle_id,\n\t\trelease: event.to_release_id\n\t} : null;\n\tif (target === null || target.release === null || target.bundle === minBundleIdOf(event)) return false;\n\tif (head === null) return false;\n\tif (head.type === \"UPDATE_DOWNLOADED\" && head.to_bundle_id === target.bundle) return false;\n\treturn runningOf(head).bundle_id !== target.bundle;\n};\n/**\n* The event as recorded, with what only the server sets: what a kept\n* UNCHANGED report changed, a late report's flag, and a download its launch\n* or crash implied.\n*/\nconst recordedOf = (event, head) => {\n\tconst { change: _change, late: _late, implied_download: _implied, ...metadata } = event.metadata;\n\tconst reported = {\n\t\t...event,\n\t\tmetadata\n\t};\n\tconst late = isLate(reported, head);\n\tconst change = late ? null : changeOf(reported, head);\n\tconst withChange = change === null ? reported : {\n\t\t...reported,\n\t\tmetadata: {\n\t\t\t...metadata,\n\t\t\tchange\n\t\t}\n\t};\n\treturn {\n\t\trecorded: late && reported.type !== \"UNCHANGED\" ? {\n\t\t\t...reported,\n\t\t\tmetadata: {\n\t\t\t\t...metadata,\n\t\t\t\tlate: true\n\t\t\t}\n\t\t} : !late && impliesDownload(withChange, head) ? {\n\t\t\t...withChange,\n\t\t\tmetadata: {\n\t\t\t\t...withChange.metadata,\n\t\t\t\timplied_download: true\n\t\t\t}\n\t\t} : withChange,\n\t\tlate\n\t};\n};\n/** What an UNCHANGED report must share with its installation's head to repeat it. */\nconst REPEATED_FIELDS = [\n\t\"channel\",\n\t\"platform\",\n\t\"app_version\",\n\t\"to_bundle_id\",\n\t\"to_release_id\",\n\t\"user_id\"\n];\n/**\n* An UNCHANGED report that repeats its installation's head from the same UTC\n* day: the installation already counts as active that day, on that bundle,\n* so the report records nothing. A download's head does not count, because\n* its installation still ran the bundle it downloaded from.\n*/\nconst repeatsHead = (event, head) => event.type === \"UNCHANGED\" && head.type !== \"UPDATE_DOWNLOADED\" && dayOf(event.received_at_ms) === dayOf(head.received_at_ms) && REPEATED_FIELDS.every((field) => event[field] === head[field]);\n/**\n* Records one event in one transaction: one batch read of the event and its\n* installation's head, one of the gauge and sketch rows it changes, then one\n* write. On a database that batches aggregates (DynamoDB, Firestore), the\n* write holds the event's rows and one log row instead, and a compaction\n* reads and writes the aggregate rows. A stored event's id changes nothing\n* when repeated, whichever installation sends it, and neither does the id\n* of the installation's head. An UNCHANGED report that repeats its head on\n* the same UTC day writes nothing at all. An older event still counts in its\n* own hour but never replaces the head. An update failure is stored and\n* counted, but changes what no installation runs, so it moves no head.\n*/\nconst recordEvent = (db, event) => {\n\tassertBundleEventRow(event);\n\treturn db.transaction(async (tx) => {\n\t\tconst [existing, previous] = await Promise.all([tx.findOne(\"bundle_events\", { id: event.id }), tx.findOne(\"bundle_event_heads\", { install_id: event.install_id })]);\n\t\tif (existing !== null || previous?.id === event.id) return;\n\t\tif (previous !== null && repeatsHead(event, previous)) return;\n\t\tconst { recorded, late } = recordedOf(event, previous);\n\t\tif (recorded.type !== \"UNCHANGED\" || recorded.metadata.change !== void 0 && !late) {\n\t\t\ttx.create(\"bundle_events\", recorded);\n\t\t\tcountOutcome(tx, recorded);\n\t\t}\n\t\tif (recorded.type === \"UPDATE_FAILED\") {\n\t\t\tcountFailure(tx, recorded);\n\t\t\treturn;\n\t\t}\n\t\tcountEvent(tx, recorded);\n\t\tif (previous !== null && (late || !isNewer(recorded, previous))) return;\n\t\tif (previous === null) tx.create(\"bundle_event_heads\", recorded);\n\t\telse {\n\t\t\tconst { install_id: _, ...fields } = recorded;\n\t\t\tcountHead(tx, previous, -1);\n\t\t\ttx.update(\"bundle_event_heads\", previous, fields);\n\t\t}\n\t\tcountHead(tx, recorded, 1);\n\t});\n};\n//#endregion\nexport { PAIR_FIELD, bundlePairKey, insightsIdentity, recordEvent };\n", "import { DAILY_EVENTS, DAY_MS, HOUR_MS, bundleRefOfFilter } from \"./schema.mjs\";\nimport \"./provider.mjs\";\nimport { PAIR_FIELD, bundlePairKey, insightsIdentity } from \"./recordEvent.mjs\";\nimport { DatabaseAdapterInputError, compareUtf8, countDistinct, mergeDistinct } from \"@hot-updater/plugin-core\";\n//#region src/server/reads.ts\nconst PAGE = 500;\nconst hourFloor = (ms) => ms - ms % HOUR_MS;\nconst hourCeil = (ms) => hourFloor(ms + HOUR_MS - 1);\nconst dayFloor = (ms) => ms - ms % DAY_MS;\nconst dayCeil = (ms) => dayFloor(ms + DAY_MS - 1);\n/** Every page of one read, in order. */\nconst drain = async (read) => {\n\tconst rows = [];\n\tlet cursor;\n\tdo {\n\t\tconst page = await read(cursor === void 0 ? {} : { cursor });\n\t\trows.push(...page.rows);\n\t\tcursor = page.next;\n\t} while (cursor !== void 0);\n\treturn rows;\n};\nconst EVENT_FIELDS = [\n\t\"id\",\n\t\"type\",\n\t\"install_id\",\n\t\"user_id\",\n\t\"from_release_id\",\n\t\"from_bundle_id\",\n\t\"to_release_id\",\n\t\"to_bundle_id\",\n\t\"platform\",\n\t\"app_version\",\n\t\"channel\",\n\t\"metadata\",\n\t\"received_at_ms\"\n];\n/** A stored event or head, as the event row it holds. */\nconst toEvent = (row) => Object.fromEntries(EVENT_FIELDS.map((field) => [field, row[field]]));\nconst scopeOf = (filter) => ({\n\tplatform: filter.platform,\n\tchannel: filter.channel,\n\ttype: filter.type,\n\tbundle_ref: bundleRefOfFilter(filter)\n});\n/** One UTC day of a global or bundle list, newest first. */\nconst eventsOfDay = (db, filter, day, range, limit) => filter.kind === \"all\" ? db.findMany(\"bundle_events\", {\n\tindex: \"byDay\",\n\twhere: { day },\n\trange,\n\torder: \"desc\",\n\tlimit\n}) : db.findMany(\"bundle_events\", {\n\tindex: \"byBundle\",\n\twhere: {\n\t\t...scopeOf(filter),\n\t\tday\n\t},\n\trange,\n\torder: \"desc\",\n\tlimit\n});\n/**\n* The newest UTC day before `day`, and not before `since`'s, that holds an\n* event the list matches, from one outcome row: the global list's per-day\n* count, or the bundle filter's own hourly one.\n*/\nconst newestDayBelow = async (db, filter, day, since) => {\n\tconst counted = filter.kind === \"all\" ? {\n\t\twhere: DAILY_EVENTS,\n\t\tfrom: dayFloor(since)\n\t} : {\n\t\twhere: scopeOf(filter),\n\t\tfrom: hourFloor(since)\n\t};\n\tconst [newest] = (await db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: counted.where,\n\t\trange: {\n\t\t\tgte: counted.from,\n\t\t\tlt: day\n\t\t},\n\t\torder: \"desc\",\n\t\tlimit: 1\n\t})).rows;\n\treturn newest === void 0 ? void 0 : dayFloor(newest.bucket_start_ms);\n};\n/**\n* Newest first over [since, before), after the cursor. The global and bundle\n* lists cover at most 90 \u00D7 24 hours, however many UTC days that touches, and\n* reject a longer range instead of cutting it short. They read one query per\n* UTC day that holds a matching event: a day that holds none is read once,\n* then one outcome row names the newest day below it that does, so a gap of\n* any length costs two reads.\n*/\nconst listEvents = async (db, input) => {\n\tconst since = input.sinceMs ?? 0;\n\tconst range = {\n\t\tgte: since,\n\t\tlt: input.after === void 0 ? input.beforeReceivedAtMs : [input.after.receivedAtMs, input.after.id]\n\t};\n\tconst { filter, limit } = input;\n\tif (filter.kind === \"installationMovement\") return (await db.findMany(\"bundle_events\", {\n\t\tindex: \"movementsByInstall\",\n\t\twhere: { movement_install_id: filter.installId },\n\t\trange,\n\t\torder: \"desc\",\n\t\tlimit\n\t})).rows.map(toEvent);\n\tif (input.beforeReceivedAtMs - since > 7776e6) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst rows = [];\n\tconst bottom = dayFloor(since);\n\tlet day = dayFloor(input.after?.receivedAtMs ?? input.beforeReceivedAtMs - 1);\n\twhile (day !== void 0 && day >= bottom && rows.length < limit) {\n\t\tconst page = await eventsOfDay(db, filter, day, range, limit - rows.length);\n\t\trows.push(...page.rows.map(toEvent));\n\t\tday = page.rows.length > 0 ? day - DAY_MS : day > bottom ? await newestDayBelow(db, filter, day, since) : void 0;\n\t}\n\treturn rows;\n};\n/** One point read for an installation; a user's installations in binary install id order. */\nconst findLatestEvents = async (db, input) => {\n\tif (\"installId\" in input) {\n\t\tconst head = await db.findOne(\"bundle_event_heads\", { install_id: input.installId });\n\t\treturn head === null ? [] : [toEvent(head)];\n\t}\n\treturn (await db.findMany(\"bundle_event_heads\", {\n\t\tindex: \"byUser\",\n\t\twhere: { user_id: input.userId },\n\t\t...input.afterInstallId === void 0 ? {} : { range: { gt: input.afterInstallId } },\n\t\torder: \"asc\",\n\t\tlimit: input.limit\n\t})).rows.map(toEvent);\n};\n/** Raw events of one bundle filter over [from, to), which spans at most two partial hours. */\nconst countRaw = async (db, filter, from, to) => {\n\tlet total = 0;\n\tfor (let day = dayFloor(from); from < to && day < to; day += DAY_MS) {\n\t\tconst rows = await drain((page) => db.findMany(\"bundle_events\", {\n\t\t\tindex: \"byBundle\",\n\t\t\twhere: {\n\t\t\t\t...scopeOf(filter),\n\t\t\t\tday\n\t\t\t},\n\t\t\trange: {\n\t\t\t\tgte: from,\n\t\t\t\tlt: to\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}));\n\t\ttotal += rows.length;\n\t}\n\treturn total;\n};\n/**\n* Whole hours from outcome counters; the partial hours at either edge from\n* raw events. A download filter's whole hours count the downloads a launch\n* or crash implied too, which its raw events do not hold.\n*/\nconst countEvents = async (db, input) => {\n\tconst { filter, sinceMs, beforeReceivedAtMs } = input;\n\tconst start = hourCeil(sinceMs);\n\tconst end = hourFloor(beforeReceivedAtMs);\n\tif (start >= end) return countRaw(db, filter, sinceMs, beforeReceivedAtMs);\n\tconst hours = await drain((page) => db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: scopeOf(filter),\n\t\trange: {\n\t\t\tgte: start,\n\t\t\tlt: end\n\t\t},\n\t\tlimit: PAGE,\n\t\t...page\n\t}));\n\treturn await countRaw(db, filter, sinceMs, start) + hours.reduce((sum, row) => sum + row.events, 0) + await countRaw(db, filter, end, beforeReceivedAtMs);\n};\n/**\n* A bundle filter's stored events in each interval of whole hours, and for a\n* download filter the downloads a launch or crash implied: one read of its\n* hourly counts, every interval present.\n*/\nconst countEventSeries = async (db, input) => {\n\tconst { filter, intervalMs } = input;\n\tconst { start, end } = input.timeRange;\n\tconst events = Array.from({ length: (end - start) / intervalMs }, () => 0);\n\tconst hours = await drain((page) => db.findAggregates(\"insights_outcomes\", {\n\t\tindex: \"byRef\",\n\t\twhere: scopeOf(filter),\n\t\trange: {\n\t\t\tgte: start,\n\t\t\tlt: end\n\t\t},\n\t\tlimit: PAGE,\n\t\t...page\n\t}));\n\tfor (const row of hours) events[Math.floor((row.bucket_start_ms - start) / intervalMs)] += row.events;\n\treturn events.map((count, index) => ({\n\t\tstartMs: start + index * intervalMs,\n\t\tevents: count\n\t}));\n};\n/** A bundle filter's distinct (field, value, type) predicates. */\nconst latestPredicates = (bundle) => {\n\tif (bundle === void 0) return void 0;\n\treturn [...new Map(bundle.flatMap(({ field, value, types }) => types.map((type) => [JSON.stringify([\n\t\tfield,\n\t\tvalue,\n\t\ttype\n\t]), {\n\t\tfield,\n\t\tvalue,\n\t\ttype\n\t}]))).values()];\n};\n/**\n* Latest events at or after `sinceMs`, a UTC day's start: the gauges count\n* each installation in the UTC day of its latest event, so they answer whole\n* days only, and a later start is rejected rather than rounded.\n*/\nconst countLatestEvents = async (db, input) => {\n\tconst { platform, channel, sinceMs: start } = input;\n\tif (start % 864e5 !== 0) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst predicates = latestPredicates(input.bundle);\n\tlet total = 0;\n\tif (predicates === void 0) {\n\t\tconst rows = await drain((page) => db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange: { gte: start },\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}));\n\t\ttotal += rows.reduce((sum, row) => sum + row.latest_installations, 0);\n\t} else {\n\t\tconst gauge = async (bundleField, bundleId, type) => {\n\t\t\treturn (await drain((page) => db.findAggregates(\"insights_latest_by_bundle\", {\n\t\t\t\tindex: \"byBundle\",\n\t\t\t\twhere: {\n\t\t\t\t\tplatform,\n\t\t\t\t\tchannel,\n\t\t\t\t\tbundle_field: bundleField,\n\t\t\t\t\tbundle_id: bundleId,\n\t\t\t\t\ttype\n\t\t\t\t},\n\t\t\t\trange: { gte: start },\n\t\t\t\tlimit: PAGE,\n\t\t\t\t...page\n\t\t\t}))).reduce((sum, row) => sum + row.installations, 0);\n\t\t};\n\t\tfor (const { field, value, type } of predicates) total += await gauge(field, value, type);\n\t\tfor (const from of predicates) {\n\t\t\tif (from.field !== \"from_bundle_id\") continue;\n\t\t\tfor (const to of predicates) {\n\t\t\t\tif (to.field !== \"to_bundle_id\" || to.type !== from.type) continue;\n\t\t\t\ttotal -= await gauge(PAIR_FIELD, bundlePairKey(from.value, to.value), from.type);\n\t\t\t}\n\t\t}\n\t}\n\treturn Math.max(0, total);\n};\n/** The oldest whole hour and UTC day that hourly and daily rows still hold. */\nconst retained = (now, { rawDays, dailyDays }) => ({\n\thour: hourCeil(now - rawDays * DAY_MS),\n\tday: dayCeil(now - dailyDays * DAY_MS)\n});\n/**\n* Whether the rows a window reads still hold all of it; an older start is\n* partial from `oldest`, the first bucket its rows keep.\n*/\nconst coverageOf = (start, oldest) => start >= oldest ? {\n\tkind: \"complete\",\n\tsinceMs: 0\n} : {\n\tkind: \"partial\",\n\tsinceMs: oldest\n};\n/**\n* Periods covering [start, end): whole UTC days when `days` and the window is\n* over 48 hours, hours elsewhere. Hourly rows start at `hour`, the raw\n* period ago, so with `days` an edge older than that reads its whole UTC day\n* from the daily rows.\n*/\nconst periodsOf = (range, days, hour) => {\n\tconst start = days && range.start < hour ? dayFloor(range.start) : range.start;\n\tconst end = days && range.end < hour ? dayCeil(range.end) : range.end;\n\tif (!days || end - start <= 1728e5 && start >= hour) return [{\n\t\tperiodKind: \"hour\",\n\t\tstart,\n\t\tend\n\t}];\n\tconst first = Math.min(end, dayCeil(start));\n\tconst last = Math.max(first, dayFloor(end));\n\treturn [\n\t\t{\n\t\t\tperiodKind: \"hour\",\n\t\t\tstart,\n\t\t\tend: first\n\t\t},\n\t\t{\n\t\t\tperiodKind: \"day\",\n\t\t\tstart: first,\n\t\t\tend: last\n\t\t},\n\t\t{\n\t\t\tperiodKind: \"hour\",\n\t\t\tstart: last,\n\t\t\tend\n\t\t}\n\t].filter((period) => period.start < period.end);\n};\n/** The hourly and daily aggregates of counters, and of sketches. */\nconst COUNTERS = {\n\thour: \"insights_overview\",\n\tday: \"insights_overview_daily\"\n};\nconst SKETCHES = {\n\thour: \"insights_sketches\",\n\tday: \"insights_sketches_daily\"\n};\n/** Every counter or sketch row of one identity over [start, end), mixing day and hour periods. */\nconst windowRows = async (db, models, parts, range, days, hour) => {\n\tconst rows = [];\n\tfor (const period of periodsOf(range, days, hour)) {\n\t\tconst identity = insightsIdentity({\n\t\t\t...parts,\n\t\t\tperiodKind: period.periodKind\n\t\t});\n\t\trows.push(...await drain((page) => db.findAggregates(models[period.periodKind], {\n\t\t\tindex: \"window\",\n\t\t\twhere: { identity },\n\t\t\trange: {\n\t\t\t\tgte: period.start,\n\t\t\t\tlt: period.end\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t}\n\treturn rows;\n};\nconst counterRows = (...[db, ...args]) => windowRows(db, COUNTERS, ...args);\nconst sketchRows = (...[db, ...args]) => windowRows(db, SKETCHES, ...args);\nconst releaseParts = (release) => ({\n\tscopeKind: \"release\",\n\treleaseKind: \"specific\",\n\treleaseId: release.releaseId,\n\tchannel: release.channel,\n\tplatform: release.platform,\n\tappVersionKind: \"all\",\n\tappVersion: \"\"\n});\n/** A release's lifetime counters: one logical row at bucket 0. */\nconst lifetimeMetrics = async (db, release) => {\n\tconst identity = insightsIdentity({\n\t\t...releaseParts(release),\n\t\tperiodKind: \"lifetime\"\n\t});\n\tconst [lifetime] = (await db.findAggregates(\"insights_overview_lifetime\", {\n\t\tindex: \"window\",\n\t\twhere: { identity },\n\t\trange: {\n\t\t\tgte: 0,\n\t\t\tlte: 0\n\t\t},\n\t\tlimit: PAGE\n\t})).rows;\n\treturn {\n\t\tdownloads: lifetime?.downloads ?? 0,\n\t\tapplies: lifetime?.applies ?? 0,\n\t\tfailedLaunches: lifetime?.failed_launches ?? 0\n\t};\n};\n/** A channel and platform's usage rows, of every app version or of one. */\nconst usageParts = (channel, platform, appVersion) => ({\n\tscopeKind: \"usage\",\n\treleaseKind: \"all\",\n\treleaseId: \"\",\n\tchannel,\n\tplatform,\n\tappVersionKind: appVersion === void 0 ? \"all\" : \"specific\",\n\tappVersion: appVersion ?? \"\"\n});\n/** Each release's lifetime counters, which are kept: one logical row apiece. */\nconst getReleaseActivity = async (db, input, now) => {\n\tconst measuredAtMs = now();\n\treturn {\n\t\tdata: await Promise.all(input.releases.map(async (release) => ({\n\t\t\trelease,\n\t\t\tmetrics: await lifetimeMetrics(db, release)\n\t\t}))),\n\t\tmeasuredAtMs\n\t};\n};\n/**\n* Entries with installations, most first. Batched gauges sum signed shard\n* rows, so a version or platform everyone left can read 0, and is left out.\n*/\nconst byInstallations = (values) => [...values].flatMap(([name, installations]) => installations > 0 ? [{\n\tname,\n\tinstallations\n}] : []).sort((left, right) => right.installations - left.installations || left.name.localeCompare(right.name, \"en\", { numeric: true }));\nconst getAppUsage = async (db, input, now, retention) => {\n\tconst { timeRange, intervalMs } = input;\n\tconst at = now();\n\tconst kept = retained(at, retention);\n\tconst days = intervalMs % 864e5 === 0 && timeRange.start % 864e5 === 0;\n\tconst reported = input.platform === \"all\" ? [\"ios\", \"android\"] : [input.platform];\n\tconst usage = (await Promise.all(reported.map((platform) => sketchRows(db, usageParts(input.channel, platform, input.appVersion), timeRange, days, kept.hour)))).flat();\n\tconst range = {\n\t\tgte: dayFloor(timeRange.start),\n\t\tlt: timeRange.end\n\t};\n\tconst distribution = [];\n\tconst builtinDistribution = [];\n\tfor (const platform of reported) {\n\t\tdistribution.push(...await drain((page) => input.appVersion === void 0 ? db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}) : db.findAggregates(\"insights_distribution\", {\n\t\t\tindex: \"byVersion\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform,\n\t\t\t\tapp_version: input.appVersion\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t\tbuiltinDistribution.push(...await drain((page) => input.appVersion === void 0 ? db.findAggregates(\"insights_builtin_distribution\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}) : db.findAggregates(\"insights_builtin_distribution\", {\n\t\t\tindex: \"byVersion\",\n\t\t\twhere: {\n\t\t\t\tchannel: input.channel,\n\t\t\t\tplatform,\n\t\t\t\tapp_version: input.appVersion\n\t\t\t},\n\t\t\trange,\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t})));\n\t}\n\tconst points = [];\n\tfor (let start = timeRange.start; start < timeRange.end; start += intervalMs) points.push({\n\t\tstartMs: start,\n\t\tinstallations: countDistinct(mergeDistinct(usage.filter((row) => row.bucket_start_ms >= start && row.bucket_start_ms < start + intervalMs).map((row) => row.activity_users)))\n\t});\n\tconst versions = /* @__PURE__ */ new Map();\n\tconst platforms = /* @__PURE__ */ new Map();\n\tconst bundles = /* @__PURE__ */ new Map();\n\tconst countBundle = (row, releaseId, builtinBundleId, count) => {\n\t\tconst key = JSON.stringify([\n\t\t\trow.app_version,\n\t\t\trow.platform,\n\t\t\treleaseId,\n\t\t\tbuiltinBundleId\n\t\t]);\n\t\tbundles.set(key, {\n\t\t\tappVersion: row.app_version,\n\t\t\tplatform: row.platform,\n\t\t\treleaseId,\n\t\t\tbuiltinBundleId,\n\t\t\tinstallations: (bundles.get(key)?.installations ?? 0) + count\n\t\t});\n\t};\n\tfor (const row of distribution) {\n\t\tconst count = row.latest_installations;\n\t\tversions.set(row.app_version, (versions.get(row.app_version) ?? 0) + count);\n\t\tplatforms.set(row.platform, (platforms.get(row.platform) ?? 0) + count);\n\t\tcountBundle(row, row.release_id || null, null, count);\n\t}\n\tfor (const row of builtinDistribution) {\n\t\tconst releaseId = row.release_id || null;\n\t\tcountBundle(row, releaseId, null, -row.latest_installations);\n\t\tcountBundle(row, releaseId, row.builtin_bundle_id, row.latest_installations);\n\t}\n\tconst sortedVersions = byInstallations(versions);\n\treturn {\n\t\tcoverage: coverageOf(timeRange.start, kept[days ? \"day\" : \"hour\"]),\n\t\tactiveInstallations: countDistinct(mergeDistinct(usage.map((row) => row.activity_users))),\n\t\tpoints,\n\t\tappVersions: sortedVersions.map(({ name }) => name),\n\t\tversions: sortedVersions,\n\t\tplatforms: byInstallations(platforms),\n\t\tbundleDistribution: [...bundles.values()].filter(({ installations }) => installations > 0),\n\t\tmeasuredAtMs: at\n\t};\n};\n/** The longest period the failures read covers: the console's longest, 30 days. */\nconst UPDATE_FAILURES_RANGE_MS = 30 * DAY_MS;\nconst isRange = (range) => range === void 0 || Number.isSafeInteger(range.start) && Number.isSafeInteger(range.end) && range.start >= 0 && range.start < range.end && range.end - range.start <= UPDATE_FAILURES_RANGE_MS;\nconst isText = (value, maxLength) => typeof value === \"string\" && value.length > 0 && value.length <= maxLength;\nconst failed = (...rows) => countDistinct(mergeDistinct(rows.flat().map((row) => row.failed_users)));\n/** Entries of a count map, most first, then in key order. */\nconst mostFirst = (counts) => [...counts].sort(([leftKey, left], [rightKey, right]) => right.events - left.events || compareUtf8(leftKey, rightKey)).map(([, entry]) => entry);\n/** The stages a failure row records: where an update failed. */\nconst FAILURE_STAGES = /* @__PURE__ */ new Set([\n\t\"check\",\n\t\"download\",\n\t\"install\",\n\t\"unknown\"\n]);\n/** Failure rows as their breakdown by stage, reason, and detail. */\nconst breakdownOf = (rows) => {\n\tconst failures = /* @__PURE__ */ new Map();\n\tfor (const { stage, reason, detail, events } of rows) {\n\t\tif (events <= 0) continue;\n\t\tconst key = JSON.stringify([stage, reason]);\n\t\tconst entry = failures.get(key) ?? {\n\t\t\tvalue: {\n\t\t\t\tstage,\n\t\t\t\treason\n\t\t\t},\n\t\t\tevents: 0,\n\t\t\tdetails: /* @__PURE__ */ new Map()\n\t\t};\n\t\tentry.events += events;\n\t\tconst known = entry.details.get(detail) ?? {\n\t\t\tvalue: detail,\n\t\t\tevents: 0\n\t\t};\n\t\tknown.events += events;\n\t\tentry.details.set(detail, known);\n\t\tfailures.set(key, entry);\n\t}\n\treturn mostFirst(failures).map(({ value, events }) => {\n\t\tconst { details } = failures.get(JSON.stringify([value.stage, value.reason]));\n\t\treturn {\n\t\t\t...value,\n\t\t\tevents,\n\t\t\tdetails: mostFirst(details).map(({ value: detail, events }) => {\n\t\t\t\tconst [resource, httpStatus, originCode, transport] = JSON.parse(detail);\n\t\t\t\treturn {\n\t\t\t\t\tresource,\n\t\t\t\t\thttpStatus,\n\t\t\t\t\toriginCode,\n\t\t\t\t\ttransport,\n\t\t\t\t\tevents\n\t\t\t\t};\n\t\t\t})\n\t\t};\n\t});\n};\n/**\n* A release's or a channel's update failures. Since a release's first\n* report: its lifetime counters and failed installations. Over a time range\n* of at most 30 days: failures, failed checks, and the breakdown by stage,\n* reason, and detail, all summed from the breakdown's hourly rows; downloads\n* from the counters; failed installations from their sketches. A release reads hourly rows, a\n* channel daily rows past 48 hours like its activity; the breakdown's rows\n* are hourly, so its coverage is the raw period's.\n*/\nconst getUpdateFailures = async (db, input, now, retention) => {\n\tconst { platform, channel, releaseId, timeRange } = input;\n\tif (platform !== \"ios\" && platform !== \"android\" || !isText(channel, 1024) || releaseId !== void 0 && !isText(releaseId, 36) || !isRange(timeRange) || releaseId === void 0 && timeRange === void 0) throw new DatabaseAdapterInputError(\"invalid-query\");\n\tconst at = now();\n\tconst kept = retained(at, retention);\n\tconst channelParts = {\n\t\t...usageParts(channel, platform),\n\t\tscopeKind: \"channel\"\n\t};\n\tconst parts = releaseId === void 0 ? channelParts : releaseParts({\n\t\treleaseId,\n\t\tplatform,\n\t\tchannel\n\t});\n\tconst failure = {\n\t\t...parts,\n\t\tscopeKind: \"failure\"\n\t};\n\tif (timeRange === void 0) {\n\t\tconst where = (from) => ({ identity: insightsIdentity({\n\t\t\t...from,\n\t\t\tperiodKind: \"lifetime\"\n\t\t}) });\n\t\tconst [counters, sketches] = await Promise.all([db.findAggregates(\"insights_overview_lifetime\", {\n\t\t\tindex: \"window\",\n\t\t\twhere: where(parts),\n\t\t\trange: {\n\t\t\t\tgte: 0,\n\t\t\t\tlte: 0\n\t\t\t},\n\t\t\tlimit: PAGE\n\t\t}), db.findAggregates(\"insights_sketches_lifetime\", {\n\t\t\tindex: \"window\",\n\t\t\twhere: where(failure),\n\t\t\trange: {\n\t\t\t\tgte: 0,\n\t\t\t\tlte: 0\n\t\t\t},\n\t\t\tlimit: PAGE\n\t\t})]);\n\t\tconst lifetime = counters.rows[0];\n\t\treturn {\n\t\t\tcoverage: {\n\t\t\t\tkind: \"complete\",\n\t\t\t\tsinceMs: 0\n\t\t\t},\n\t\t\tmeasuredAtMs: at,\n\t\t\tfailedUpdates: lifetime?.failed_updates ?? 0,\n\t\t\tfailedInstallations: countDistinct(mergeDistinct(sketches.rows.map((row) => row.failed_users))),\n\t\t\tdownloads: lifetime?.downloads ?? 0,\n\t\t\tpatchDownloads: lifetime?.patch_downloads ?? 0,\n\t\t\tpatchFallbacks: lifetime?.patch_fallbacks ?? 0\n\t\t};\n\t}\n\tconst days = releaseId === void 0;\n\tconst window = [\n\t\ttimeRange,\n\t\tdays,\n\t\tkept.hour\n\t];\n\tconst [counters, failures, checks, active, rows] = await Promise.all([\n\t\tcounterRows(db, parts, ...window),\n\t\tsketchRows(db, failure, ...window),\n\t\tdays ? sketchRows(db, {\n\t\t\t...channelParts,\n\t\t\tscopeKind: \"check\"\n\t\t}, ...window) : [],\n\t\tdays ? sketchRows(db, usageParts(channel, platform), ...window) : [],\n\t\tdrain((page) => db.findAggregates(\"insights_failures\", {\n\t\t\tindex: \"byScope\",\n\t\t\twhere: {\n\t\t\t\tplatform,\n\t\t\t\tchannel\n\t\t\t},\n\t\t\trange: {\n\t\t\t\tgte: timeRange.start,\n\t\t\t\tlt: timeRange.end\n\t\t\t},\n\t\t\tlimit: PAGE,\n\t\t\t...page\n\t\t}))\n\t]);\n\tconst total = (field) => counters.reduce((sum, row) => sum + row[field], 0);\n\tconst scoped = rows.filter((row) => FAILURE_STAGES.has(row.stage) && (releaseId === void 0 || row.release_id === releaseId));\n\tconst failuresAt = (counted) => scoped.reduce((sum, row) => sum + (counted(row.stage) ? Math.max(0, row.events) : 0), 0);\n\treturn {\n\t\tcoverage: coverageOf(timeRange.start, kept.hour),\n\t\tmeasuredAtMs: at,\n\t\tfailedUpdates: failuresAt((stage) => stage !== \"check\"),\n\t\tfailedInstallations: failed(failures),\n\t\tdownloads: total(\"downloads\"),\n\t\tpatchDownloads: total(\"patch_downloads\"),\n\t\tpatchFallbacks: total(\"patch_fallbacks\"),\n\t\t...days ? { checks: {\n\t\t\tfailures: failuresAt((stage) => stage === \"check\"),\n\t\t\tfailedInstallations: failed(checks),\n\t\t\tactiveInstallations: countDistinct(mergeDistinct(active.map((row) => row.activity_users)))\n\t\t} } : {},\n\t\tbreakdown: breakdownOf(scoped)\n\t};\n};\n//#endregion\nexport { UPDATE_FAILURES_RANGE_MS, countEventSeries, countEvents, countLatestEvents, findLatestEvents, getAppUsage, getReleaseActivity, getUpdateFailures, listEvents };\n", "import { InsightsBadRequestError } from \"./errors.mjs\";\n//#region src/server/queryInput.ts\nconst MAX_PAGE_LIMIT = 100;\nconst MAX_IDENTITY_LENGTH = 255;\nconst MAX_CURSOR_LENGTH = 8192;\nconst readSingle = (url, key) => {\n\tconst values = url.searchParams.getAll(key);\n\tif (values.length > 1) throw new InsightsBadRequestError(`Duplicate '${key}' query parameter.`);\n\treturn values[0];\n};\nconst readPageLimit = (url) => {\n\tconst value = readSingle(url, \"limit\");\n\tif (value === void 0) return void 0;\n\tconst limit = Number(value);\n\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_PAGE_LIMIT) throw new InsightsBadRequestError(\"Invalid 'limit' query parameter.\");\n\treturn limit;\n};\nconst readCursor = (url) => {\n\tconst cursor = readSingle(url, \"cursor\");\n\tif (cursor !== void 0 && (cursor.length === 0 || cursor.length > MAX_CURSOR_LENGTH)) throw new InsightsBadRequestError(\"Invalid 'cursor' query parameter.\");\n\treturn cursor;\n};\nconst readId = (url, key, maximumLength = MAX_IDENTITY_LENGTH) => {\n\tconst value = readSingle(url, key);\n\tif (value === void 0 || value.length === 0 || value.length > maximumLength) throw new InsightsBadRequestError(`Invalid '${key}' query parameter.`);\n\treturn value;\n};\nconst readTimestamp = (url, key) => {\n\tconst raw = readSingle(url, key);\n\tif (raw === void 0) return void 0;\n\tconst value = Number(raw);\n\tif (!raw.length || !Number.isSafeInteger(value) || value < 0) throw new InsightsBadRequestError(`Invalid '${key}' query parameter.`);\n\treturn value;\n};\nconst readScope = (url) => {\n\tconst platform = readSingle(url, \"platform\");\n\tif (platform !== \"ios\" && platform !== \"android\") throw new InsightsBadRequestError(\"Invalid 'platform' query parameter.\");\n\treturn {\n\t\tplatform,\n\t\tchannel: readId(url, \"channel\", 1024)\n\t};\n};\nconst parseEventPageInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst bundleFields = [\n\t\t\"bundleId\",\n\t\t\"outcome\",\n\t\t\"platform\",\n\t\t\"channel\"\n\t];\n\tlet bundle;\n\tif (bundleFields.some((key) => url.searchParams.has(key))) {\n\t\tconst outcome = readSingle(url, \"outcome\");\n\t\tif (outcome !== \"downloaded\" && outcome !== \"applied\" && outcome !== \"recovered\" && outcome !== \"failed\") throw new InsightsBadRequestError(\"Invalid 'outcome' query parameter.\");\n\t\tbundle = {\n\t\t\t...readScope(url),\n\t\t\tbundleId: readId(url, \"bundleId\", 1024),\n\t\t\toutcome\n\t\t};\n\t}\n\treturn {\n\t\tbeforeReceivedAtMs: readTimestamp(url, \"beforeReceivedAtMs\"),\n\t\tsinceMs: readTimestamp(url, \"sinceMs\"),\n\t\tcursor: readCursor(url),\n\t\tlimit: readPageLimit(url),\n\t\t...bundle === void 0 ? {} : { bundle }\n\t};\n};\nconst parseUserInstallationPageInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst cursor = readCursor(url);\n\tconst limit = readPageLimit(url);\n\treturn {\n\t\tuserId: readId(url, \"userId\"),\n\t\t...cursor === void 0 ? {} : { cursor },\n\t\t...limit === void 0 ? {} : { limit }\n\t};\n};\nconst parseReportingOverviewInput = (request) => {\n\tconst url = new URL(request.url);\n\tconst window = readSingle(url, \"window\") ?? \"30d\";\n\tif (window !== \"24h\" && window !== \"7d\" && window !== \"30d\") throw new InsightsBadRequestError(\"Invalid 'window' query parameter.\");\n\tconst bundleId = readSingle(url, \"bundleId\");\n\treturn {\n\t\t...readScope(url),\n\t\twindow,\n\t\t...bundleId === void 0 ? {} : { bundleId: readId(url, \"bundleId\", 1024) }\n\t};\n};\n//#endregion\nexport { parseEventPageInput, parseReportingOverviewInput, parseUserInstallationPageInput };\n", "import { InsightsBadRequestError, InsightsPayloadTooLargeError } from \"./errors.mjs\";\nimport { parseBundleEventRequest } from \"./eventInput.mjs\";\nimport { parseEventPageInput, parseReportingOverviewInput, parseUserInstallationPageInput } from \"./queryInput.mjs\";\nimport { isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/routes.ts\n/** Seconds a client waits before it resends a request the busy database refused. */\nconst RETRY_AFTER_SECONDS = 5;\nconst json = (body, status, headers = {}) => Response.json(body, {\n\theaders: {\n\t\t\"cache-control\": \"private, no-store\",\n\t\t...headers\n\t},\n\tstatus\n});\nconst requireParam = (params, key) => {\n\tconst value = params[key];\n\tif (value === void 0 || value.length === 0) throw new InsightsBadRequestError(`Missing route parameter: ${key}`);\n\ttry {\n\t\treturn decodeURIComponent(value);\n\t} catch {\n\t\tthrow new InsightsBadRequestError(`Invalid route parameter: ${key}`);\n\t}\n};\nconst run = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof InsightsBadRequestError) return json({ error: error.message }, 400);\n\t\tif (error instanceof InsightsPayloadTooLargeError) return json({ error: error.message }, 413);\n\t\tif (isDatabaseBusyError(error)) {\n\t\t\tconsole.warn(\"[hot-updater] Insights answered 503: the database is busy.\", error);\n\t\t\treturn json({ error: \"Service unavailable\" }, 503, { \"retry-after\": String(RETRY_AFTER_SECONDS) });\n\t\t}\n\t\tthrow error;\n\t}\n};\nconst query = (operation) => run(async () => json(await operation(), 200));\n/** Every Insights route: where it mounts, and the handler it runs. */\nconst INSIGHTS_ROUTES = [\n\t{\n\t\taccess: \"client\",\n\t\tmethod: \"POST\",\n\t\tpath: \"/events\",\n\t\thandler: \"appendBundleEvent\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/events\",\n\t\thandler: \"listEvents\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/overview\",\n\t\thandler: \"getReportingOverview\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations\",\n\t\thandler: \"pageInstallationsByCurrentUserId\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations/:installId/events\",\n\t\thandler: \"listInstallationEvents\"\n\t},\n\t{\n\t\taccess: \"admin\",\n\t\tmethod: \"GET\",\n\t\tpath: \"/installations/:installId\",\n\t\thandler: \"getInstallation\"\n\t}\n];\nconst createInsightsRouteHandlers = (provider) => ({\n\tappendBundleEvent: async (_params, request) => run(async () => {\n\t\tawait provider.appendBundleEvent(await parseBundleEventRequest(request));\n\t\treturn new Response(null, { status: 204 });\n\t}),\n\tgetReportingOverview: (_params, request) => query(() => provider.getReportingOverview(parseReportingOverviewInput(request))),\n\tgetInstallation: (params) => run(async () => {\n\t\tconst installation = await provider.getInstallation({ installId: requireParam(params, \"installId\") });\n\t\treturn installation === null ? json({ error: \"Installation not found\" }, 404) : json(installation, 200);\n\t}),\n\tlistEvents: (_params, request) => query(() => provider.listEvents(parseEventPageInput(request))),\n\tlistInstallationEvents: (params, request) => query(() => provider.listInstallationEvents({\n\t\t...parseEventPageInput(request),\n\t\tinstallId: requireParam(params, \"installId\")\n\t})),\n\tpageInstallationsByCurrentUserId: (_params, request) => query(() => provider.pageInstallationsByCurrentUserId(parseUserInstallationPageInput(request)))\n});\n//#endregion\nexport { INSIGHTS_ROUTES, createInsightsRouteHandlers };\n", "import { DEFAULT_INSIGHTS_RETENTION, createInsightsSchema, insightsSchema } from \"./schema.mjs\";\nimport { createInsightsModel } from \"./model.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { InsightsBadRequestError } from \"./errors.mjs\";\nimport { createInsightsProvider } from \"./provider.mjs\";\nimport { insightsIdentity, recordEvent } from \"./recordEvent.mjs\";\nimport { countEventSeries, countEvents, countLatestEvents, findLatestEvents, getAppUsage, getReleaseActivity, getUpdateFailures, listEvents } from \"./reads.mjs\";\nimport { INSIGHTS_ROUTES, createInsightsRouteHandlers } from \"./routes.mjs\";\nimport { createInsightsAdminReads, createInsightsReads } from \"./adminReads.mjs\";\nimport { DatabaseAdapterInputError, HotUpdaterConfigError, definePlugin, isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\nconst createInsightsApi = (db, now, retention) => ({\n\t/** How long this plugin keeps its rows. */\n\tretention,\n\t/** Records one validated event row; a repeated id changes nothing. */\n\trecordEvent: (event) => recordEvent(db, event),\n\tlistEvents: (input) => listEvents(db, input),\n\tfindLatestEvents: (input) => findLatestEvents(db, input),\n\tcountLatestEvents: (input) => countLatestEvents(db, input),\n\tcountEvents: (input) => countEvents(db, input),\n\tcountEventSeries: (input) => countEventSeries(db, input),\n\tgetReleaseActivity: (input) => getReleaseActivity(db, input, now),\n\tgetAppUsage: (input) => getAppUsage(db, input, now, retention),\n\t/** A release's or a channel's update failures, and their breakdown over a time range. */\n\tgetUpdateFailures: (input) => getUpdateFailures(db, input, now, retention)\n});\n/** `GET /failures`'s query: a scope, an optional release, and a time range or none. */\nconst readFailuresQuery = (url) => {\n\tconst query = url.searchParams;\n\tconst time = (name) => {\n\t\tconst value = query.get(name);\n\t\treturn value === null ? void 0 : Number(value);\n\t};\n\tconst [start, end] = [time(\"start\"), time(\"end\")];\n\tconst platform = query.get(\"platform\");\n\tconst releaseId = query.get(\"releaseId\");\n\tif (platform !== \"ios\" && platform !== \"android\" || start === void 0 !== (end === void 0)) throw new DatabaseAdapterInputError(\"invalid-query\");\n\treturn {\n\t\tplatform,\n\t\tchannel: query.get(\"channel\") ?? \"\",\n\t\t...releaseId === null ? {} : { releaseId },\n\t\t...start === void 0 ? {} : { timeRange: {\n\t\t\tstart,\n\t\t\tend\n\t\t} }\n\t};\n};\n/**\n* The admin route of the update failures read: a release's (`releaseId`)\n* since its first report, or over `start`\u2013`end`, or a channel's over a range,\n* which covers at most 30 days.\n*/\nconst failuresEndpoint = (api) => ({\n\taccess: \"admin\",\n\tmethod: \"GET\",\n\tpath: \"/failures\",\n\thandler: async (request) => {\n\t\ttry {\n\t\t\treturn Response.json(await api.getUpdateFailures(readFailuresQuery(new URL(request.url))), { headers: { \"cache-control\": \"private, no-store\" } });\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseAdapterInputError) return Response.json({ error: \"Send platform and channel, and releaseId or start and end in epoch milliseconds, at most 30 days apart.\" }, { status: 400 });\n\t\t\tif (!isDatabaseBusyError(error)) throw error;\n\t\t\treturn Response.json({ error: \"Service unavailable\" }, {\n\t\t\t\tstatus: 503,\n\t\t\t\theaders: { \"retry-after\": \"5\" }\n\t\t\t});\n\t\t}\n\t}\n});\nconst retentionOf = ({ retention }) => {\n\tconst rawDays = retention?.rawDays ?? 90;\n\tconst dailyDays = retention?.dailyDays ?? 400;\n\tconst whole = (days) => Number.isSafeInteger(days) && days >= 1;\n\tif (!whole(rawDays) || !whole(dailyDays) || dailyDays < rawDays) throw new HotUpdaterConfigError(`insights({ retention }) takes whole days of at least 1, with dailyDays at least rawDays; got rawDays ${rawDays} and dailyDays ${dailyDays}.`);\n\treturn {\n\t\trawDays,\n\t\tdailyDays\n\t};\n};\n/**\n* Insights: bundle lifecycle events and update failures, each\n* installation's latest event, and the counters, gauges, and sketches its\n* reads come from, each kept for its retention. It serves `POST /events` to\n* clients, and the Insights reads, update failures, and retention to admins.\n*/\nconst insights = (options = {}) => {\n\tconst retention = retentionOf(options);\n\tconst plugin = definePlugin({\n\t\tid: \"insights\",\n\t\tnamespace: false,\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: createInsightsSchema(retention),\n\t\tinit: ({ db, now }) => {\n\t\t\tconst api = createInsightsApi(db, now, retention);\n\t\t\tconst routes = createInsightsRouteHandlers(createInsightsProvider(createInsightsModel(api)));\n\t\t\treturn {\n\t\t\t\tapi,\n\t\t\t\tendpoints: [\n\t\t\t\t\t...INSIGHTS_ROUTES.map(({ access, method, path, handler }) => ({\n\t\t\t\t\t\taccess,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\thandler: (request, params) => routes[handler](params, request)\n\t\t\t\t\t})),\n\t\t\t\t\tfailuresEndpoint(api),\n\t\t\t\t\t{\n\t\t\t\t\t\taccess: \"admin\",\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\tpath: \"/retention\",\n\t\t\t\t\t\thandler: async () => Response.json(retention)\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t};\n\t\t},\n\t\tcli: { clientPlugin: {\n\t\t\tmodule: \"@hot-updater/react-native\",\n\t\t\tname: \"insights\"\n\t\t} }\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { DEFAULT_INSIGHTS_RETENTION, InsightsBadRequestError, createInsightsAdminReads, createInsightsModel, createInsightsProvider, createInsightsReads, createInsightsSchema, insights, insightsIdentity, insightsSchema };\n", "//#region src/shared/ownEntry.ts\n/**\n* A record's own entry. Parameter keys and condition names come from users,\n* so `constructor` or `__proto__` must name theirs, never Object.prototype's.\n*/\nconst ownEntry = (record, key) => record !== void 0 && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : void 0;\n//#endregion\nexport { ownEntry };\n", "import { ownEntry } from \"../shared/ownEntry.mjs\";\nimport { semverSatisfies } from \"@hot-updater/plugin-core\";\nimport { getNumericCohortRolloutPosition, getNumericCohortValue, isValidCohort, normalizeCohortValue } from \"@hot-updater/protocol\";\nimport { isValidRange } from \"verkit\";\n//#region src/server/template.ts\nconst EMPTY_REMOTE_CONFIG_TEMPLATE = Object.freeze({\n\tconditions: Object.freeze([]),\n\tparameters: Object.freeze({})\n});\n/**\n* A template's JSON stays under this many characters, so a device's values\n* always fit the 64 KB a client plugin may store under one key.\n*/\nconst REMOTE_CONFIG_MAX_TEMPLATE_LENGTH = 6e4;\nconst REMOTE_CONFIG_MAX_PARAMETERS = 2e3;\nconst REMOTE_CONFIG_MAX_CONDITIONS = 500;\nconst MAX_RULE_VALUES = 100;\nconst MAX_DESCRIPTION_LENGTH = 256;\nconst MAX_CONDITION_NAME_LENGTH = 100;\nconst MAX_RULE_TEXT_LENGTH = 128;\nconst PARAMETER_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,255}$/u;\nconst SEED_PATTERN = /^[A-Za-z0-9_-]{1,64}$/u;\n/** A date-time with its time zone, so it names one instant. */\nconst DATE_TIME_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,3})?)?(?:Z|[+-]\\d{2}:\\d{2})$/u;\nconst VALUE_TYPES = /* @__PURE__ */ new Set([\n\t\"STRING\",\n\t\"NUMBER\",\n\t\"BOOLEAN\",\n\t\"JSON\"\n]);\nconst PLATFORMS = /* @__PURE__ */ new Set([\"ios\", \"android\"]);\n/** A template that cannot be published; `issues` lists every problem found. */\nvar RemoteConfigValidationError = class extends Error {\n\tissues;\n\tname = \"RemoteConfigValidationError\";\n\tconstructor(issues) {\n\t\tsuper(`The Remote Config template is invalid: ${issues.slice(0, 3).map(({ path, message }) => path ? `${path}: ${message}` : message).join(\"; \")}${issues.length > 3 ? ` (and ${issues.length - 3} more)` : \"\"}`);\n\t\tthis.issues = issues;\n\t}\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst visibleText = (value, max) => typeof value === \"string\" && value.trim().length > 0 && value.length <= max && !/[\\p{Cc}]/u.test(value);\n/** Whether a value's text suits its type; the problem otherwise. */\nconst checkValueText = (valueType, text) => {\n\tswitch (valueType) {\n\t\tcase \"NUMBER\": return text.trim().length > 0 && Number.isFinite(Number(text)) ? null : \"must be a number.\";\n\t\tcase \"BOOLEAN\": return text === \"true\" || text === \"false\" ? null : \"must be \\\"true\\\" or \\\"false\\\".\";\n\t\tcase \"JSON\": try {\n\t\t\tJSON.parse(text);\n\t\t\treturn null;\n\t\t} catch {\n\t\t\treturn \"must be valid JSON.\";\n\t\t}\n\t\tdefault: return null;\n\t}\n};\n/**\n* Checks a template and returns it with only its declared fields, or throws\n* `RemoteConfigValidationError` with every problem it finds.\n*/\nconst validateRemoteConfigTemplate = (input) => {\n\tconst issues = [];\n\tconst issue = (path, message) => {\n\t\tissues.push({\n\t\t\tpath,\n\t\t\tmessage\n\t\t});\n\t};\n\tconst unknownKeys = (value, allowed, path) => {\n\t\tfor (const key of Object.keys(value)) if (!allowed.includes(key)) issue(path ? `${path}.${key}` : key, \"is not a template field.\");\n\t};\n\tif (!isRecord(input)) throw new RemoteConfigValidationError([{\n\t\tpath: \"\",\n\t\tmessage: \"A template is an object.\"\n\t}]);\n\tunknownKeys(input, [\"conditions\", \"parameters\"], \"\");\n\tconst conditions = [];\n\tconst conditionNames = /* @__PURE__ */ new Set();\n\tconst rawConditions = input.conditions ?? [];\n\tif (!Array.isArray(rawConditions)) issue(\"conditions\", \"must be a list.\");\n\telse {\n\t\tif (rawConditions.length > 500) issue(\"conditions\", `holds at most 500 conditions.`);\n\t\trawConditions.forEach((raw, index) => {\n\t\t\tconst path = `conditions[${index}]`;\n\t\t\tif (!isRecord(raw)) {\n\t\t\t\tissue(path, \"must be an object.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tunknownKeys(raw, [\"name\", \"rules\"], path);\n\t\t\tconst { name } = raw;\n\t\t\tif (!visibleText(name, MAX_CONDITION_NAME_LENGTH)) issue(`${path}.name`, `must be 1-${MAX_CONDITION_NAME_LENGTH} visible characters.`);\n\t\t\telse if (conditionNames.has(name)) issue(`${path}.name`, `\"${name}\" names another condition too.`);\n\t\t\telse conditionNames.add(name);\n\t\t\tconst rules = validateRules(raw.rules, `${path}.rules`, issue);\n\t\t\tif (typeof name === \"string\") conditions.push({\n\t\t\t\tname,\n\t\t\t\trules\n\t\t\t});\n\t\t});\n\t}\n\tconst parameters = [];\n\tconst rawParameters = input.parameters ?? {};\n\tif (!isRecord(rawParameters)) issue(\"parameters\", \"must be an object keyed by parameter.\");\n\telse {\n\t\tconst keys = Object.keys(rawParameters);\n\t\tif (keys.length > 2e3) issue(\"parameters\", `holds at most ${REMOTE_CONFIG_MAX_PARAMETERS} parameters.`);\n\t\tfor (const key of keys) {\n\t\t\tconst path = `parameters.${key}`;\n\t\t\tif (!PARAMETER_KEY_PATTERN.test(key)) issue(path, \"Parameter keys start with a letter or _, and hold up to 256 letters, digits, and _.\");\n\t\t\tconst raw = rawParameters[key];\n\t\t\tif (!isRecord(raw)) {\n\t\t\t\tissue(path, \"must be an object.\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tunknownKeys(raw, [\n\t\t\t\t\"valueType\",\n\t\t\t\t\"defaultValue\",\n\t\t\t\t\"conditionalValues\",\n\t\t\t\t\"description\"\n\t\t\t], path);\n\t\t\tconst valueType = raw.valueType;\n\t\t\tif (typeof valueType !== \"string\" || !VALUE_TYPES.has(valueType)) {\n\t\t\t\tissue(`${path}.valueType`, \"must be STRING, NUMBER, BOOLEAN, or JSON.\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst type = valueType;\n\t\t\tconst readValue = (value, valuePath) => {\n\t\t\t\tif (!isRecord(value)) {\n\t\t\t\t\tissue(valuePath, \"must be { value } or { useInAppDefault: true }.\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (\"useInAppDefault\" in value) {\n\t\t\t\t\tunknownKeys(value, [\"useInAppDefault\"], valuePath);\n\t\t\t\t\tif (value.useInAppDefault !== true) {\n\t\t\t\t\t\tissue(`${valuePath}.useInAppDefault`, \"must be true.\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn { useInAppDefault: true };\n\t\t\t\t}\n\t\t\t\tunknownKeys(value, [\"value\"], valuePath);\n\t\t\t\tif (typeof value.value !== \"string\") {\n\t\t\t\t\tissue(`${valuePath}.value`, \"must be text.\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst problem = checkValueText(type, value.value);\n\t\t\t\tif (problem !== null) {\n\t\t\t\t\tissue(`${valuePath}.value`, problem);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn { value: value.value };\n\t\t\t};\n\t\t\tconst defaultValue = readValue(raw.defaultValue, `${path}.defaultValue`);\n\t\t\tconst conditionalValues = [];\n\t\t\tif (raw.conditionalValues !== void 0) {\n\t\t\t\tif (!isRecord(raw.conditionalValues)) issue(`${path}.conditionalValues`, \"must be an object keyed by condition.\");\n\t\t\t\telse for (const [conditionName, value] of Object.entries(raw.conditionalValues)) {\n\t\t\t\t\tconst valuePath = `${path}.conditionalValues.${conditionName}`;\n\t\t\t\t\tif (!conditionNames.has(conditionName)) {\n\t\t\t\t\t\tissue(valuePath, `No condition is named \"${conditionName}\".`);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst read = readValue(value, valuePath);\n\t\t\t\t\tif (read !== null) conditionalValues.push([conditionName, read]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet description;\n\t\t\tif (raw.description !== void 0) {\n\t\t\t\tconst text = typeof raw.description === \"string\" ? raw.description.trim() : null;\n\t\t\t\tif (text === null || text.length > MAX_DESCRIPTION_LENGTH) issue(`${path}.description`, `must be text of up to ${MAX_DESCRIPTION_LENGTH} characters.`);\n\t\t\t\telse if (text.length > 0) description = text;\n\t\t\t}\n\t\t\tif (defaultValue !== null) parameters.push([key, {\n\t\t\t\tvalueType: type,\n\t\t\t\tdefaultValue,\n\t\t\t\t...conditionalValues.length === 0 ? {} : { conditionalValues: Object.fromEntries(conditionalValues) },\n\t\t\t\t...description === void 0 ? {} : { description }\n\t\t\t}]);\n\t\t}\n\t}\n\tif (issues.length > 0) throw new RemoteConfigValidationError(issues);\n\tconst template = {\n\t\tconditions,\n\t\tparameters: Object.fromEntries(parameters)\n\t};\n\tconst length = JSON.stringify(template).length;\n\tif (length > 6e4) throw new RemoteConfigValidationError([{\n\t\tpath: \"\",\n\t\tmessage: `The template takes ${length.toLocaleString(\"en-US\")} characters of JSON; the limit is ${REMOTE_CONFIG_MAX_TEMPLATE_LENGTH.toLocaleString(\"en-US\")}.`\n\t}]);\n\treturn template;\n};\nconst textList = (value, path, issue, check, describe) => {\n\tif (!Array.isArray(value) || value.length === 0 || value.length > MAX_RULE_VALUES) {\n\t\tissue(path, `must list 1-${MAX_RULE_VALUES} values.`);\n\t\treturn [];\n\t}\n\tconst list = [];\n\tvalue.forEach((entry, index) => {\n\t\tif (typeof entry !== \"string\" || !check(entry)) issue(`${path}[${index}]`, describe);\n\t\telse if (!list.includes(entry)) list.push(entry);\n\t});\n\treturn list;\n};\nconst RULE_FIELDS = {\n\tplatform: [\"type\", \"platforms\"],\n\tchannel: [\"type\", \"channels\"],\n\tappVersion: [\"type\", \"range\"],\n\tcohort: [\"type\", \"cohorts\"],\n\tpercent: [\n\t\t\"type\",\n\t\t\"seed\",\n\t\t\"from\",\n\t\t\"to\"\n\t],\n\tfingerprint: [\"type\", \"hashes\"],\n\tdateTime: [\n\t\t\"type\",\n\t\t\"from\",\n\t\t\"to\"\n\t]\n};\nconst validateRules = (value, path, issue) => {\n\tif (!Array.isArray(value) || value.length === 0) {\n\t\tissue(path, \"must list at least one rule.\");\n\t\treturn [];\n\t}\n\tconst rules = [];\n\tvalue.forEach((raw, index) => {\n\t\tconst rulePath = `${path}[${index}]`;\n\t\tif (!isRecord(raw) || typeof raw.type !== \"string\") {\n\t\t\tissue(rulePath, \"must be a rule object with a type.\");\n\t\t\treturn;\n\t\t}\n\t\tconst type = raw.type;\n\t\tconst fields = ownEntry(RULE_FIELDS, type);\n\t\tif (fields === void 0) {\n\t\t\tissue(`${rulePath}.type`, \"must be platform, channel, appVersion, cohort, percent, fingerprint, or dateTime.\");\n\t\t\treturn;\n\t\t}\n\t\tfor (const key of Object.keys(raw)) if (!fields.includes(key)) issue(`${rulePath}.${key}`, `is not a field of a ${type} rule.`);\n\t\tswitch (type) {\n\t\t\tcase \"platform\": {\n\t\t\t\tconst platforms = textList(raw.platforms, `${rulePath}.platforms`, issue, (text) => PLATFORMS.has(text), \"must be \\\"ios\\\" or \\\"android\\\".\");\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tplatforms\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"channel\": {\n\t\t\t\tconst channels = textList(raw.channels, `${rulePath}.channels`, issue, (text) => visibleText(text, MAX_RULE_TEXT_LENGTH), `must be a channel name of 1-${MAX_RULE_TEXT_LENGTH} characters.`);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tchannels\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"appVersion\": {\n\t\t\t\tconst range = raw.range;\n\t\t\t\tif (!visibleText(range, MAX_RULE_TEXT_LENGTH) || !isValidRange(range.trim())) {\n\t\t\t\t\tissue(`${rulePath}.range`, \"must be a semver range, such as >=1.4.0 or 2.x.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\trange: range.trim()\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"cohort\": {\n\t\t\t\tconst cohorts = textList(raw.cohorts, `${rulePath}.cohorts`, issue, isValidCohort, \"must be a cohort from 1 to 1000, or a lowercase slug.\").map(normalizeCohortValue);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tcohorts: [...new Set(cohorts)]\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"percent\": {\n\t\t\t\tconst { seed, from, to } = raw;\n\t\t\t\tif (typeof seed !== \"string\" || !SEED_PATTERN.test(seed)) {\n\t\t\t\t\tissue(`${rulePath}.seed`, \"must be 1-64 letters, digits, _, and -.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst isPercent = (value) => typeof value === \"number\" && value >= 0 && value <= 100 && Math.abs(value * 10 - Math.round(value * 10)) < 1e-9;\n\t\t\t\tif (!isPercent(from) || !isPercent(to) || from >= to) {\n\t\t\t\t\tissue(rulePath, \"takes from < to, each a percentage from 0 to 100 in steps of 0.1.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\tseed,\n\t\t\t\t\tfrom,\n\t\t\t\t\tto\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"fingerprint\": {\n\t\t\t\tconst hashes = textList(raw.hashes, `${rulePath}.hashes`, issue, (text) => visibleText(text, MAX_RULE_TEXT_LENGTH), `must be a fingerprint of 1-${MAX_RULE_TEXT_LENGTH} characters.`);\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\thashes\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"dateTime\": {\n\t\t\t\tconst instant = (field) => {\n\t\t\t\t\tconst value = raw[field];\n\t\t\t\t\tif (value === void 0) return void 0;\n\t\t\t\t\tconst ms = typeof value === \"string\" ? Date.parse(value) : NaN;\n\t\t\t\t\tif (typeof value !== \"string\" || !DATE_TIME_PATTERN.test(value) || !Number.isFinite(ms)) {\n\t\t\t\t\t\tissue(`${rulePath}.${field}`, \"must be an ISO 8601 date-time with a time zone, such as 2026-10-08T10:00:00Z.\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn new Date(ms).toISOString();\n\t\t\t\t};\n\t\t\t\tconst from = instant(\"from\");\n\t\t\t\tconst to = instant(\"to\");\n\t\t\t\tif (from === null || to === null) return;\n\t\t\t\tif (from === void 0 && to === void 0) {\n\t\t\t\t\tissue(rulePath, \"takes from, to, or both.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (from !== void 0 && to !== void 0 && from >= to) {\n\t\t\t\t\tissue(rulePath, \"takes a from before its to.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trules.push({\n\t\t\t\t\ttype,\n\t\t\t\t\t...from === void 0 ? {} : { from },\n\t\t\t\t\t...to === void 0 ? {} : { to }\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\treturn rules;\n};\n/** Whether one rule matches a device. */\nconst matchesRemoteConfigRule = (rule, context) => {\n\tswitch (rule.type) {\n\t\tcase \"platform\": return context.platform !== void 0 && context.platform !== null && rule.platforms.includes(context.platform);\n\t\tcase \"channel\": return typeof context.channel === \"string\" && rule.channels.includes(context.channel);\n\t\tcase \"appVersion\": return typeof context.appVersion === \"string\" && semverSatisfies(rule.range, context.appVersion);\n\t\tcase \"cohort\": return typeof context.cohort === \"string\" && rule.cohorts.includes(normalizeCohortValue(context.cohort));\n\t\tcase \"percent\": {\n\t\t\tif (typeof context.cohort !== \"string\") return false;\n\t\t\tconst cohort = getNumericCohortValue(context.cohort);\n\t\t\tif (cohort === null) return false;\n\t\t\tconst position = getNumericCohortRolloutPosition(rule.seed, cohort);\n\t\t\treturn position >= Math.round(rule.from * 10) && position < Math.round(rule.to * 10);\n\t\t}\n\t\tcase \"fingerprint\": return typeof context.fingerprintHash === \"string\" && rule.hashes.includes(context.fingerprintHash);\n\t\tcase \"dateTime\": return typeof context.now === \"number\" && (rule.from === void 0 || context.now >= Date.parse(rule.from)) && (rule.to === void 0 || context.now < Date.parse(rule.to));\n\t}\n};\n/** Whether every rule of a condition matches a device. */\nconst matchesRemoteConfigCondition = (condition, context) => condition.rules.every((rule) => matchesRemoteConfigRule(rule, context));\n/**\n* Every parameter's value for one device: the value of the first condition,\n* in the template's order, that matches and that the parameter has a value\n* for; otherwise its default value.\n*/\nconst evaluateRemoteConfig = (template, context) => {\n\tconst matched = template.conditions.filter((condition) => matchesRemoteConfigCondition(condition, context)).map(({ name }) => name);\n\treturn Object.fromEntries(Object.entries(template.parameters).map(([key, parameter]) => {\n\t\tlet condition = null;\n\t\tlet chosen = parameter.defaultValue;\n\t\tfor (const name of matched) {\n\t\t\tconst value = ownEntry(parameter.conditionalValues, name);\n\t\t\tif (value !== void 0) {\n\t\t\t\tcondition = name;\n\t\t\t\tchosen = value;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn [key, {\n\t\t\tvalue: \"value\" in chosen ? chosen.value : null,\n\t\t\tcondition\n\t\t}];\n\t}));\n};\n/** The values a device receives: each parameter's text, without in-app defaults. */\nconst resolveRemoteConfigValues = (template, context) => {\n\treturn Object.fromEntries(Object.entries(evaluateRemoteConfig(template, context)).flatMap(([key, { value }]) => value === null ? [] : [[key, value]]));\n};\n//#endregion\nexport { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigValidationError, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, resolveRemoteConfigValues, validateRemoteConfigTemplate };\n", "import { EMPTY_REMOTE_CONFIG_TEMPLATE, resolveRemoteConfigValues, validateRemoteConfigTemplate } from \"./template.mjs\";\nimport { DatabaseConstraintError } from \"@hot-updater/plugin-core\";\n//#region src/server/api.ts\nconst ACTIVE_ID = \"active\";\n/** How long a server answers fetches from the active template it read last. */\nconst ACTIVE_CACHE_TTL_MS = 5e3;\nconst MAX_DESCRIPTION_LENGTH = 256;\nconst MAX_VERSIONS_PAGE = 100;\n/**\n* An argument the API refuses, such as a negative `baseVersion`; the admin\n* routes answer it with `400`.\n*/\nvar RemoteConfigInputError = class extends TypeError {\n\tname = \"RemoteConfigInputError\";\n};\nconst normalizeDescription = (description) => {\n\tif (description === void 0 || description === null) return null;\n\tif (typeof description !== \"string\") throw new RemoteConfigInputError(\"A version description is text.\");\n\tconst trimmed = description.trim();\n\tif (trimmed.length > MAX_DESCRIPTION_LENGTH) throw new RemoteConfigInputError(`A version description holds up to ${MAX_DESCRIPTION_LENGTH} characters.`);\n\treturn trimmed.length === 0 ? null : trimmed;\n};\nconst requireVersionNumber = (value, name) => {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) throw new RemoteConfigInputError(`${name} must be a non-negative integer.`);\n\treturn value;\n};\n/** A template as its `json` column stores it; validation made it plain JSON. */\nconst toColumn = (template) => template;\nconst fromColumn = (value) => value;\nconst toVersion = (row) => Object.freeze({\n\tversion: row.version,\n\tdescription: row.description,\n\tupdateType: row.update_type === \"ROLLBACK\" ? \"ROLLBACK\" : \"PUBLISH\",\n\trollbackSource: row.rollback_source,\n\tcreatedAtMs: row.created_at_ms\n});\n/** Remote Config's API over its tables. */\nconst createRemoteConfigApi = ({ db, now }) => {\n\tlet cached = null;\n\tlet loading = null;\n\tlet generation = 0;\n\tconst readActive = async () => {\n\t\tconst row = await db.findOne(\"remote_config_active\", { id: ACTIVE_ID });\n\t\treturn row === null ? {\n\t\t\tversion: 0,\n\t\t\ttemplate: EMPTY_REMOTE_CONFIG_TEMPLATE,\n\t\t\tupdatedAtMs: null\n\t\t} : {\n\t\t\tversion: row.version,\n\t\t\ttemplate: fromColumn(row.template),\n\t\t\tupdatedAtMs: row.updated_at_ms\n\t\t};\n\t};\n\t/** The active template for fetches: one read per server every few seconds at most. */\n\tconst servedActive = () => {\n\t\tif (cached !== null && cached.expiresAt > now()) return Promise.resolve(cached.active);\n\t\tif (loading !== null) return loading;\n\t\tconst started = generation;\n\t\tconst read = readActive().then((active) => {\n\t\t\tif (generation === started) cached = {\n\t\t\t\tactive,\n\t\t\t\texpiresAt: now() + ACTIVE_CACHE_TTL_MS\n\t\t\t};\n\t\t\treturn active;\n\t\t}).finally(() => {\n\t\t\tif (loading === read) loading = null;\n\t\t});\n\t\tloading = read;\n\t\treturn read;\n\t};\n\tconst commit = async (input) => {\n\t\tconst attempt = () => db.transaction(async (tx) => {\n\t\t\tconst active = await tx.findOne(\"remote_config_active\", { id: ACTIVE_ID });\n\t\t\tconst currentVersion = active?.version ?? 0;\n\t\t\tif (currentVersion !== input.baseVersion) return {\n\t\t\t\tstatus: \"conflict\",\n\t\t\t\tcurrentVersion\n\t\t\t};\n\t\t\tconst version = currentVersion + 1;\n\t\t\tconst at = now();\n\t\t\tconst row = {\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tdescription: input.description,\n\t\t\t\tupdate_type: input.rollbackSource === null ? \"PUBLISH\" : \"ROLLBACK\",\n\t\t\t\trollback_source: input.rollbackSource,\n\t\t\t\tcreated_at_ms: at\n\t\t\t};\n\t\t\ttx.create(\"remote_config_versions\", row);\n\t\t\tif (active === null) tx.create(\"remote_config_active\", {\n\t\t\t\tid: ACTIVE_ID,\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tupdated_at_ms: at\n\t\t\t});\n\t\t\telse tx.update(\"remote_config_active\", active, {\n\t\t\t\tversion,\n\t\t\t\ttemplate: toColumn(input.template),\n\t\t\t\tupdated_at_ms: at\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tstatus: \"published\",\n\t\t\t\tversion: toVersion(row)\n\t\t\t};\n\t\t});\n\t\ttry {\n\t\t\tconst result = await attempt();\n\t\t\tif (result.status === \"published\") {\n\t\t\t\tgeneration += 1;\n\t\t\t\tcached = null;\n\t\t\t\tloading = null;\n\t\t\t}\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseConstraintError && (error.reason === \"exists\" || error.reason === \"unique\")) return {\n\t\t\t\tstatus: \"conflict\",\n\t\t\t\tcurrentVersion: (await readActive()).version\n\t\t\t};\n\t\t\tthrow error;\n\t\t}\n\t};\n\treturn Object.freeze({\n\t\tgetActive: readActive,\n\t\tpublish: async ({ template, baseVersion, description }) => commit({\n\t\t\ttemplate: validateRemoteConfigTemplate(template),\n\t\t\tbaseVersion: requireVersionNumber(baseVersion, \"baseVersion\"),\n\t\t\tdescription: normalizeDescription(description),\n\t\t\trollbackSource: null\n\t\t}),\n\t\trollback: async ({ version, baseVersion, description }) => {\n\t\t\tconst source = await db.findOne(\"remote_config_versions\", { version: requireVersionNumber(version, \"version\") });\n\t\t\tif (source === null) return { status: \"not_found\" };\n\t\t\treturn commit({\n\t\t\t\ttemplate: fromColumn(source.template),\n\t\t\t\tbaseVersion: requireVersionNumber(baseVersion, \"baseVersion\"),\n\t\t\t\tdescription: normalizeDescription(description) ?? `Rollback to version ${source.version}`,\n\t\t\t\trollbackSource: source.version\n\t\t\t});\n\t\t},\n\t\tlistVersions: async ({ limit = 20, cursor } = {}) => {\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_VERSIONS_PAGE) throw new RemoteConfigInputError(`limit must be an integer from 1 to ${MAX_VERSIONS_PAGE}.`);\n\t\t\tconst page = await db.findMany(\"remote_config_versions\", {\n\t\t\t\tindex: \"byVersion\",\n\t\t\t\twhere: {},\n\t\t\t\torder: \"desc\",\n\t\t\t\tlimit,\n\t\t\t\t...cursor === void 0 ? {} : { cursor }\n\t\t\t});\n\t\t\treturn Object.freeze({\n\t\t\t\tversions: Object.freeze(page.rows.map(toVersion)),\n\t\t\t\t...page.next === void 0 ? {} : { next: page.next }\n\t\t\t});\n\t\t},\n\t\tgetVersion: async (version) => {\n\t\t\tconst row = await db.findOne(\"remote_config_versions\", { version: requireVersionNumber(version, \"version\") });\n\t\t\treturn row === null ? null : Object.freeze({\n\t\t\t\t...toVersion(row),\n\t\t\t\ttemplate: fromColumn(row.template)\n\t\t\t});\n\t\t},\n\t\tresolve: async (context) => {\n\t\t\tconst active = await servedActive();\n\t\t\treturn {\n\t\t\t\tversion: active.version,\n\t\t\t\tvalues: resolveRemoteConfigValues(active.template, {\n\t\t\t\t\t...context,\n\t\t\t\t\tnow: context.now ?? now()\n\t\t\t\t})\n\t\t\t};\n\t\t}\n\t});\n};\n//#endregion\nexport { RemoteConfigInputError, createRemoteConfigApi };\n", "//#region src/server/official.ts\n/**\n* The brand of Hot Updater's own plugins, a registered symbol that\n* `@hot-updater/server` reads to reserve the id \"remoteConfig\" for this plugin.\n* Each official plugin package keeps this copy, so none imports another's\n* internals for it.\n*/\nconst OFFICIAL = Symbol.for(\"@hot-updater/server/official-plugin\");\n/** Marks a plugin one of Hot Updater's own factories made. */\nconst markOfficial = (plugin) => Object.defineProperty(plugin, OFFICIAL, { value: true });\n//#endregion\nexport { markOfficial };\n", "//#region src/shared/wire.ts\n/**\n* The exchange between the app's `remoteConfig()` client plugin and the\n* `remoteConfig()` server plugin: `GET /remote-config`, relative to the\n* `baseURL` the app passes to `HotUpdater.init`. The app\n* sends what conditions read as query parameters, and the server answers the\n* values the published template gives them. Both sides import this module,\n* which imports nothing, so the app's bundle never reaches server code.\n*/\n/** The path both sides use, relative to the app's `baseURL`. */\nconst REMOTE_CONFIG_PATH = \"remote-config\";\n/** The query parameter each context field travels in. */\nconst REMOTE_CONFIG_QUERY = {\n\tplatform: \"platform\",\n\tappVersion: \"appVersion\",\n\tchannel: \"channel\",\n\tcohort: \"cohort\",\n\tfingerprintHash: \"fingerprintHash\"\n};\n/**\n* `GET /remote-config?\u2026`, with a field left out when it is null. It encodes\n* the query itself, since React Native's `URLSearchParams` throws on `set`.\n*/\nconst remoteConfigRequestPath = (context) => {\n\tconst query = Object.keys(REMOTE_CONFIG_QUERY).flatMap((field) => {\n\t\tconst value = context[field];\n\t\treturn value === null ? [] : [`${encodeURIComponent(REMOTE_CONFIG_QUERY[field])}=${encodeURIComponent(value)}`];\n\t});\n\treturn `${REMOTE_CONFIG_PATH}?${query.join(\"&\")}`;\n};\nconst isRecord = (value) => typeof value === \"object\" && value !== null && !Array.isArray(value);\n/** A `200` body, checked; null when it is not one. */\nconst parseRemoteConfigFetchResponse = (value) => {\n\tif (!isRecord(value)) return null;\n\tconst { version, values } = value;\n\tif (typeof version !== \"number\" || !Number.isSafeInteger(version) || version < 0 || !isRecord(values)) return null;\n\tconst entries = Object.entries(values);\n\tif (entries.some(([, text]) => typeof text !== \"string\")) return null;\n\treturn {\n\t\tversion,\n\t\tvalues: Object.fromEntries(entries)\n\t};\n};\n//#endregion\nexport { REMOTE_CONFIG_PATH, REMOTE_CONFIG_QUERY, parseRemoteConfigFetchResponse, remoteConfigRequestPath };\n", "import { RemoteConfigValidationError } from \"./template.mjs\";\nimport { RemoteConfigInputError } from \"./api.mjs\";\nimport { REMOTE_CONFIG_PATH, REMOTE_CONFIG_QUERY } from \"../shared/wire.mjs\";\nimport { DatabaseCursorError, isDatabaseBusyError } from \"@hot-updater/plugin-core\";\n//#region src/server/routes.ts\n/** Seconds a client waits before it resends a request the busy database refused. */\nconst RETRY_AFTER_SECONDS = 5;\n/** A shared cache keeps a device's values five seconds, as it keeps a Release Catalog. */\nconst FETCH_CACHE_CONTROL = \"public, max-age=0, s-maxage=5\";\nconst MAX_CONTEXT_LENGTH = 128;\nvar BadRequestError = class extends Error {};\nconst json = (body, status, headers = {}) => Response.json(body, {\n\theaders: {\n\t\t\"cache-control\": \"private, no-store\",\n\t\t...headers\n\t},\n\tstatus\n});\nconst run = async (operation) => {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof RemoteConfigValidationError) return json({\n\t\t\terror: error.message,\n\t\t\tissues: error.issues\n\t\t}, 400);\n\t\tif (error instanceof BadRequestError || error instanceof RemoteConfigInputError || error instanceof DatabaseCursorError) return json({ error: error.message }, 400);\n\t\tif (isDatabaseBusyError(error)) {\n\t\t\tconsole.warn(\"[hot-updater] Remote Config answered 503: the database is busy.\", error);\n\t\t\treturn json({ error: \"Service unavailable\" }, 503, { \"retry-after\": String(RETRY_AFTER_SECONDS) });\n\t\t}\n\t\tthrow error;\n\t}\n};\nconst readContext = (request) => {\n\tconst query = new URL(request.url).searchParams;\n\tconst read = (field) => {\n\t\tconst value = query.get(REMOTE_CONFIG_QUERY[field]);\n\t\tif (value === null || value.length === 0) return null;\n\t\tif (value.length > MAX_CONTEXT_LENGTH) throw new BadRequestError(`${field} is too long.`);\n\t\treturn value;\n\t};\n\tconst platform = read(\"platform\");\n\tif (platform !== null && platform !== \"ios\" && platform !== \"android\") throw new BadRequestError(\"platform must be \\\"ios\\\" or \\\"android\\\".\");\n\treturn {\n\t\tplatform,\n\t\tappVersion: read(\"appVersion\"),\n\t\tchannel: read(\"channel\"),\n\t\tcohort: read(\"cohort\"),\n\t\tfingerprintHash: read(\"fingerprintHash\")\n\t};\n};\nconst bodyHash = async (body) => {\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(body));\n\treturn [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n};\nconst readJsonBody = async (request) => {\n\tconst body = await request.json().catch(() => null);\n\tif (typeof body !== \"object\" || body === null || Array.isArray(body)) throw new BadRequestError(\"The request body must be a JSON object.\");\n\treturn body;\n};\nconst versionParam = (params) => {\n\tconst text = params.version ?? \"\";\n\tif (!/^\\d{1,15}$/u.test(text)) throw new BadRequestError(\"The version must be a positive integer.\");\n\treturn Number(text);\n};\nconst publishResponse = (result) => result.status === \"published\" ? json(result.version, 200) : json({\n\terror: `Version ${result.currentVersion} was published since; reload the template and publish again.`,\n\tcurrentVersion: result.currentVersion\n}, 409);\n/**\n* Remote Config's routes: the devices' `GET /remote-config` on\n* `handlers.client`, and template management on `handlers.admin`.\n*/\nconst createRemoteConfigEndpoints = (api) => [\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}`,\n\t\taccess: \"client\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst body = JSON.stringify(await api.resolve(readContext(request)));\n\t\t\tconst etag = `\"sha256:${await bodyHash(body)}\"`;\n\t\t\tconst headers = {\n\t\t\t\t\"cache-control\": FETCH_CACHE_CONTROL,\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\tetag,\n\t\t\t\tvary: \"Accept-Encoding\"\n\t\t\t};\n\t\t\tif (request.headers.get(\"if-none-match\") === etag) return new Response(null, {\n\t\t\t\theaders,\n\t\t\t\tstatus: 304\n\t\t\t});\n\t\t\treturn new Response(body, {\n\t\t\t\theaders,\n\t\t\t\tstatus: 200\n\t\t\t});\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/template`,\n\t\taccess: \"admin\",\n\t\thandler: () => run(async () => json(await api.getActive(), 200))\n\t},\n\t{\n\t\tmethod: \"PUT\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/template`,\n\t\taccess: \"admin\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst body = await readJsonBody(request);\n\t\t\treturn publishResponse(await api.publish({\n\t\t\t\ttemplate: body.template,\n\t\t\t\tbaseVersion: body.baseVersion,\n\t\t\t\t...body.description === void 0 ? {} : { description: body.description }\n\t\t\t}));\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions`,\n\t\taccess: \"admin\",\n\t\thandler: (request) => run(async () => {\n\t\t\tconst query = new URL(request.url).searchParams;\n\t\t\tconst limit = query.get(\"limit\");\n\t\t\tconst cursor = query.get(\"cursor\");\n\t\t\treturn json(await api.listVersions({\n\t\t\t\t...limit === null ? {} : { limit: Number(limit) },\n\t\t\t\t...cursor === null ? {} : { cursor }\n\t\t\t}), 200);\n\t\t})\n\t},\n\t{\n\t\tmethod: \"GET\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions/:version`,\n\t\taccess: \"admin\",\n\t\thandler: (_request, params) => run(async () => {\n\t\t\tconst version = await api.getVersion(versionParam(params));\n\t\t\treturn version === null ? json({ error: \"Version not found\" }, 404) : json(version, 200);\n\t\t})\n\t},\n\t{\n\t\tmethod: \"POST\",\n\t\tpath: `/${REMOTE_CONFIG_PATH}/versions/:version/rollback`,\n\t\taccess: \"admin\",\n\t\thandler: (request, params) => run(async () => {\n\t\t\tconst body = await readJsonBody(request);\n\t\t\tconst result = await api.rollback({\n\t\t\t\tversion: versionParam(params),\n\t\t\t\tbaseVersion: body.baseVersion,\n\t\t\t\t...body.description === void 0 ? {} : { description: body.description }\n\t\t\t});\n\t\t\treturn result.status === \"not_found\" ? json({ error: \"Version not found\" }, 404) : publishResponse(result);\n\t\t})\n\t}\n];\n//#endregion\nexport { createRemoteConfigEndpoints };\n", "import { defineTable } from \"@hot-updater/plugin-core\";\n//#region src/server/schema.ts\n/**\n* Remote Config's tables: the active template in one row, which a device's\n* fetch reads by key, and every published version beside it.\n*/\nconst remoteConfigSchema = {\n\t/** One row, `id` `\"active\"`: the template devices receive and its version. */\n\tremote_config_active: defineTable({\n\t\tid: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\tversion: { type: \"integer\" },\n\t\ttemplate: { type: \"json\" },\n\t\tupdated_at_ms: { type: \"integer\" }\n\t}, { key: [\"id\"] }),\n\t/** Each publish and rollback, kept so the Console can show and restore it. */\n\tremote_config_versions: defineTable({\n\t\tversion: { type: \"integer\" },\n\t\ttemplate: { type: \"json\" },\n\t\tdescription: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 256,\n\t\t\trequired: false\n\t\t},\n\t\t/** `PUBLISH`, or `ROLLBACK` for a copy of `rollback_source`. */\n\t\tupdate_type: {\n\t\t\ttype: \"string\",\n\t\t\tmaxLength: 16\n\t\t},\n\t\trollback_source: {\n\t\t\ttype: \"integer\",\n\t\t\trequired: false\n\t\t},\n\t\tcreated_at_ms: { type: \"integer\" }\n\t}, {\n\t\tkey: [\"version\"],\n\t\tindexes: { byVersion: {\n\t\t\teq: [],\n\t\t\tsort: [\"version\"]\n\t\t} }\n\t})\n};\n//#endregion\nexport { remoteConfigSchema };\n", "import { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigValidationError, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, resolveRemoteConfigValues, validateRemoteConfigTemplate } from \"./template.mjs\";\nimport { RemoteConfigInputError, createRemoteConfigApi } from \"./api.mjs\";\nimport { markOfficial } from \"./official.mjs\";\nimport { createRemoteConfigEndpoints } from \"./routes.mjs\";\nimport { remoteConfigSchema } from \"./schema.mjs\";\nimport { createRemoteConfigAdminApi } from \"./admin.mjs\";\nimport { definePlugin } from \"@hot-updater/plugin-core\";\n//#region src/server/index.ts\n/**\n* Remote Config: parameters whose values the server picks per device by\n* conditions, published as versioned templates. Devices fetch their values\n* from `GET /remote-config` with the `remoteConfig()` client plugin; the\n* Console and `hotUpdater.api.remoteConfig` edit, publish, and roll back\n* templates.\n*/\nconst remoteConfig = () => {\n\tconst plugin = definePlugin({\n\t\tid: \"remoteConfig\",\n\t\tnamespace: false,\n\t\tschemaVersion: \"1.0.0\",\n\t\tschema: remoteConfigSchema,\n\t\tinit: ({ db, now }) => {\n\t\t\tconst api = createRemoteConfigApi({\n\t\t\t\tdb,\n\t\t\t\tnow\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tapi,\n\t\t\t\tendpoints: createRemoteConfigEndpoints(api)\n\t\t\t};\n\t\t}\n\t});\n\treturn markOfficial(plugin);\n};\n//#endregion\nexport { EMPTY_REMOTE_CONFIG_TEMPLATE, REMOTE_CONFIG_MAX_CONDITIONS, REMOTE_CONFIG_MAX_PARAMETERS, REMOTE_CONFIG_MAX_TEMPLATE_LENGTH, RemoteConfigInputError, RemoteConfigValidationError, createRemoteConfigAdminApi, evaluateRemoteConfig, matchesRemoteConfigCondition, matchesRemoteConfigRule, remoteConfig, remoteConfigSchema, resolveRemoteConfigValues, validateRemoteConfigTemplate };\n", "import { createHotUpdater } from \"@hot-updater/server\";\nimport { apiKeys, insights, remoteConfig } from \"@hot-updater/server/plugins\";\nimport { env } from \"cloudflare:workers\";\nimport { Hono } from \"hono\";\n\nimport { d1Database, r2Storage } from \"../../src/worker\";\n\nexport type CloudflareWorkerEnv = {\n DB: {\n batch: D1Database[\"batch\"];\n prepare: D1Database[\"prepare\"];\n };\n BUCKET: R2Bucket;\n BUCKET_NAME: string;\n ACCOUNT_ID: string;\n R2_ACCESS_KEY_ID: string;\n R2_SECRET_ACCESS_KEY: string;\n};\n\nexport const HOT_UPDATER_BASE_PATH = \"/\";\n\nconst hotUpdater = createHotUpdater({\n database: d1Database(env.DB),\n plugins: [insights(), apiKeys(), remoteConfig()],\n storage: r2Storage({\n bucket: env.BUCKET,\n bucketName: env.BUCKET_NAME,\n // Presign download URLs, so devices download from R2.\n accountId: env.ACCOUNT_ID,\n credentials: {\n accessKeyId: env.R2_ACCESS_KEY_ID,\n secretAccessKey: env.R2_SECRET_ACCESS_KEY,\n },\n }),\n});\n\nconst app = new Hono<{ Bindings: CloudflareWorkerEnv }>();\n\napp.mount(HOT_UPDATER_BASE_PATH, (request: Request) =>\n hotUpdater.handlers.client(request),\n);\n\nexport default app;\n", "// src/compose.ts\nvar compose = (middleware, onError, onNotFound) => {\n return (context, next) => {\n let index = -1;\n return dispatch(0);\n async function dispatch(i) {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n let res;\n let isError = false;\n let handler;\n if (middleware[i]) {\n handler = middleware[i][0][0];\n context.req.routeIndex = i;\n } else {\n handler = i === middleware.length && next || void 0;\n }\n if (handler) {\n try {\n res = await handler(context, () => dispatch(i + 1));\n } catch (err) {\n if (err instanceof Error && onError) {\n context.error = err;\n res = await onError(err, context);\n isError = true;\n } else {\n throw err;\n }\n }\n } else {\n if (context.finalized === false && onNotFound) {\n res = await onNotFound(context);\n }\n }\n if (res && (context.finalized === false || isError)) {\n context.res = res;\n }\n return context;\n }\n };\n};\nexport {\n compose\n};\n", "// src/request/constants.ts\nvar GET_MATCH_RESULT = /* @__PURE__ */ Symbol();\nexport {\n GET_MATCH_RESULT\n};\n", "// src/utils/buffer.ts\nimport { sha256 } from \"./crypto.js\";\nvar equal = (a, b) => {\n if (a === b) {\n return true;\n }\n if (a.byteLength !== b.byteLength) {\n return false;\n }\n const va = new DataView(a);\n const vb = new DataView(b);\n let i = va.byteLength;\n while (i--) {\n if (va.getUint8(i) !== vb.getUint8(i)) {\n return false;\n }\n }\n return true;\n};\nvar constantTimeEqualString = (a, b) => {\n const aLen = a.length;\n const bLen = b.length;\n const maxLen = Math.max(aLen, bLen);\n let out = aLen ^ bLen;\n for (let i = 0; i < maxLen; i++) {\n const aChar = i < aLen ? a.charCodeAt(i) : 0;\n const bChar = i < bLen ? b.charCodeAt(i) : 0;\n out |= aChar ^ bChar;\n }\n return out === 0;\n};\nvar timingSafeEqualString = async (a, b, hashFunction) => {\n if (!hashFunction) {\n hashFunction = sha256;\n }\n const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);\n if (sa == null || sb == null || typeof sa !== \"string\" || typeof sb !== \"string\") {\n return false;\n }\n const hashEqual = constantTimeEqualString(sa, sb);\n const originalEqual = constantTimeEqualString(a, b);\n return hashEqual && originalEqual;\n};\nvar timingSafeEqual = async (a, b, hashFunction) => {\n if (typeof a === \"string\" && typeof b === \"string\") {\n return timingSafeEqualString(a, b, hashFunction);\n }\n if (!hashFunction) {\n hashFunction = sha256;\n }\n const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);\n if (!sa || !sb || typeof sa !== \"string\" || typeof sb !== \"string\") {\n return false;\n }\n return timingSafeEqualString(sa, sb);\n};\nvar bufferToString = (buffer) => {\n if (buffer instanceof ArrayBuffer) {\n const enc = new TextDecoder(\"utf-8\");\n return enc.decode(buffer);\n }\n return buffer;\n};\nvar bufferToFormData = (arrayBuffer, contentType) => {\n const response = new Response(arrayBuffer, {\n headers: {\n // Normalize the media type (case-insensitive) while keeping parameters like the boundary\n \"Content-Type\": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())\n }\n });\n return response.formData();\n};\nexport {\n bufferToFormData,\n bufferToString,\n equal,\n timingSafeEqual\n};\n", "// src/utils/body.ts\nimport { bufferToFormData } from \"./buffer.js\";\nvar isRawRequest = (request) => \"headers\" in request;\nvar parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {\n const { all = false, dot = false } = options;\n const headers = isRawRequest(request) ? request.headers : request.raw.headers;\n const contentType = headers.get(\"Content-Type\");\n const mediaType = contentType?.split(\";\")[0].trim().toLowerCase();\n if (mediaType === \"multipart/form-data\" || mediaType === \"application/x-www-form-urlencoded\") {\n return parseFormData(request, { all, dot });\n }\n return {};\n};\nasync function parseFormData(request, options) {\n if (!isRawRequest(request) && request.bodyCache.formData) {\n return convertFormDataToBodyData(\n await request.bodyCache.formData,\n options\n );\n }\n const headers = isRawRequest(request) ? request.headers : request.raw.headers;\n const arrayBuffer = await request.arrayBuffer();\n const formDataPromise = bufferToFormData(arrayBuffer, headers.get(\"Content-Type\") || \"\");\n if (!isRawRequest(request)) {\n request.bodyCache.formData = formDataPromise;\n }\n const formData = await formDataPromise;\n if (formData) {\n return convertFormDataToBodyData(formData, options);\n }\n return {};\n}\nfunction convertFormDataToBodyData(formData, options) {\n const form = /* @__PURE__ */ Object.create(null);\n formData.forEach((value, key) => {\n const shouldParseAllValues = options.all || key.endsWith(\"[]\");\n if (!shouldParseAllValues) {\n form[key] = value;\n } else {\n handleParsingAllValues(form, key, value);\n }\n });\n if (options.dot) {\n Object.entries(form).forEach(([key, value]) => {\n const shouldParseDotValues = key.includes(\".\");\n if (shouldParseDotValues) {\n handleParsingNestedValues(form, key, value);\n delete form[key];\n }\n });\n }\n return form;\n}\nvar handleParsingAllValues = (form, key, value) => {\n if (form[key] !== void 0) {\n if (Array.isArray(form[key])) {\n ;\n form[key].push(value);\n } else {\n form[key] = [form[key], value];\n }\n } else {\n if (!key.endsWith(\"[]\")) {\n form[key] = value;\n } else {\n form[key] = [value];\n }\n }\n};\nvar handleParsingNestedValues = (form, key, value) => {\n if (/(?:^|\\.)__proto__\\./.test(key)) {\n return;\n }\n let nestedForm = form;\n const keys = key.split(\".\");\n keys.forEach((key2, index) => {\n if (index === keys.length - 1) {\n nestedForm[key2] = value;\n } else {\n if (!nestedForm[key2] || typeof nestedForm[key2] !== \"object\" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {\n nestedForm[key2] = /* @__PURE__ */ Object.create(null);\n }\n nestedForm = nestedForm[key2];\n }\n });\n};\nexport {\n parseBody\n};\n", "// src/utils/url.ts\nvar splitPath = (path) => {\n const paths = path.split(\"/\");\n if (paths[0] === \"\") {\n paths.shift();\n }\n return paths;\n};\nvar splitRoutingPath = (routePath) => {\n const { groups, path } = extractGroupsFromPath(routePath);\n const paths = splitPath(path);\n return replaceGroupMarks(paths, groups);\n};\nvar extractGroupsFromPath = (path) => {\n const groups = [];\n path = path.replace(/\\{[^}]+\\}/g, (match, index) => {\n const mark = `@${index}`;\n groups.push([mark, match]);\n return mark;\n });\n return { groups, path };\n};\nvar replaceGroupMarks = (paths, groups) => {\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = paths.length - 1; j >= 0; j--) {\n if (paths[j].includes(mark)) {\n paths[j] = paths[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n return paths;\n};\nvar patternCache = {};\nvar getPattern = (label, next) => {\n if (label === \"*\") {\n return \"*\";\n }\n const match = label.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n if (match) {\n const cacheKey = `${label}#${next}`;\n if (!patternCache[cacheKey]) {\n if (match[2]) {\n patternCache[cacheKey] = next && next[0] !== \":\" && next[0] !== \"*\" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];\n } else {\n patternCache[cacheKey] = [label, match[1], true];\n }\n }\n return patternCache[cacheKey];\n }\n return null;\n};\nvar tryDecode = (str, decoder) => {\n try {\n return decoder(str);\n } catch {\n return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {\n try {\n return decoder(match);\n } catch {\n return match;\n }\n });\n }\n};\nvar tryDecodeURI = (str) => tryDecode(str, decodeURI);\nvar getPath = (request) => {\n const url = request.url;\n const start = url.indexOf(\"/\", url.indexOf(\":\") + 4);\n let i = start;\n for (; i < url.length; i++) {\n const charCode = url.charCodeAt(i);\n if (charCode === 37) {\n const queryIndex = url.indexOf(\"?\", i);\n const hashIndex = url.indexOf(\"#\", i);\n const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);\n const path = url.slice(start, end);\n return tryDecodeURI(path.includes(\"%25\") ? path.replace(/%25/g, \"%2525\") : path);\n } else if (charCode === 63 || charCode === 35) {\n break;\n }\n }\n return url.slice(start, i);\n};\nvar getQueryStrings = (url) => {\n const queryIndex = url.indexOf(\"?\", 8);\n return queryIndex === -1 ? \"\" : \"?\" + url.slice(queryIndex + 1);\n};\nvar getPathNoStrict = (request) => {\n const result = getPath(request);\n return result.length > 1 && result.at(-1) === \"/\" ? result.slice(0, -1) : result;\n};\nvar mergePath = (base, sub, ...rest) => {\n if (rest.length) {\n sub = mergePath(sub, ...rest);\n }\n return `${base?.[0] === \"/\" ? \"\" : \"/\"}${base}${sub === \"/\" ? \"\" : `${base?.at(-1) === \"/\" ? \"\" : \"/\"}${sub?.[0] === \"/\" ? sub.slice(1) : sub}`}`;\n};\nvar checkOptionalParameter = (path) => {\n if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(\":\")) {\n return null;\n }\n const segments = path.split(\"/\");\n const results = [];\n let basePath = \"\";\n segments.forEach((segment) => {\n if (segment !== \"\" && !/\\:/.test(segment)) {\n basePath += \"/\" + segment;\n } else if (/\\:/.test(segment)) {\n if (/\\?/.test(segment)) {\n if (results.length === 0 && basePath === \"\") {\n results.push(\"/\");\n } else {\n results.push(basePath);\n }\n const optionalSegment = segment.replace(\"?\", \"\");\n basePath += \"/\" + optionalSegment;\n results.push(basePath);\n } else {\n basePath += \"/\" + segment;\n }\n }\n });\n return results.filter((v, i, a) => a.indexOf(v) === i);\n};\nvar _decodeURI = (value) => {\n if (!/[%+]/.test(value)) {\n return value;\n }\n if (value.indexOf(\"+\") !== -1) {\n value = value.replace(/\\+/g, \" \");\n }\n return value.indexOf(\"%\") !== -1 ? tryDecode(value, decodeURIComponent_) : value;\n};\nvar _getQueryParam = (url, key, multiple) => {\n let encoded;\n if (!multiple && key && !/[%+]/.test(key)) {\n let keyIndex2 = url.indexOf(\"?\", 8);\n if (keyIndex2 === -1) {\n return void 0;\n }\n if (!url.startsWith(key, keyIndex2 + 1)) {\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n while (keyIndex2 !== -1) {\n const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);\n if (trailingKeyCode === 61) {\n const valueIndex = keyIndex2 + key.length + 2;\n const endIndex = url.indexOf(\"&\", valueIndex);\n return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));\n } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {\n return \"\";\n }\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n encoded = /[%+]/.test(url);\n if (!encoded) {\n return void 0;\n }\n }\n const results = /* @__PURE__ */ Object.create(null);\n encoded ??= /[%+]/.test(url);\n let keyIndex = url.indexOf(\"?\", 8);\n while (keyIndex !== -1) {\n const nextKeyIndex = url.indexOf(\"&\", keyIndex + 1);\n let valueIndex = url.indexOf(\"=\", keyIndex);\n if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {\n valueIndex = -1;\n }\n let name = url.slice(\n keyIndex + 1,\n valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex\n );\n if (encoded) {\n name = _decodeURI(name);\n }\n keyIndex = nextKeyIndex;\n if (name === \"\") {\n continue;\n }\n let value;\n if (valueIndex === -1) {\n value = \"\";\n } else {\n value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);\n if (encoded) {\n value = _decodeURI(value);\n }\n }\n if (multiple) {\n if (!(results[name] && Array.isArray(results[name]))) {\n results[name] = [];\n }\n ;\n results[name].push(value);\n } else {\n results[name] ??= value;\n }\n }\n return key ? results[key] : results;\n};\nvar getQueryParam = _getQueryParam;\nvar getQueryParams = (url, key) => {\n return _getQueryParam(url, key, true);\n};\nvar decodeURIComponent_ = decodeURIComponent;\nexport {\n checkOptionalParameter,\n decodeURIComponent_,\n getPath,\n getPathNoStrict,\n getPattern,\n getQueryParam,\n getQueryParams,\n getQueryStrings,\n mergePath,\n splitPath,\n splitRoutingPath,\n tryDecode,\n tryDecodeURI\n};\n", "// src/request.ts\nimport { HTTPException } from \"./http-exception.js\";\nimport { GET_MATCH_RESULT } from \"./request/constants.js\";\nimport { parseBody } from \"./utils/body.js\";\nimport { decodeURIComponent_, getQueryParam, getQueryParams, tryDecode } from \"./utils/url.js\";\nvar tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);\nvar HonoRequest = class {\n /**\n * `.raw` can get the raw Request object.\n *\n * @see {@link https://hono.dev/docs/api/request#raw}\n *\n * @example\n * ```ts\n * // For Cloudflare Workers\n * app.post('/', async (c) => {\n * const metadata = c.req.raw.cf?.hostMetadata?\n * ...\n * })\n * ```\n */\n raw;\n #validatedData;\n // Short name of validatedData\n #matchResult;\n routeIndex = 0;\n /**\n * `.path` can get the pathname of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#path}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const pathname = c.req.path // `/about/me`\n * })\n * ```\n */\n path;\n bodyCache = {};\n constructor(request, path = \"/\", matchResult = [[]]) {\n this.raw = request;\n this.path = path;\n this.#matchResult = matchResult;\n this.#validatedData = {};\n }\n param(key) {\n return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();\n }\n #getDecodedParam(key) {\n const paramKey = this.#matchResult[0][this.routeIndex][1][key];\n const param = this.#getParamValue(paramKey);\n return param && /\\%/.test(param) ? tryDecodeURIComponent(param) : param;\n }\n #getAllDecodedParams() {\n const decoded = {};\n const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);\n for (const key of keys) {\n const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);\n if (value !== void 0) {\n decoded[key] = /\\%/.test(value) ? tryDecodeURIComponent(value) : value;\n }\n }\n return decoded;\n }\n #getParamValue(paramKey) {\n return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;\n }\n query(key) {\n return getQueryParam(this.url, key);\n }\n queries(key) {\n return getQueryParams(this.url, key);\n }\n header(name) {\n if (name) {\n return this.raw.headers.get(name) ?? void 0;\n }\n const headerData = /* @__PURE__ */ Object.create(null);\n this.raw.headers.forEach((value, key) => {\n headerData[key] = value;\n });\n return headerData;\n }\n async parseBody(options) {\n return parseBody(this, options);\n }\n #cachedBody = (key) => {\n const { bodyCache, raw } = this;\n const cachedBody = bodyCache[key];\n if (cachedBody) {\n return cachedBody;\n }\n const anyCachedKey = Object.keys(bodyCache)[0];\n if (anyCachedKey) {\n return bodyCache[anyCachedKey].then((body) => {\n if (anyCachedKey === \"json\") {\n body = JSON.stringify(body);\n }\n return new Response(body)[key]();\n });\n }\n return bodyCache[key] = raw[key]();\n };\n /**\n * `.json()` can parse Request body of type `application/json`\n *\n * @see {@link https://hono.dev/docs/api/request#json}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.json()\n * })\n * ```\n */\n json() {\n return this.#cachedBody(\"text\").then((text) => JSON.parse(text));\n }\n /**\n * `.text()` can parse Request body of type `text/plain`\n *\n * @see {@link https://hono.dev/docs/api/request#text}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.text()\n * })\n * ```\n */\n text() {\n return this.#cachedBody(\"text\");\n }\n /**\n * `.arrayBuffer()` parse Request body as an `ArrayBuffer`\n *\n * @see {@link https://hono.dev/docs/api/request#arraybuffer}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.arrayBuffer()\n * })\n * ```\n */\n arrayBuffer() {\n return this.#cachedBody(\"arrayBuffer\");\n }\n /**\n * `.bytes()` parses the request body as a `Uint8Array`.\n *\n * @see {@link https://hono.dev/docs/api/request#bytes}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.bytes()\n * })\n * ```\n */\n bytes() {\n return this.#cachedBody(\"arrayBuffer\").then((buffer) => new Uint8Array(buffer));\n }\n /**\n * Parses the request body as a `Blob`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.blob();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#blob\n */\n blob() {\n return this.#cachedBody(\"blob\");\n }\n /**\n * Parses the request body as `FormData`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.formData();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#formdata\n */\n formData() {\n return this.#cachedBody(\"formData\");\n }\n /**\n * Adds validated data to the request.\n *\n * @param target - The target of the validation.\n * @param data - The validated data to add.\n */\n addValidatedData(target, data) {\n this.#validatedData[target] = data;\n }\n valid(target) {\n return this.#validatedData[target];\n }\n /**\n * `.url()` can get the request url strings.\n *\n * @see {@link https://hono.dev/docs/api/request#url}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const url = c.req.url // `http://localhost:8787/about/me`\n * ...\n * })\n * ```\n */\n get url() {\n return this.raw.url;\n }\n /**\n * `.method()` can get the method name of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#method}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const method = c.req.method // `GET`\n * })\n * ```\n */\n get method() {\n return this.raw.method;\n }\n get [GET_MATCH_RESULT]() {\n return this.#matchResult;\n }\n /**\n * `.matchedRoutes()` can return a matched route in the handler\n *\n * @deprecated\n *\n * Use matchedRoutes helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#matchedroutes}\n *\n * @example\n * ```ts\n * app.use('*', async function logger(c, next) {\n * await next()\n * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {\n * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')\n * console.log(\n * method,\n * ' ',\n * path,\n * ' '.repeat(Math.max(10 - path.length, 0)),\n * name,\n * i === c.req.routeIndex ? '<- respond from here' : ''\n * )\n * })\n * })\n * ```\n */\n get matchedRoutes() {\n return this.#matchResult[0].map(([[, route]]) => route);\n }\n /**\n * `routePath()` can retrieve the path registered within the handler\n *\n * @deprecated\n *\n * Use routePath helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#routepath}\n *\n * @example\n * ```ts\n * app.get('/posts/:id', (c) => {\n * return c.json({ path: c.req.routePath })\n * })\n * ```\n */\n get routePath() {\n return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;\n }\n};\nvar cloneRawRequest = async (req) => {\n if (!req.raw.bodyUsed) {\n return req.raw.clone();\n }\n const cacheKey = Object.keys(req.bodyCache)[0];\n if (!cacheKey) {\n throw new HTTPException(500, {\n message: \"Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly.\"\n });\n }\n const body = await req[cacheKey]();\n const headers = req.header();\n if (body instanceof FormData) {\n delete headers[\"content-type\"];\n }\n const requestInit = {\n body,\n cache: req.raw.cache,\n credentials: req.raw.credentials,\n headers,\n integrity: req.raw.integrity,\n keepalive: req.raw.keepalive,\n method: req.method,\n mode: req.raw.mode,\n redirect: req.raw.redirect,\n referrer: req.raw.referrer,\n referrerPolicy: req.raw.referrerPolicy,\n signal: req.raw.signal\n };\n return new Request(req.url, requestInit);\n};\nexport {\n HonoRequest,\n cloneRawRequest\n};\n", "// src/utils/html.ts\nvar HtmlEscapedCallbackPhase = {\n Stringify: 1,\n BeforeStream: 2,\n Stream: 3\n};\nvar raw = (value, callbacks) => {\n const escapedString = new String(value);\n escapedString.isEscaped = true;\n escapedString.callbacks = callbacks;\n return escapedString;\n};\nvar escapeRe = /[&<>'\"]/;\nvar stringBufferToString = async (buffer, callbacks) => {\n let str = \"\";\n callbacks ||= [];\n const resolvedBuffer = await Promise.all(buffer);\n for (let i = resolvedBuffer.length - 1; ; i--) {\n str += resolvedBuffer[i];\n i--;\n if (i < 0) {\n break;\n }\n let r = resolvedBuffer[i];\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n const isEscaped = r.isEscaped;\n r = await (typeof r === \"object\" ? r.toString() : r);\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n if (r.isEscaped ?? isEscaped) {\n str += r;\n } else {\n const buf = [str];\n escapeToBuffer(r, buf);\n str = buf[0];\n }\n }\n return raw(str, callbacks);\n};\nvar escapeToBuffer = (str, buffer) => {\n const match = str.search(escapeRe);\n if (match === -1) {\n buffer[0] += str;\n return;\n }\n let escape;\n let index;\n let lastIndex = 0;\n for (index = match; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n escape = \""\";\n break;\n case 39:\n escape = \"'\";\n break;\n case 38:\n escape = \"&\";\n break;\n case 60:\n escape = \"<\";\n break;\n case 62:\n escape = \">\";\n break;\n default:\n continue;\n }\n buffer[0] += str.substring(lastIndex, index) + escape;\n lastIndex = index + 1;\n }\n buffer[0] += str.substring(lastIndex, index);\n};\nvar resolveCallbackSync = (str) => {\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return str;\n }\n const buffer = [str];\n const context = {};\n callbacks.forEach((c) => c({ phase: HtmlEscapedCallbackPhase.Stringify, buffer, context }));\n return buffer[0];\n};\nvar resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {\n if (typeof str === \"object\" && !(str instanceof String)) {\n if (!(str instanceof Promise)) {\n str = str.toString();\n }\n if (str instanceof Promise) {\n str = await str;\n }\n }\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return Promise.resolve(str);\n }\n if (buffer) {\n buffer[0] += str;\n } else {\n buffer = [str];\n }\n const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(\n (res) => Promise.all(\n res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))\n ).then(() => buffer[0])\n );\n if (preserveCallbacks) {\n return raw(await resStr, callbacks);\n } else {\n return resStr;\n }\n};\nexport {\n HtmlEscapedCallbackPhase,\n escapeToBuffer,\n raw,\n resolveCallback,\n resolveCallbackSync,\n stringBufferToString\n};\n", "// src/context.ts\nimport { HonoRequest } from \"./request.js\";\nimport { HtmlEscapedCallbackPhase, resolveCallback } from \"./utils/html.js\";\nvar TEXT_PLAIN = \"text/plain; charset=UTF-8\";\nvar setDefaultContentType = (contentType, headers) => {\n return {\n \"Content-Type\": contentType,\n ...headers\n };\n};\nvar createResponseInstance = (body, init) => new Response(body, init);\nvar Context = class {\n #rawRequest;\n #req;\n /**\n * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.\n *\n * @see {@link https://hono.dev/docs/api/context#env}\n *\n * @example\n * ```ts\n * // Environment object for Cloudflare Workers\n * app.get('*', async c => {\n * const counter = c.env.COUNTER\n * })\n * ```\n */\n env = {};\n #var;\n finalized = false;\n /**\n * `.error` can get the error object from the middleware if the Handler throws an error.\n *\n * @see {@link https://hono.dev/docs/api/context#error}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * await next()\n * if (c.error) {\n * // do something...\n * }\n * })\n * ```\n */\n error;\n #status;\n #executionCtx;\n #res;\n #layout;\n #renderer;\n #notFoundHandler;\n #preparedHeaders;\n #matchResult;\n #path;\n /**\n * Creates an instance of the Context class.\n *\n * @param req - The Request object.\n * @param options - Optional configuration options for the context.\n */\n constructor(req, options) {\n this.#rawRequest = req;\n if (options) {\n this.#executionCtx = options.executionCtx;\n this.env = options.env;\n this.#notFoundHandler = options.notFoundHandler;\n this.#path = options.path;\n this.#matchResult = options.matchResult;\n }\n }\n /**\n * `.req` is the instance of {@link HonoRequest}.\n */\n get req() {\n this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);\n return this.#req;\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#event}\n * The FetchEvent associated with the current request.\n *\n * @throws Will throw an error if the context does not have a FetchEvent.\n */\n get event() {\n if (this.#executionCtx && \"respondWith\" in this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no FetchEvent\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#executionctx}\n * The ExecutionContext associated with the current request.\n *\n * @throws Will throw an error if the context does not have an ExecutionContext.\n */\n get executionCtx() {\n if (this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no ExecutionContext\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#res}\n * The Response object for the current request.\n */\n get res() {\n return this.#res ||= createResponseInstance(null, {\n headers: this.#preparedHeaders ??= new Headers()\n });\n }\n /**\n * Sets the Response object for the current request.\n *\n * @param _res - The Response object to set.\n */\n set res(_res) {\n if (this.#res && _res) {\n _res = createResponseInstance(_res.body, _res);\n for (const [k, v] of this.#res.headers.entries()) {\n if (k === \"content-type\") {\n continue;\n }\n if (k === \"set-cookie\") {\n const cookies = this.#res.headers.getSetCookie();\n _res.headers.delete(\"set-cookie\");\n for (const cookie of cookies) {\n _res.headers.append(\"set-cookie\", cookie);\n }\n } else {\n _res.headers.set(k, v);\n }\n }\n }\n this.#res = _res;\n this.finalized = true;\n }\n /**\n * `.render()` can create a response within a layout.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * return c.render('Hello!')\n * })\n * ```\n */\n render = (...args) => {\n this.#renderer ??= (content) => this.html(content);\n return this.#renderer(...args);\n };\n /**\n * Sets the layout for the response.\n *\n * @param layout - The layout to set.\n * @returns The layout function.\n */\n setLayout = (layout) => this.#layout = layout;\n /**\n * Gets the current layout for the response.\n *\n * @returns The current layout function.\n */\n getLayout = () => this.#layout;\n /**\n * `.setRenderer()` can set the layout in the custom middleware.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```tsx\n * app.use('*', async (c, next) => {\n * c.setRenderer((content) => {\n * return c.html(\n * <html>\n * <body>\n * <p>{content}</p>\n * </body>\n * </html>\n * )\n * })\n * await next()\n * })\n * ```\n */\n setRenderer = (renderer) => {\n this.#renderer = renderer;\n };\n /**\n * `.header()` can set headers.\n *\n * @see {@link https://hono.dev/docs/api/context#header}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n *\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n header = (name, value, options) => {\n if (this.finalized) {\n this.#res = createResponseInstance(this.#res.body, this.#res);\n }\n const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();\n if (value === void 0) {\n headers.delete(name);\n } else if (options?.append) {\n headers.append(name, value);\n } else {\n headers.set(name, value);\n }\n };\n status = (status) => {\n this.#status = status;\n };\n /**\n * `.set()` can set the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * c.set('message', 'Hono is hot!!')\n * await next()\n * })\n * ```\n */\n set = (key, value) => {\n this.#var ??= /* @__PURE__ */ new Map();\n this.#var.set(key, value);\n };\n /**\n * `.get()` can use the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * const message = c.get('message')\n * return c.text(`The message is \"${message}\"`)\n * })\n * ```\n */\n get = (key) => {\n return this.#var ? this.#var.get(key) : void 0;\n };\n /**\n * `.var` can access the value of a variable.\n *\n * @see {@link https://hono.dev/docs/api/context#var}\n *\n * @example\n * ```ts\n * const result = c.var.client.oneMethod()\n * ```\n */\n // c.var.propName is a read-only\n get var() {\n if (!this.#var) {\n return {};\n }\n return Object.fromEntries(this.#var);\n }\n #newResponse(data, arg, headers) {\n const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();\n if (typeof arg === \"object\" && \"headers\" in arg) {\n const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);\n for (const [key, value] of argHeaders) {\n if (key.toLowerCase() === \"set-cookie\") {\n responseHeaders.append(key, value);\n } else {\n responseHeaders.set(key, value);\n }\n }\n }\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (typeof v === \"string\") {\n responseHeaders.set(k, v);\n } else {\n responseHeaders.delete(k);\n for (const v2 of v) {\n responseHeaders.append(k, v2);\n }\n }\n }\n }\n const status = typeof arg === \"number\" ? arg : arg?.status ?? this.#status;\n return createResponseInstance(data, { status, headers: responseHeaders });\n }\n newResponse = (...args) => this.#newResponse(...args);\n /**\n * `.body()` can return the HTTP response.\n * You can set headers with `.header()` and set HTTP status code with `.status`.\n * This can also be set in `.text()`, `.json()` and so on.\n *\n * @see {@link https://hono.dev/docs/api/context#body}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n * // Set HTTP status code\n * c.status(201)\n *\n * // Return the response body\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n body = (data, arg, headers) => this.#newResponse(data, arg, headers);\n /**\n * `.text()` can render text as `Content-Type:text/plain`.\n *\n * @see {@link https://hono.dev/docs/api/context#text}\n *\n * @example\n * ```ts\n * app.get('/say', (c) => {\n * return c.text('Hello!')\n * })\n * ```\n */\n text = (text, arg, headers) => {\n return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(\n text,\n arg,\n setDefaultContentType(TEXT_PLAIN, headers)\n );\n };\n /**\n * `.json()` can render JSON as `Content-Type:application/json`.\n *\n * @see {@link https://hono.dev/docs/api/context#json}\n *\n * @example\n * ```ts\n * app.get('/api', (c) => {\n * return c.json({ message: 'Hello!' })\n * })\n * ```\n */\n json = (object, arg, headers) => {\n return this.#newResponse(\n JSON.stringify(object),\n arg,\n setDefaultContentType(\"application/json\", headers)\n );\n };\n html = (html, arg, headers) => {\n const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType(\"text/html; charset=UTF-8\", headers));\n return typeof html === \"object\" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);\n };\n /**\n * `.redirect()` can Redirect, default status code is 302.\n *\n * @see {@link https://hono.dev/docs/api/context#redirect}\n *\n * @example\n * ```ts\n * app.get('/redirect', (c) => {\n * return c.redirect('/')\n * })\n * app.get('/redirect-permanently', (c) => {\n * return c.redirect('/', 301)\n * })\n * ```\n */\n redirect = (location, status) => {\n const locationString = String(location);\n this.header(\n \"Location\",\n // Multibyes should be encoded\n // eslint-disable-next-line no-control-regex\n !/[^\\x00-\\xFF]/.test(locationString) ? locationString : encodeURI(locationString)\n );\n return this.newResponse(null, status ?? 302);\n };\n /**\n * `.notFound()` can return the Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/context#notfound}\n *\n * @example\n * ```ts\n * app.get('/notfound', (c) => {\n * return c.notFound()\n * })\n * ```\n */\n notFound = () => {\n this.#notFoundHandler ??= () => createResponseInstance();\n return this.#notFoundHandler(this);\n };\n};\nexport {\n Context,\n TEXT_PLAIN\n};\n", "// src/router.ts\nvar METHOD_NAME_ALL = \"ALL\";\nvar METHOD_NAME_ALL_LOWERCASE = \"all\";\nvar METHODS = [\"get\", \"post\", \"put\", \"delete\", \"options\", \"patch\"];\nvar MESSAGE_MATCHER_IS_ALREADY_BUILT = \"Can not add a route since the matcher is already built.\";\nvar UnsupportedPathError = class extends Error {\n};\nexport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHODS,\n METHOD_NAME_ALL,\n METHOD_NAME_ALL_LOWERCASE,\n UnsupportedPathError\n};\n", "// src/utils/constants.ts\nvar COMPOSED_HANDLER = \"__COMPOSED_HANDLER\";\nexport {\n COMPOSED_HANDLER\n};\n", "// src/hono-base.ts\nimport { compose } from \"./compose.js\";\nimport { Context } from \"./context.js\";\nimport { METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE } from \"./router.js\";\nimport { COMPOSED_HANDLER } from \"./utils/constants.js\";\nimport { getPath, getPathNoStrict, mergePath } from \"./utils/url.js\";\nvar notFoundHandler = (c) => {\n return c.text(\"404 Not Found\", 404);\n};\nvar errorHandler = (err, c) => {\n if (\"getResponse\" in err) {\n const res = err.getResponse();\n return c.newResponse(res.body, res);\n }\n console.error(err);\n return c.text(\"Internal Server Error\", 500);\n};\nvar Hono = class _Hono {\n get;\n post;\n put;\n delete;\n options;\n patch;\n all;\n on;\n use;\n /*\n This class is like an abstract class and does not have a router.\n To use it, inherit the class and implement router in the constructor.\n */\n router;\n getPath;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n _basePath = \"/\";\n #path = \"/\";\n routes = [];\n constructor(options = {}) {\n const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];\n allMethods.forEach((method) => {\n this[method] = (args1, ...args) => {\n if (typeof args1 === \"string\") {\n this.#path = args1;\n } else {\n this.#addRoute(method, this.#path, args1);\n }\n args.forEach((handler) => {\n this.#addRoute(method, this.#path, handler);\n });\n return this;\n };\n });\n this.on = (method, path, ...handlers) => {\n for (const p of [path].flat()) {\n this.#path = p;\n for (const m of [method].flat()) {\n handlers.map((handler) => {\n this.#addRoute(m.toUpperCase(), this.#path, handler);\n });\n }\n }\n return this;\n };\n this.use = (arg1, ...handlers) => {\n if (typeof arg1 === \"string\") {\n this.#path = arg1;\n } else {\n this.#path = \"*\";\n handlers.unshift(arg1);\n }\n handlers.forEach((handler) => {\n this.#addRoute(METHOD_NAME_ALL, this.#path, handler);\n });\n return this;\n };\n const { strict, ...optionsWithoutStrict } = options;\n Object.assign(this, optionsWithoutStrict);\n this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;\n }\n #clone() {\n const clone = new _Hono({\n router: this.router,\n getPath: this.getPath\n });\n clone.errorHandler = this.errorHandler;\n clone.#notFoundHandler = this.#notFoundHandler;\n clone.routes = this.routes;\n return clone;\n }\n #notFoundHandler = notFoundHandler;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n errorHandler = errorHandler;\n /**\n * `.route()` allows grouping other Hono instance in routes.\n *\n * @see {@link https://hono.dev/docs/api/routing#grouping}\n *\n * @param {string} path - base Path\n * @param {Hono} app - other Hono instance\n * @returns {Hono} routed Hono instance\n *\n * @example\n * ```ts\n * const app = new Hono()\n * const app2 = new Hono()\n *\n * app2.get(\"/user\", (c) => c.text(\"user\"))\n * app.route(\"/api\", app2) // GET /api/user\n * ```\n */\n route(path, app) {\n const subApp = this.basePath(path);\n app.routes.map((r) => {\n let handler;\n if (app.errorHandler === errorHandler) {\n handler = r.handler;\n } else {\n handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;\n handler[COMPOSED_HANDLER] = r.handler;\n }\n subApp.#addRoute(r.method, r.path, handler, r.basePath);\n });\n return this;\n }\n /**\n * `.basePath()` allows base paths to be specified.\n *\n * @see {@link https://hono.dev/docs/api/routing#base-path}\n *\n * @param {string} path - base Path\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * const api = new Hono().basePath('/api')\n * ```\n */\n basePath(path) {\n const subApp = this.#clone();\n subApp._basePath = mergePath(this._basePath, path);\n return subApp;\n }\n /**\n * `.onError()` handles an error and returns a customized Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#error-handling}\n *\n * @param {ErrorHandler} handler - request Handler for error\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.onError((err, c) => {\n * console.error(`${err}`)\n * return c.text('Custom Error Message', 500)\n * })\n * ```\n */\n onError = (handler) => {\n this.errorHandler = handler;\n return this;\n };\n /**\n * `.notFound()` allows you to customize a Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#not-found}\n *\n * @param {NotFoundHandler} handler - request handler for not-found\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.notFound((c) => {\n * return c.text('Custom 404 Message', 404)\n * })\n * ```\n */\n notFound = (handler) => {\n this.#notFoundHandler = handler;\n return this;\n };\n /**\n * `.mount()` allows you to mount applications built with other frameworks into your Hono application.\n *\n * @see {@link https://hono.dev/docs/api/hono#mount}\n *\n * @param {string} path - base Path\n * @param {Function} applicationHandler - other Request Handler\n * @param {MountOptions} [options] - options of `.mount()`\n * @returns {Hono} mounted Hono instance\n *\n * @example\n * ```ts\n * import { Router as IttyRouter } from 'itty-router'\n * import { Hono } from 'hono'\n * // Create itty-router application\n * const ittyRouter = IttyRouter()\n * // GET /itty-router/hello\n * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))\n *\n * const app = new Hono()\n * app.mount('/itty-router', ittyRouter.handle)\n * ```\n *\n * @example\n * ```ts\n * const app = new Hono()\n * // Send the request to another application without modification.\n * app.mount('/app', anotherApp, {\n * replaceRequest: (req) => req,\n * })\n * ```\n */\n mount(path, applicationHandler, options) {\n let replaceRequest;\n let optionHandler;\n if (options) {\n if (typeof options === \"function\") {\n optionHandler = options;\n } else {\n optionHandler = options.optionHandler;\n if (options.replaceRequest === false) {\n replaceRequest = (request) => request;\n } else {\n replaceRequest = options.replaceRequest;\n }\n }\n }\n const getOptions = optionHandler ? (c) => {\n const options2 = optionHandler(c);\n return Array.isArray(options2) ? options2 : [options2];\n } : (c) => {\n let executionContext = void 0;\n try {\n executionContext = c.executionCtx;\n } catch {\n }\n return [c.env, executionContext];\n };\n replaceRequest ||= (() => {\n const mergedPath = mergePath(this._basePath, path);\n const pathPrefixLength = mergedPath === \"/\" ? 0 : mergedPath.length;\n return (request) => {\n const url = new URL(request.url);\n url.pathname = this.getPath(request).slice(pathPrefixLength) || \"/\";\n return new Request(url, request);\n };\n })();\n const handler = async (c, next) => {\n const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));\n if (res) {\n return res;\n }\n await next();\n };\n this.#addRoute(METHOD_NAME_ALL, mergePath(path, \"*\"), handler);\n return this;\n }\n #addRoute(method, path, handler, baseRoutePath) {\n method = method.toUpperCase();\n path = mergePath(this._basePath, path);\n const r = {\n basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,\n path,\n method,\n handler\n };\n this.router.add(method, path, [handler, r]);\n this.routes.push(r);\n }\n #handleError(err, c) {\n if (err instanceof Error) {\n return this.errorHandler(err, c);\n }\n throw err;\n }\n #dispatch(request, executionCtx, env, method) {\n if (method === \"HEAD\") {\n return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, \"GET\")))();\n }\n const path = this.getPath(request, { env });\n const matchResult = this.router.match(method, path);\n const c = new Context(request, {\n path,\n matchResult,\n env,\n executionCtx,\n notFoundHandler: this.#notFoundHandler\n });\n if (matchResult[0].length === 1) {\n let res;\n try {\n res = matchResult[0][0][0][0](c, async () => {\n c.res = await this.#notFoundHandler(c);\n });\n } catch (err) {\n return this.#handleError(err, c);\n }\n return res instanceof Promise ? res.then(\n (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))\n ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);\n }\n const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);\n return (async () => {\n try {\n const context = await composed(c);\n if (!context.finalized) {\n throw new Error(\n \"Context is not finalized. Did you forget to return a Response object or `await next()`?\"\n );\n }\n return context.res;\n } catch (err) {\n return this.#handleError(err, c);\n }\n })();\n }\n /**\n * `.fetch()` will be entry point of your app.\n *\n * @see {@link https://hono.dev/docs/api/hono#fetch}\n *\n * @param {Request} request - request Object of request\n * @param {Env} Env - env Object\n * @param {ExecutionContext} - context of execution\n * @returns {Response | Promise<Response>} response of request\n *\n */\n fetch = (request, ...rest) => {\n return this.#dispatch(request, rest[1], rest[0], request.method);\n };\n /**\n * `.request()` is a useful method for testing.\n * You can pass a URL or pathname to send a GET request.\n * app will return a Response object.\n * ```ts\n * test('GET /hello is ok', async () => {\n * const res = await app.request('/hello')\n * expect(res.status).toBe(200)\n * })\n * ```\n * @see https://hono.dev/docs/api/hono#request\n */\n request = (input, requestInit, Env, executionCtx) => {\n if (input instanceof Request) {\n return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);\n }\n input = input.toString();\n return this.fetch(\n new Request(\n /^https?:\\/\\//.test(input) ? input : `http://localhost${mergePath(\"/\", input)}`,\n requestInit\n ),\n Env,\n executionCtx\n );\n };\n /**\n * `.fire()` automatically adds a global fetch event listener.\n * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.\n * @deprecated\n * Use `fire` from `hono/service-worker` instead.\n * ```ts\n * import { Hono } from 'hono'\n * import { fire } from 'hono/service-worker'\n *\n * const app = new Hono()\n * // ...\n * fire(app)\n * ```\n * @see https://hono.dev/docs/api/hono#fire\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API\n * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/\n */\n fire = () => {\n addEventListener(\"fetch\", (event) => {\n event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));\n });\n };\n};\nexport {\n Hono as HonoBase\n};\n", "// src/router/reg-exp-router/matcher.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nvar emptyParam = [];\nfunction match(method, path) {\n const matchers = this.buildAllMatchers();\n const match2 = ((method2, path2) => {\n const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];\n const staticMatch = matcher[2][path2];\n if (staticMatch) {\n return staticMatch;\n }\n const match3 = path2.match(matcher[0]);\n if (!match3) {\n return [[], emptyParam];\n }\n const index = match3.indexOf(\"\", 1);\n return [matcher[1][index], match3];\n });\n this.match = match2;\n return match2(method, path);\n}\nexport {\n emptyParam,\n match\n};\n", "// src/router/reg-exp-router/node.ts\nvar LABEL_REG_EXP_STR = \"[^/]+\";\nvar ONLY_WILDCARD_REG_EXP_STR = \".*\";\nvar TAIL_WILDCARD_REG_EXP_STR = \"(?:|/.*)\";\nvar PATH_ERROR = /* @__PURE__ */ Symbol();\nvar regExpMetaChars = new Set(\".\\\\+*[^]$()\");\nfunction compareKey(a, b) {\n if (a.length === 1) {\n return b.length === 1 ? a < b ? -1 : 1 : -1;\n }\n if (b.length === 1) {\n return 1;\n }\n if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {\n return 1;\n } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {\n return -1;\n }\n if (a === LABEL_REG_EXP_STR) {\n return 1;\n } else if (b === LABEL_REG_EXP_STR) {\n return -1;\n }\n return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;\n}\nvar Node = class _Node {\n #index;\n #varIndex;\n #children = /* @__PURE__ */ Object.create(null);\n insert(tokens, index, paramMap, context, pathErrorCheckOnly) {\n if (tokens.length === 0) {\n if (this.#index !== void 0) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n this.#index = index;\n return;\n }\n const [token, ...restTokens] = tokens;\n const pattern = token === \"*\" ? restTokens.length === 0 ? [\"\", \"\", ONLY_WILDCARD_REG_EXP_STR] : [\"\", \"\", LABEL_REG_EXP_STR] : token === \"/*\" ? [\"\", \"\", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n let node;\n if (pattern) {\n const name = pattern[1];\n let regexpStr = pattern[2] || LABEL_REG_EXP_STR;\n if (name && pattern[2]) {\n if (regexpStr === \".*\") {\n throw PATH_ERROR;\n }\n regexpStr = regexpStr.replace(/^\\((?!\\?:)(?=[^)]+\\)$)/, \"(?:\");\n if (/\\((?!\\?:)/.test(regexpStr)) {\n throw PATH_ERROR;\n }\n }\n node = this.#children[regexpStr];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[regexpStr] = new _Node();\n if (name !== \"\") {\n node.#varIndex = context.varIndex++;\n }\n }\n if (!pathErrorCheckOnly && name !== \"\") {\n paramMap.push([name, node.#varIndex]);\n }\n } else {\n node = this.#children[token];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[token] = new _Node();\n }\n }\n node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);\n }\n buildRegExpStr() {\n const childKeys = Object.keys(this.#children).sort(compareKey);\n const strList = childKeys.map((k) => {\n const c = this.#children[k];\n return (typeof c.#varIndex === \"number\" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\\\${k}` : k) + c.buildRegExpStr();\n });\n if (typeof this.#index === \"number\") {\n strList.unshift(`#${this.#index}`);\n }\n if (strList.length === 0) {\n return \"\";\n }\n if (strList.length === 1) {\n return strList[0];\n }\n return \"(?:\" + strList.join(\"|\") + \")\";\n }\n};\nexport {\n Node,\n PATH_ERROR\n};\n", "// src/router/reg-exp-router/trie.ts\nimport { Node } from \"./node.js\";\nvar Trie = class {\n #context = { varIndex: 0 };\n #root = new Node();\n insert(path, index, pathErrorCheckOnly) {\n const paramAssoc = [];\n const groups = [];\n for (let i = 0; ; ) {\n let replaced = false;\n path = path.replace(/\\{[^}]+\\}/g, (m) => {\n const mark = `@\\\\${i}`;\n groups[i] = [mark, m];\n i++;\n replaced = true;\n return mark;\n });\n if (!replaced) {\n break;\n }\n }\n const tokens = path.match(/(?::[^\\/]+)|(?:\\/\\*$)|./g) || [];\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = tokens.length - 1; j >= 0; j--) {\n if (tokens[j].indexOf(mark) !== -1) {\n tokens[j] = tokens[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);\n return paramAssoc;\n }\n buildRegExp() {\n let regexp = this.#root.buildRegExpStr();\n if (regexp === \"\") {\n return [/^$/, [], []];\n }\n let captureIndex = 0;\n const indexReplacementMap = [];\n const paramReplacementMap = [];\n regexp = regexp.replace(/#(\\d+)|@(\\d+)|\\.\\*\\$/g, (_, handlerIndex, paramIndex) => {\n if (handlerIndex !== void 0) {\n indexReplacementMap[++captureIndex] = Number(handlerIndex);\n return \"$()\";\n }\n if (paramIndex !== void 0) {\n paramReplacementMap[Number(paramIndex)] = ++captureIndex;\n return \"\";\n }\n return \"\";\n });\n return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];\n }\n};\nexport {\n Trie\n};\n", "// src/router/reg-exp-router/router.ts\nimport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHOD_NAME_ALL,\n UnsupportedPathError\n} from \"../../router.js\";\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { match, emptyParam } from \"./matcher.js\";\nimport { PATH_ERROR } from \"./node.js\";\nimport { Trie } from \"./trie.js\";\nvar nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];\nvar wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\nfunction buildWildcardRegExp(path) {\n return wildcardRegExpCache[path] ??= new RegExp(\n path === \"*\" ? \"\" : `^${path.replace(\n /\\/\\*$|([.\\\\+*[^\\]$()])/g,\n (_, metaChar) => metaChar ? `\\\\${metaChar}` : \"(?:|/.*)\"\n )}$`\n );\n}\nfunction clearWildcardRegExpCache() {\n wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\n}\nfunction buildMatcherFromPreprocessedRoutes(routes) {\n const trie = new Trie();\n const handlerData = [];\n if (routes.length === 0) {\n return nullMatcher;\n }\n const routesWithStaticPathFlag = routes.map(\n (route) => [!/\\*|\\/:/.test(route[0]), ...route]\n ).sort(\n ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length\n );\n const staticMap = /* @__PURE__ */ Object.create(null);\n for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {\n const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];\n if (pathErrorCheckOnly) {\n staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];\n } else {\n j++;\n }\n let paramAssoc;\n try {\n paramAssoc = trie.insert(path, j, pathErrorCheckOnly);\n } catch (e) {\n throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;\n }\n if (pathErrorCheckOnly) {\n continue;\n }\n handlerData[j] = handlers.map(([h, paramCount]) => {\n const paramIndexMap = /* @__PURE__ */ Object.create(null);\n paramCount -= 1;\n for (; paramCount >= 0; paramCount--) {\n const [key, value] = paramAssoc[paramCount];\n paramIndexMap[key] = value;\n }\n return [h, paramIndexMap];\n });\n }\n const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();\n for (let i = 0, len = handlerData.length; i < len; i++) {\n for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {\n const map = handlerData[i][j]?.[1];\n if (!map) {\n continue;\n }\n const keys = Object.keys(map);\n for (let k = 0, len3 = keys.length; k < len3; k++) {\n map[keys[k]] = paramReplacementMap[map[keys[k]]];\n }\n }\n }\n const handlerMap = [];\n for (const i in indexReplacementMap) {\n handlerMap[i] = handlerData[indexReplacementMap[i]];\n }\n return [regexp, handlerMap, staticMap];\n}\nfunction findMiddleware(middleware, path) {\n if (!middleware) {\n return void 0;\n }\n for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {\n if (buildWildcardRegExp(k).test(path)) {\n return [...middleware[k]];\n }\n }\n return void 0;\n}\nvar RegExpRouter = class {\n name = \"RegExpRouter\";\n #middleware;\n #routes;\n constructor() {\n this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n }\n add(method, path, handler) {\n const middleware = this.#middleware;\n const routes = this.#routes;\n if (!middleware || !routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n if (!middleware[method]) {\n ;\n [middleware, routes].forEach((handlerMap) => {\n handlerMap[method] = /* @__PURE__ */ Object.create(null);\n Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {\n handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];\n });\n });\n }\n if (path === \"/*\") {\n path = \"*\";\n }\n const paramCount = (path.match(/\\/:/g) || []).length;\n if (/\\*$/.test(path)) {\n const re = buildWildcardRegExp(path);\n if (method === METHOD_NAME_ALL) {\n Object.keys(middleware).forEach((m) => {\n middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n });\n } else {\n middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n }\n Object.keys(middleware).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(middleware[m]).forEach((p) => {\n re.test(p) && middleware[m][p].push([handler, paramCount]);\n });\n }\n });\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(routes[m]).forEach(\n (p) => re.test(p) && routes[m][p].push([handler, paramCount])\n );\n }\n });\n return;\n }\n const paths = checkOptionalParameter(path) || [path];\n for (let i = 0, len = paths.length; i < len; i++) {\n const path2 = paths[i];\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n routes[m][path2] ||= [\n ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []\n ];\n routes[m][path2].push([handler, paramCount - len + i + 1]);\n }\n });\n }\n }\n match = match;\n buildAllMatchers() {\n const matchers = /* @__PURE__ */ Object.create(null);\n Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {\n matchers[method] ||= this.#buildMatcher(method);\n });\n this.#middleware = this.#routes = void 0;\n clearWildcardRegExpCache();\n return matchers;\n }\n #buildMatcher(method) {\n const routes = [];\n let hasOwnRoute = method === METHOD_NAME_ALL;\n [this.#middleware, this.#routes].forEach((r) => {\n const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];\n if (ownRoute.length !== 0) {\n hasOwnRoute ||= true;\n routes.push(...ownRoute);\n } else if (method !== METHOD_NAME_ALL) {\n routes.push(\n ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])\n );\n }\n });\n if (!hasOwnRoute) {\n return null;\n } else {\n return buildMatcherFromPreprocessedRoutes(routes);\n }\n }\n};\nexport {\n RegExpRouter\n};\n", "// src/router/smart-router/router.ts\nimport { MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError } from \"../../router.js\";\nvar SmartRouter = class {\n name = \"SmartRouter\";\n #routers = [];\n #routes = [];\n constructor(init) {\n this.#routers = init.routers;\n }\n add(method, path, handler) {\n if (!this.#routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n this.#routes.push([method, path, handler]);\n }\n match(method, path) {\n if (!this.#routes) {\n throw new Error(\"Fatal error\");\n }\n const routers = this.#routers;\n const routes = this.#routes;\n const len = routers.length;\n let i = 0;\n let res;\n for (; i < len; i++) {\n const router = routers[i];\n try {\n for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {\n router.add(...routes[i2]);\n }\n res = router.match(method, path);\n } catch (e) {\n if (e instanceof UnsupportedPathError) {\n continue;\n }\n throw e;\n }\n this.match = router.match.bind(router);\n this.#routers = [router];\n this.#routes = void 0;\n break;\n }\n if (i === len) {\n throw new Error(\"Fatal error\");\n }\n this.name = `SmartRouter + ${this.activeRouter.name}`;\n return res;\n }\n get activeRouter() {\n if (this.#routes || this.#routers.length !== 1) {\n throw new Error(\"No active router has been determined yet.\");\n }\n return this.#routers[0];\n }\n};\nexport {\n SmartRouter\n};\n", "// src/router/trie-router/node.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nimport { getPattern, splitPath, splitRoutingPath } from \"../../utils/url.js\";\nvar emptyParams = /* @__PURE__ */ Object.create(null);\nvar hasChildren = (children) => {\n for (const _ in children) {\n return true;\n }\n return false;\n};\nvar Node = class _Node {\n #methods;\n #children;\n #patterns;\n #order = 0;\n #params = emptyParams;\n constructor(method, handler, children) {\n this.#children = children || /* @__PURE__ */ Object.create(null);\n this.#methods = [];\n if (method && handler) {\n const m = /* @__PURE__ */ Object.create(null);\n m[method] = { handler, possibleKeys: [], score: 0 };\n this.#methods = [m];\n }\n this.#patterns = [];\n }\n insert(method, path, handler) {\n this.#order = ++this.#order;\n let curNode = this;\n const parts = splitRoutingPath(path);\n const possibleKeys = [];\n for (let i = 0, len = parts.length; i < len; i++) {\n const p = parts[i];\n const nextP = parts[i + 1];\n const pattern = getPattern(p, nextP);\n const key = Array.isArray(pattern) ? pattern[0] : p;\n if (key in curNode.#children) {\n curNode = curNode.#children[key];\n if (pattern) {\n possibleKeys.push(pattern[1]);\n }\n continue;\n }\n curNode.#children[key] = new _Node();\n if (pattern) {\n curNode.#patterns.push(pattern);\n possibleKeys.push(pattern[1]);\n }\n curNode = curNode.#children[key];\n }\n curNode.#methods.push({\n [method]: {\n handler,\n possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),\n score: this.#order\n }\n });\n return curNode;\n }\n #pushHandlerSets(handlerSets, node, method, nodeParams, params) {\n for (let i = 0, len = node.#methods.length; i < len; i++) {\n const m = node.#methods[i];\n const handlerSet = m[method] || m[METHOD_NAME_ALL];\n const processedSet = {};\n if (handlerSet !== void 0) {\n handlerSet.params = /* @__PURE__ */ Object.create(null);\n handlerSets.push(handlerSet);\n if (nodeParams !== emptyParams || params && params !== emptyParams) {\n for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {\n const key = handlerSet.possibleKeys[i2];\n const processed = processedSet[handlerSet.score];\n handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];\n processedSet[handlerSet.score] = true;\n }\n }\n }\n }\n }\n search(method, path) {\n const handlerSets = [];\n this.#params = emptyParams;\n const curNode = this;\n let curNodes = [curNode];\n const parts = splitPath(path);\n const curNodesQueue = [];\n const len = parts.length;\n let partOffsets = null;\n for (let i = 0; i < len; i++) {\n const part = parts[i];\n const isLast = i === len - 1;\n const tempNodes = [];\n for (let j = 0, len2 = curNodes.length; j < len2; j++) {\n const node = curNodes[j];\n const nextNode = node.#children[part];\n if (nextNode) {\n nextNode.#params = node.#params;\n if (isLast) {\n if (nextNode.#children[\"*\"]) {\n this.#pushHandlerSets(handlerSets, nextNode.#children[\"*\"], method, node.#params);\n }\n this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);\n } else {\n tempNodes.push(nextNode);\n }\n }\n for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {\n const pattern = node.#patterns[k];\n const params = node.#params === emptyParams ? {} : { ...node.#params };\n if (pattern === \"*\") {\n const astNode = node.#children[\"*\"];\n if (astNode) {\n this.#pushHandlerSets(handlerSets, astNode, method, node.#params);\n astNode.#params = params;\n tempNodes.push(astNode);\n }\n continue;\n }\n const [key, name, matcher] = pattern;\n if (!part && !(matcher instanceof RegExp)) {\n continue;\n }\n const child = node.#children[key];\n if (matcher instanceof RegExp) {\n if (partOffsets === null) {\n partOffsets = new Array(len);\n let offset = path[0] === \"/\" ? 1 : 0;\n for (let p = 0; p < len; p++) {\n partOffsets[p] = offset;\n offset += parts[p].length + 1;\n }\n }\n const restPathString = path.substring(partOffsets[i]);\n const m = matcher.exec(restPathString);\n if (m) {\n params[name] = m[0];\n this.#pushHandlerSets(handlerSets, child, method, node.#params, params);\n if (m[0].length === restPathString.length && child.#children[\"*\"]) {\n this.#pushHandlerSets(\n handlerSets,\n child.#children[\"*\"],\n method,\n node.#params,\n params\n );\n }\n if (hasChildren(child.#children)) {\n child.#params = params;\n const componentCount = m[0].match(/\\//)?.length ?? 0;\n const targetCurNodes = curNodesQueue[componentCount] ||= [];\n targetCurNodes.push(child);\n }\n continue;\n }\n }\n if (matcher === true || matcher.test(part)) {\n params[name] = part;\n if (isLast) {\n this.#pushHandlerSets(handlerSets, child, method, params, node.#params);\n if (child.#children[\"*\"]) {\n this.#pushHandlerSets(\n handlerSets,\n child.#children[\"*\"],\n method,\n params,\n node.#params\n );\n }\n } else {\n child.#params = params;\n tempNodes.push(child);\n }\n }\n }\n }\n const shifted = curNodesQueue.shift();\n curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;\n }\n if (handlerSets.length > 1) {\n handlerSets.sort((a, b) => {\n return a.score - b.score;\n });\n }\n return [handlerSets.map(({ handler, params }) => [handler, params])];\n }\n};\nexport {\n Node\n};\n", "// src/router/trie-router/router.ts\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { Node } from \"./node.js\";\nvar TrieRouter = class {\n name = \"TrieRouter\";\n #node;\n constructor() {\n this.#node = new Node();\n }\n add(method, path, handler) {\n const results = checkOptionalParameter(path);\n if (results) {\n for (let i = 0, len = results.length; i < len; i++) {\n this.#node.insert(method, results[i], handler);\n }\n return;\n }\n this.#node.insert(method, path, handler);\n }\n match(method, path) {\n return this.#node.search(method, path);\n }\n};\nexport {\n TrieRouter\n};\n", "// src/hono.ts\nimport { HonoBase } from \"./hono-base.js\";\nimport { RegExpRouter } from \"./router/reg-exp-router/index.js\";\nimport { SmartRouter } from \"./router/smart-router/index.js\";\nimport { TrieRouter } from \"./router/trie-router/index.js\";\nvar Hono = class extends HonoBase {\n /**\n * Creates an instance of the Hono class.\n *\n * @param options - Optional configuration options for the Hono instance.\n */\n constructor(options = {}) {\n super(options);\n this.router = options.router ?? new SmartRouter({\n routers: [new RegExpRouter(), new TrieRouter()]\n });\n }\n};\nexport {\n Hono\n};\n", "import {\n createEngineDatabase,\n createSqlAdapter,\n type SqlExecutor,\n type SqlResult,\n type SqlStatement,\n} from \"@hot-updater/plugin-core\";\nimport type { ToolingDatabase } from \"@hot-updater/plugin-core\";\n\n/** A D1 result, from the binding or the REST API. */\nexport interface D1ResultLike {\n readonly results?: readonly unknown[];\n readonly success?: boolean;\n readonly meta?: { readonly changes?: number };\n}\n\nexport class D1ExecutionError extends Error {\n readonly name = \"D1ExecutionError\";\n constructor() {\n super(\"D1 did not successfully execute every requested statement\");\n }\n}\n\nexport const toSqlResult = (result: D1ResultLike): SqlResult => {\n if (result.success === false) throw new D1ExecutionError();\n return {\n rows: (result.results ?? []) as Record<string, unknown>[],\n changes: result.meta?.changes ?? 0,\n };\n};\n\n/** D1 reports SQLite errors in the message; the SQL core classifies codes. */\nconst withSqliteCode = (error: unknown): unknown => {\n const message = error instanceof Error ? error.message : String(error);\n const code = /UNIQUE constraint failed|constraint failed: .*PRIMARY/iu.test(\n message,\n )\n ? \"SQLITE_CONSTRAINT_UNIQUE\"\n : /SQLITE_BUSY|database is locked/iu.test(message)\n ? \"SQLITE_BUSY\"\n : undefined;\n return code === undefined\n ? error\n : Object.assign(new Error(message, { cause: error }), { code });\n};\n\n/**\n * The most ops one write sends. Each statement of a batch is one query, a\n * Worker invocation allows 1,000 queries on the paid plan, and an op takes at\n * most two statements besides the batch's three.\n */\nexport const D1_MAX_OPS = 450;\n\n/**\n * Hot Updater's database on D1: the storage engine through the shared SQL\n * core, fenced by the schema settings. D1 has no interactive transactions,\n * so each write is one atomic batch that evaluates its guards first\n * (`_hu_write`).\n */\nexport const createD1Database = (runner: {\n query(statement: SqlStatement): Promise<SqlResult>;\n batch(statements: readonly SqlStatement[]): Promise<readonly SqlResult[]>;\n}): ToolingDatabase => {\n const executor: SqlExecutor = {\n dialect: \"sqlite\",\n execute: (statement) =>\n runner.query(statement).catch((error: unknown) => {\n throw withSqliteCode(error);\n }),\n batch: (statements) =>\n runner.batch(statements).catch((error: unknown) => {\n throw withSqliteCode(error);\n }),\n transaction: () => {\n throw new Error(\n \"D1 has no interactive transactions; writes are batches.\",\n );\n },\n };\n return createEngineDatabase({\n name: \"d1Database\",\n adapter: createSqlAdapter({ executor, maxOps: D1_MAX_OPS, maxParams: 100 }),\n });\n};\n", "import type { EngineDatabase } from \"@hot-updater/plugin-core\";\n\nimport {\n createD1Database,\n D1ExecutionError,\n type D1ResultLike,\n toSqlResult,\n} from \"../d1Executor\";\n\ntype D1BoundStatement = {\n all: () => Promise<D1ResultLike>;\n};\n\ntype D1PreparedStatement = {\n bind: (...values: readonly unknown[]) => D1BoundStatement;\n};\n\nexport type D1Like = {\n prepare(sql: string): D1PreparedStatement;\n batch(statements: D1BoundStatement[]): Promise<readonly D1ResultLike[]>;\n};\n\n/** Hot Updater's database on a D1 binding, inside a Worker. */\nexport const d1Database = (database: D1Like): EngineDatabase =>\n createD1Database({\n query: async ({ sql, params }) =>\n toSqlResult(\n await database\n .prepare(sql)\n .bind(...params)\n .all(),\n ),\n async batch(statements) {\n const results = await database.batch(\n statements.map(({ sql, params }) =>\n database.prepare(sql).bind(...params),\n ),\n );\n if (results.length !== statements.length) throw new D1ExecutionError();\n return results.map(toSqlResult);\n },\n });\n", "const encoder = new TextEncoder();\n\nconst hex = (bytes: ArrayBuffer) =>\n Array.from(new Uint8Array(bytes), (byte) =>\n byte.toString(16).padStart(2, \"0\"),\n ).join(\"\");\n\nconst hmac = async (key: BufferSource, value: string) =>\n crypto.subtle.sign(\n \"HMAC\",\n await crypto.subtle.importKey(\n \"raw\",\n key,\n { hash: \"SHA-256\", name: \"HMAC\" },\n false,\n [\"sign\"],\n ),\n encoder.encode(value),\n );\n\n/** RFC 3986 encoding, which S3 signs keys and query values in. */\nconst encodeRfc3986 = (value: string) =>\n encodeURIComponent(value).replace(\n /[!'()*]/g,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n\n/** R2's S3-compatible credentials. */\nexport interface R2Credentials {\n readonly accessKeyId: string;\n readonly secretAccessKey: string;\n}\n\n/**\n * A presigned GET URL for an object on R2's S3-compatible API: AWS Signature\n * Version 4 on Web Crypto, in the form `getSignedUrl` from\n * `@aws-sdk/s3-request-presigner` signs, so a Worker presigns without the\n * AWS SDK.\n */\nexport const presignR2GetUrl = async ({\n accountId,\n bucketName,\n credentials,\n expiresInSeconds,\n key,\n signingDate = new Date(),\n}: {\n readonly accountId: string;\n readonly bucketName: string;\n readonly credentials: R2Credentials;\n readonly expiresInSeconds: number;\n /** The object's key, unencoded. */\n readonly key: string;\n readonly signingDate?: Date;\n}): Promise<string> => {\n const host = `${accountId}.r2.cloudflarestorage.com`;\n const path = `/${bucketName}/${key.split(\"/\").map(encodeRfc3986).join(\"/\")}`;\n const amzDate = signingDate.toISOString().replace(/[-:]|\\.\\d{3}/g, \"\");\n const scope = `${amzDate.slice(0, 8)}/auto/s3/aws4_request`;\n // Sorted by name, as the canonical request orders them.\n const query: [string, string][] = [\n [\"X-Amz-Algorithm\", \"AWS4-HMAC-SHA256\"],\n [\"X-Amz-Content-Sha256\", \"UNSIGNED-PAYLOAD\"],\n [\"X-Amz-Credential\", `${credentials.accessKeyId}/${scope}`],\n [\"X-Amz-Date\", amzDate],\n [\"X-Amz-Expires\", String(expiresInSeconds)],\n [\"X-Amz-SignedHeaders\", \"host\"],\n [\"x-id\", \"GetObject\"],\n ];\n const queryString = (entries: [string, string][]) =>\n entries\n .map(([name, value]) => `${encodeRfc3986(name)}=${encodeRfc3986(value)}`)\n .join(\"&\");\n const canonicalRequest = [\n \"GET\",\n path,\n queryString(query),\n `host:${host}\\n`,\n \"host\",\n \"UNSIGNED-PAYLOAD\",\n ].join(\"\\n\");\n const stringToSign = [\n \"AWS4-HMAC-SHA256\",\n amzDate,\n scope,\n hex(\n await crypto.subtle.digest(\"SHA-256\", encoder.encode(canonicalRequest)),\n ),\n ].join(\"\\n\");\n let signingKey: ArrayBuffer = encoder.encode(\n `AWS4${credentials.secretAccessKey}`,\n ).buffer as ArrayBuffer;\n for (const part of [amzDate.slice(0, 8), \"auto\", \"s3\", \"aws4_request\"]) {\n signingKey = await hmac(signingKey, part);\n }\n const signature = hex(await hmac(signingKey, stringToSign));\n const signed: [string, string][] = [\n ...query.slice(0, 5),\n [\"X-Amz-Signature\", signature],\n ...query.slice(5),\n ];\n return `https://${host}${path}?${queryString(signed)}`;\n};\n", "import {\n createStorageKeyBuilder,\n createStorageAdapter,\n createStorageUri,\n parseStorageUri,\n type StorageAdapterWith,\n} from \"@hot-updater/plugin-core\";\n\nimport { presignR2GetUrl, type R2Credentials } from \"./presignR2Url\";\n\nexport type CloudflareWorkerStorageConfig = {\n readonly bucket: R2Bucket;\n readonly bucketName: string;\n readonly basePath?: string;\n} & (\n | {\n /** The account whose R2 endpoint download URLs name. */\n readonly accountId: string;\n /**\n * R2's S3-compatible credentials, which presign download URLs, as\n * `r2Storage` from `@hot-updater/cloudflare` does: what a server needs\n * to serve downloads.\n */\n readonly credentials: R2Credentials;\n }\n | { readonly accountId?: undefined; readonly credentials?: undefined }\n);\n\n/** Devices download right after the update check that returns the URL. */\nconst PRESIGNED_URL_EXPIRES_IN_SECONDS = 3600;\n\n/**\n * Storage on the Worker's R2 binding. With R2's S3-compatible credentials,\n * its download URLs are presigned and devices download from the bucket;\n * without them, it has no `getDownloadUrl`, as a Console that only reads\n * needs.\n */\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig & {\n readonly credentials: R2Credentials;\n },\n): StorageAdapterWith<\"put\" | \"get\" | \"getDownloadUrl\" | \"exists\" | \"delete\">;\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig,\n): StorageAdapterWith<\"put\" | \"get\" | \"exists\" | \"delete\">;\nexport function r2WorkerStorage(\n config: CloudflareWorkerStorageConfig,\n): StorageAdapterWith<\"put\" | \"get\" | \"exists\" | \"delete\"> {\n const getStorageKey = createStorageKeyBuilder(config.basePath);\n\n const parseAndValidate = (storageUri: string) => {\n const parsed = parseStorageUri(storageUri, \"r2\");\n if (parsed.bucket !== config.bucketName) {\n throw new Error(\n `Bucket name mismatch: expected \"${config.bucketName}\", but found \"${parsed.bucket}\".`,\n );\n }\n return parsed;\n };\n\n return createStorageAdapter({\n name: \"r2Storage\",\n protocol: \"r2\",\n async put({ key, body, contentLength, contentType }) {\n const storageKey = getStorageKey(key);\n const uploadOptions = {\n httpMetadata: {\n contentType,\n cacheControl: \"max-age=31536000\",\n },\n };\n if (contentLength === undefined) {\n const bufferedBody = new Uint8Array(\n await new Response(body).arrayBuffer(),\n );\n await config.bucket.put(storageKey, bufferedBody, uploadOptions);\n } else {\n const fixedLengthBody = new FixedLengthStream(contentLength);\n await Promise.all([\n body.pipeTo(fixedLengthBody.writable),\n config.bucket.put(\n storageKey,\n fixedLengthBody.readable,\n uploadOptions,\n ),\n ]);\n }\n return {\n storageUri: createStorageUri({\n protocol: \"r2\",\n bucket: config.bucketName,\n key: storageKey,\n }),\n };\n },\n async get({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n const object = await config.bucket.get(key);\n if (!object) return { response: null };\n const headers = new Headers();\n object.writeHttpMetadata(headers);\n headers.set(\"etag\", object.httpEtag);\n headers.set(\"content-length\", String(object.size));\n return { response: new Response(object.body, { headers }) };\n },\n ...(config.credentials === undefined\n ? {}\n : {\n async getDownloadUrl({ storageUri }: { storageUri: string }) {\n const { key } = parseAndValidate(storageUri);\n return {\n url: await presignR2GetUrl({\n accountId: config.accountId,\n bucketName: config.bucketName,\n credentials: config.credentials,\n expiresInSeconds: PRESIGNED_URL_EXPIRES_IN_SECONDS,\n key,\n }),\n };\n },\n }),\n async exists({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n return { exists: (await config.bucket.head(key)) !== null };\n },\n async delete({ storageUri }) {\n const { key } = parseAndValidate(storageUri);\n await config.bucket.delete(key);\n return { deleted: true };\n },\n });\n}\n"],
|
|
6
6
|
"mappings": "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",
|
|
7
7
|
"names": ["match", "version", "match", "hash", "version", "LETTER_DASH_NUMBER", "NUMERIC_IDENTIFIER", "NUMERIC_IDENTIFIER_LOOSE", "NON_NUMERIC_IDENTIFIER", "MAIN_VERSION", "MAIN_VERSION_LOOSE", "PRERELEASE_IDENTIFIER", "PRERELEASE_IDENTIFIER_LOOSE", "PRERELEASE", "PRERELEASE_LOOSE", "BUILD_IDENTIFIER", "BUILD", "FULL_PLAIN", "LOOSE_PLAIN", "XRANGE_IDENTIFIER", "XRANGE_IDENTIFIER_LOOSE", "COERCE_PLAIN", "COERCE", "COERCE_FULL", "makeSafeRegexSource", "safeRegex", "FULL", "LOOSE", "NUMERIC$1", "formatComparableVersion", "version", "parse", "match", "tryParse", "safeRegex", "FULL_PLAIN", "LOOSE_PLAIN", "formatComparableVersion", "match", "version", "parse", "BUILD", "safeRegex", "LOOSE_PLAIN", "LOOSE_COMPARATOR", "match", "version", "tryParse", "COERCE_EXACT", "safeRegex", "COERCE", "COERCE_FULL_EXACT", "COERCE_FULL", "PRERELEASE", "PRERELEASE_LOOSE", "version", "tryParse", "formatComparableVersion", "coerce", "match", "version", "retained", "retainedIds", "coerce", "raw", "bound", "raw", "integer", "bound", "stored", "hash", "sort", "name", "stored", "version", "hash", "counters", "fail", "sketches", "sketches", "counters", "blank", "rewrite", "run", "encode", "json", "decode", "idOf", "rows", "page", "changes", "shard", "row", "lease", "lease", "metricsOf", "stored", "version", "coreSchema", "fail", "stored", "page", "compile", "run", "failed", "page", "options", "version", "json", "compare", "bound", "compile", "match", "failed", "version", "LETTER_DASH_NUMBER", "NUMERIC_IDENTIFIER", "NUMERIC_IDENTIFIER_LOOSE", "NON_NUMERIC_IDENTIFIER", "MAIN_VERSION", "MAIN_VERSION_LOOSE", "PRERELEASE_IDENTIFIER", "PRERELEASE_IDENTIFIER_LOOSE", "PRERELEASE", "PRERELEASE_LOOSE", "BUILD_IDENTIFIER", "BUILD", "FULL_PLAIN", "LOOSE_PLAIN", "GREATER_LESS_THAN", "XRANGE_IDENTIFIER", "XRANGE_IDENTIFIER_LOOSE", "XRANGE_PLAIN", "XRANGE_PLAIN_LOOSE", "LONE_TILDE", "LONE_CARET", "COERCE_PLAIN", "COERCE", "COERCE_FULL", "makeSafeRegexSource", "safeRegex", "FULL", "LOOSE", "NUMERIC$1", "formatComparableVersion", "version", "parse", "version", "match", "LOOSE", "FULL", "NUMERIC$1", "NUMERIC", "compareIdentifiers", "compareMainParsed", "comparePrereleaseParsed", "compareIdentifiers", "compareParsed", "STRICT_COMPARATOR", "safeRegex", "GREATER_LESS_THAN", "FULL_PLAIN", "LOOSE_COMPARATOR", "LOOSE_PLAIN", "formatComparator", "formatComparableVersion", "parseComparator", "match", "version", "parse", "testParsedComparator", "version", "compareParsed", "comparatorAllowsPrerelease", "version", "testComparatorSet", "testParsedComparator", "formatComparator", "compareParsed", "BUILD_STRIP", "BUILD", "BUILD_SAFE", "safeRegex", "STRICT_HYPHEN", "XRANGE_PLAIN", "LOOSE_HYPHEN", "XRANGE_PLAIN_LOOSE", "COMPARATOR_TRIM", "GREATER_LESS_THAN", "LOOSE_PLAIN", "TILDE_TRIM", "LONE_TILDE", "CARET_TRIM", "LONE_CARET", "STRICT_TILDE", "LOOSE_TILDE", "STRICT_CARET", "LOOSE_CARET", "STRICT_XRANGE", "LOOSE_XRANGE", "STAR", "GTE_ZERO", "GTE_ZERO_PRERELEASE", "LOOSE_COMPARATOR", "isWildcard", "hasInvalidWildcardOrder", "replaceTilde", "replaceTildes", "replaceCaret", "replaceCarets", "replaceXRange", "match", "replaceXRanges", "replaceHyphenRange", "expandComparator", "parseSimpleRange", "parseComparator", "parseRange", "tryParseRange", "testComparatorSet", "tryParseRange", "parseRange", "page", "query", "PAGE", "page", "stored", "PAGE", "fail", "page", "stored", "id", "stored", "fail", "isRecord", "body", "isRecord", "body", "match", "isRecord", "hash", "hash", "page", "OFFICIAL", "HOUR_MS", "DAY_MS", "isRecord", "isTextOrNull", "encoder", "isIdentity", "isText", "isRecord", "OFFICIAL", "markOfficial", "isRecord", "decoder", "MAX_IDENTITY_LENGTH", "HOUR_MS", "DAY_MS", "WINDOW_MS", "isRecord", "encodeCursor", "decodeCursor", "query", "window", "countOutcome", "counters", "HOUR_MS", "DAY_MS", "counters", "hour", "sketches", "PAGE", "HOUR_MS", "DAY_MS", "drain", "page", "scopeOf", "hour", "countBundle", "isText", "events", "counters", "sketches", "window", "MAX_PAGE_LIMIT", "MAX_IDENTITY_LENGTH", "MAX_CURSOR_LENGTH", "raw", "readScope", "window", "json", "body", "query", "markOfficial", "isRecord", "raw", "value", "MAX_DESCRIPTION_LENGTH", "version", "page", "OFFICIAL", "markOfficial", "RETRY_AFTER_SECONDS", "json", "body", "run", "query", "version", "markOfficial", "match", "decoder", "raw", "body", "body", "METHODS", "METHODS", "app", "env", "Node", "_Node", "Node", "Hono", "encoder", "query", "body", "Hono"]
|
|
8
8
|
}
|