@hot-updater/plugin-core 1.0.0-rc.1 → 1.0.0-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -1
  2. package/dist/assetStorageLayout.cjs +4 -2
  3. package/dist/assetStorageLayout.d.cts +5 -24
  4. package/dist/assetStorageLayout.d.mts +5 -24
  5. package/dist/assetStorageLayout.mjs +4 -2
  6. package/dist/calculatePagination.d.cts +0 -1
  7. package/dist/calculatePagination.d.mts +0 -1
  8. package/dist/compressionFormat.cjs +12 -5
  9. package/dist/compressionFormat.d.cts +1 -1
  10. package/dist/compressionFormat.d.mts +1 -1
  11. package/dist/compressionFormat.mjs +11 -4
  12. package/dist/contentAddressedAssets.d.cts +1 -4
  13. package/dist/contentAddressedAssets.d.mts +1 -4
  14. package/dist/createDatabasePlugin.cjs +115 -41
  15. package/dist/createDatabasePlugin.d.cts +3 -1
  16. package/dist/createDatabasePlugin.d.mts +3 -1
  17. package/dist/createDatabasePlugin.mjs +115 -42
  18. package/dist/createStoragePlugin.d.cts +0 -1
  19. package/dist/createStoragePlugin.d.mts +0 -1
  20. package/dist/databaseClient.cjs +6 -1
  21. package/dist/databaseClient.d.cts +1 -2
  22. package/dist/databaseClient.d.mts +1 -2
  23. package/dist/databaseClient.mjs +6 -2
  24. package/dist/databaseClientReads.cjs +3 -1
  25. package/dist/databaseClientReads.mjs +3 -2
  26. package/dist/databaseClientUpdates.cjs +2 -1
  27. package/dist/databaseClientUpdates.d.cts +1 -1
  28. package/dist/databaseClientUpdates.d.mts +1 -1
  29. package/dist/databaseClientUpdates.mjs +2 -0
  30. package/dist/databaseJsonValue.cjs +4 -0
  31. package/dist/databaseJsonValue.d.cts +4 -2
  32. package/dist/databaseJsonValue.d.mts +4 -2
  33. package/dist/databaseJsonValue.mjs +2 -1
  34. package/dist/databaseMetadata.cjs +0 -1
  35. package/dist/databasePluginCrud.cjs +1 -0
  36. package/dist/databasePluginCrud.d.cts +4 -1
  37. package/dist/databasePluginCrud.d.mts +4 -1
  38. package/dist/databasePluginCrud.mjs +1 -1
  39. package/dist/databasePluginCrudValidation.d.cts +6 -1
  40. package/dist/databasePluginCrudValidation.d.mts +6 -1
  41. package/dist/databasePluginCrudValidationErrors.cjs +1 -0
  42. package/dist/databasePluginCrudValidationErrors.mjs +1 -0
  43. package/dist/databasePluginCrudValidationFields.cjs +21 -19
  44. package/dist/databasePluginCrudValidationFields.d.cts +1 -1
  45. package/dist/databasePluginCrudValidationFields.d.mts +1 -1
  46. package/dist/databasePluginCrudValidationFields.mjs +20 -20
  47. package/dist/databasePluginCrudValidationMutations.cjs +1 -1
  48. package/dist/databasePluginCrudValidationMutations.d.cts +1 -1
  49. package/dist/databasePluginCrudValidationMutations.d.mts +1 -1
  50. package/dist/databasePluginCrudValidationMutations.mjs +1 -1
  51. package/dist/databasePluginCrudValidationQueries.d.cts +2 -1
  52. package/dist/databasePluginCrudValidationQueries.d.mts +2 -1
  53. package/dist/databasePluginCrudValidationRows.cjs +2 -2
  54. package/dist/databasePluginCrudValidationRows.d.cts +1 -1
  55. package/dist/databasePluginCrudValidationRows.d.mts +1 -1
  56. package/dist/databasePluginCrudValidationRows.mjs +2 -2
  57. package/dist/databaseRows.cjs +0 -1
  58. package/dist/databaseRows.d.cts +2 -6
  59. package/dist/databaseRows.d.mts +2 -6
  60. package/dist/index.cjs +4 -1
  61. package/dist/index.d.cts +5 -4
  62. package/dist/index.d.mts +5 -4
  63. package/dist/index.mjs +3 -2
  64. package/dist/insightsContract.cjs +146 -0
  65. package/dist/insightsContract.d.cts +9 -0
  66. package/dist/insightsContract.d.mts +9 -0
  67. package/dist/insightsContract.mjs +143 -0
  68. package/dist/insightsLatestQueries.cjs +53 -0
  69. package/dist/insightsLatestQueries.d.cts +13 -0
  70. package/dist/insightsLatestQueries.d.mts +13 -0
  71. package/dist/insightsLatestQueries.mjs +52 -0
  72. package/dist/internal.cjs +3 -0
  73. package/dist/internal.d.cts +5 -3
  74. package/dist/internal.d.mts +5 -3
  75. package/dist/internal.mjs +2 -1
  76. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.cjs +136 -0
  77. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs +116 -0
  78. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.cjs +167 -0
  79. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs +165 -0
  80. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.cjs +42 -0
  81. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.mjs +39 -0
  82. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.cjs +39 -0
  83. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs +37 -0
  84. package/dist/paginateBundles.d.cts +1 -8
  85. package/dist/paginateBundles.d.mts +1 -8
  86. package/dist/parseStorageUri.d.cts +1 -5
  87. package/dist/parseStorageUri.d.mts +1 -5
  88. package/dist/queryBundles.d.cts +0 -1
  89. package/dist/queryBundles.d.mts +0 -1
  90. package/dist/releaseCatalogCompiler.cjs +15 -12
  91. package/dist/releaseCatalogCompiler.d.cts +0 -1
  92. package/dist/releaseCatalogCompiler.d.mts +0 -1
  93. package/dist/releaseCatalogCompiler.mjs +11 -7
  94. package/dist/releaseCatalogMutation.cjs +1 -1
  95. package/dist/releaseCatalogMutation.d.cts +1 -1
  96. package/dist/releaseCatalogMutation.d.mts +1 -1
  97. package/dist/releaseCatalogMutation.mjs +1 -0
  98. package/dist/releaseManagement.cjs +3 -2
  99. package/dist/releaseManagement.d.cts +1 -1
  100. package/dist/releaseManagement.d.mts +1 -1
  101. package/dist/releaseManagement.mjs +3 -1
  102. package/dist/remoteBundleSigning.cjs +4 -4
  103. package/dist/remoteBundleSigning.d.cts +2 -13
  104. package/dist/remoteBundleSigning.d.mts +2 -13
  105. package/dist/remoteBundleSigning.mjs +4 -4
  106. package/dist/requestBundleCache.d.cts +1 -2
  107. package/dist/requestBundleCache.d.mts +1 -2
  108. package/dist/semverSatisfies.cjs +4 -3
  109. package/dist/semverSatisfies.mjs +2 -1
  110. package/dist/storageDownloadPath.cjs +2 -1
  111. package/dist/storageDownloadPath.d.cts +1 -3
  112. package/dist/storageDownloadPath.d.mts +1 -3
  113. package/dist/storageDownloadPath.mjs +2 -1
  114. package/dist/types/database.d.cts +4 -3
  115. package/dist/types/database.d.mts +4 -3
  116. package/dist/types/databaseFields.cjs +1 -5
  117. package/dist/types/databaseFields.d.cts +1 -1
  118. package/dist/types/databaseFields.d.mts +1 -1
  119. package/dist/types/databaseFields.mjs +1 -5
  120. package/dist/types/databaseOperations.d.cts +15 -12
  121. package/dist/types/databaseOperations.d.mts +15 -12
  122. package/dist/types/databasePlugin.d.cts +75 -11
  123. package/dist/types/databasePlugin.d.mts +75 -11
  124. package/dist/types/databaseQuery.d.cts +2 -3
  125. package/dist/types/databaseQuery.d.mts +2 -3
  126. package/dist/types/databaseRows.d.cts +16 -11
  127. package/dist/types/databaseRows.d.mts +16 -11
  128. package/dist/types/index.d.cts +11 -7
  129. package/dist/types/index.d.mts +11 -7
  130. package/dist/types/internal.d.cts +4 -3
  131. package/dist/types/internal.d.mts +4 -3
  132. package/dist/types/public.d.cts +4 -3
  133. package/dist/types/public.d.mts +4 -3
  134. package/dist/types/utils.d.cts +1 -1
  135. package/dist/types/utils.d.mts +1 -1
  136. package/dist/uuidv7.cjs +7 -2
  137. package/dist/uuidv7.d.cts +0 -1
  138. package/dist/uuidv7.d.mts +0 -1
  139. package/dist/uuidv7.mjs +1 -1
  140. package/package.json +4 -4
  141. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +0 -345
  142. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +0 -341
@@ -4,10 +4,95 @@ import { validateCreateData, validateResult } from "./databasePluginCrudValidati
4
4
  import { validateApiKeyUpdateData, validateBundleUpdateData, validateReleaseUpdateData } from "./databasePluginCrudValidationMutations.mjs";
5
5
  import { createDatabasePluginCrud } from "./databasePluginCrud.mjs";
6
6
  import { createTransactionDatabasePlugin } from "./databasePluginTransaction.mjs";
7
+ import { compareInsightsText, createValidatedInsightsModel } from "./insightsContract.mjs";
7
8
  //#region src/createDatabasePlugin.ts
8
9
  const PAGE_SIZE = 100;
9
10
  const compareChannelRows = (left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
11
+ const toInsightsBundleWhere = (filter) => [
12
+ {
13
+ field: "platform",
14
+ value: filter.platform
15
+ },
16
+ {
17
+ field: "channel",
18
+ value: filter.channel
19
+ },
20
+ {
21
+ field: "type",
22
+ value: filter.type
23
+ },
24
+ filter.type === "RECOVERED" ? {
25
+ field: "from_bundle_id",
26
+ value: filter.fromBundleId
27
+ } : {
28
+ field: "to_bundle_id",
29
+ value: filter.toBundleId
30
+ }
31
+ ];
32
+ const toInsightsEventRanges = (filter) => {
33
+ if (filter.kind === "all") return [[]];
34
+ if (filter.kind === "bundle") return [toInsightsBundleWhere(filter)];
35
+ return [
36
+ "UPDATE_DOWNLOADED",
37
+ "UPDATE_APPLIED",
38
+ "RECOVERED"
39
+ ].map((type) => [{
40
+ field: "install_id",
41
+ value: filter.installId
42
+ }, {
43
+ field: "type",
44
+ value: type
45
+ }]);
46
+ };
47
+ const listInsightsEventRange = async (crud, input, filterWhere) => {
48
+ const where = [...filterWhere, {
49
+ field: "received_at_ms",
50
+ operator: "gte",
51
+ value: input.sinceMs ?? 0
52
+ }];
53
+ const sameTimestamp = input.after === void 0 ? [] : await crud.findMany({
54
+ model: "bundle_events",
55
+ where: [
56
+ ...filterWhere,
57
+ {
58
+ field: "received_at_ms",
59
+ value: input.after.receivedAtMs
60
+ },
61
+ {
62
+ field: "id",
63
+ operator: "lt",
64
+ value: input.after.id
65
+ }
66
+ ],
67
+ orderBy: [{
68
+ field: "id",
69
+ direction: "desc"
70
+ }],
71
+ limit: input.limit,
72
+ offset: 0
73
+ });
74
+ if (sameTimestamp.length === input.limit) return sameTimestamp;
75
+ const older = await crud.findMany({
76
+ model: "bundle_events",
77
+ where: [...where, {
78
+ field: "received_at_ms",
79
+ operator: "lt",
80
+ value: input.after?.receivedAtMs ?? input.beforeReceivedAtMs
81
+ }],
82
+ orderBy: [{
83
+ field: "received_at_ms",
84
+ direction: "desc"
85
+ }, {
86
+ field: "id",
87
+ direction: "desc"
88
+ }],
89
+ limit: input.limit - sameTimestamp.length,
90
+ offset: 0
91
+ });
92
+ return [...sameTimestamp, ...older];
93
+ };
10
94
  var DatabaseAtomicCommitUnsupportedError = class extends Error {
95
+ pluginName;
11
96
  name = "DatabaseAtomicCommitUnsupportedError";
12
97
  constructor(pluginName) {
13
98
  super(`Database plugin "${pluginName}" cannot atomically commit changes across models.`);
@@ -28,6 +113,7 @@ var DatabaseRowReferencedError = class extends Error {
28
113
  }
29
114
  };
30
115
  var DatabaseCommitConflictError = class extends Error {
116
+ result;
31
117
  name = "DatabaseCommitConflictError";
32
118
  constructor(result) {
33
119
  super("Database commit precondition failed.");
@@ -255,12 +341,6 @@ const applyChange = async (database, change, changeIndex) => {
255
341
  }
256
342
  return;
257
343
  }
258
- case "insights":
259
- await database.create({
260
- model: "bundle_events",
261
- data: change.row
262
- });
263
- return;
264
344
  case "apiKeys": switch (change.operation) {
265
345
  case "insert":
266
346
  await database.create({
@@ -442,14 +522,6 @@ const validateDatabaseChange = (change) => {
442
522
  return;
443
523
  default: throw new DatabasePluginInputError("invalid-operation");
444
524
  }
445
- case "insights":
446
- if (change.operation !== "insert" || !hasOnlyKeys(change, [
447
- "model",
448
- "operation",
449
- "row"
450
- ])) throw new DatabasePluginInputError("invalid-operation");
451
- validateCreateData("bundle_events", change.row);
452
- return;
453
525
  case "apiKeys": switch (change.operation) {
454
526
  case "insert":
455
527
  if (!hasOnlyKeys(change, [
@@ -718,36 +790,31 @@ const createDatabasePluginAdapter = (name, implementation) => {
718
790
  }
719
791
  },
720
792
  insights: {
721
- async append(row) {
722
- await crud.create({
723
- model: "bundle_events",
724
- data: row
725
- });
793
+ recordEvent: (input) => implementation.recordInsights(input),
794
+ async listEvents(input) {
795
+ const ranges = await Promise.all(toInsightsEventRanges(input.filter).map((where) => listInsightsEventRange(crud, input, where)));
796
+ if (ranges.length === 1) return ranges[0];
797
+ return ranges.flat().sort((left, right) => right.received_at_ms - left.received_at_ms || compareInsightsText(right.id, left.id)).slice(0, input.limit);
726
798
  },
727
- async scan(input) {
728
- const rows = [];
729
- for (let offset = 0; rows.length < input.limit; offset += PAGE_SIZE) {
730
- const page = await crud.findMany({
731
- model: "bundle_events",
732
- where: [{
799
+ findLatestEvents: (input) => implementation.findLatestInsightsEvents(input),
800
+ countLatestEvents: (input) => implementation.countLatestInsightsEvents(input),
801
+ countEvents(input) {
802
+ return crud.count({
803
+ model: "bundle_events",
804
+ where: [
805
+ ...toInsightsBundleWhere(input.filter),
806
+ {
807
+ field: "received_at_ms",
808
+ operator: "gte",
809
+ value: input.sinceMs
810
+ },
811
+ {
733
812
  field: "received_at_ms",
734
813
  operator: "lt",
735
814
  value: input.beforeReceivedAtMs
736
- }],
737
- orderBy: [{
738
- field: "received_at_ms",
739
- direction: "asc"
740
- }, {
741
- field: "id",
742
- direction: "asc"
743
- }],
744
- limit: PAGE_SIZE,
745
- offset
746
- });
747
- rows.push(...page.filter((row) => input.after === void 0 || row.received_at_ms > input.after.receivedAtMs || row.received_at_ms === input.after.receivedAtMs && row.id > input.after.id));
748
- if (page.length < PAGE_SIZE) break;
749
- }
750
- return rows.slice(0, input.limit);
815
+ }
816
+ ]
817
+ });
751
818
  }
752
819
  },
753
820
  apiKeys: {
@@ -791,6 +858,12 @@ const createDatabasePluginAdapter = (name, implementation) => {
791
858
  ...implementation.dispose ? { dispose: implementation.dispose } : {}
792
859
  };
793
860
  };
794
- const createDatabasePlugin = (options) => ({ ...options });
861
+ const createDatabasePlugin = (options) => ({
862
+ ...options,
863
+ models: {
864
+ ...options.models,
865
+ insights: createValidatedInsightsModel(options.models.insights)
866
+ }
867
+ });
795
868
  //#endregion
796
- export { DatabaseAtomicCommitUnsupportedError, DatabaseRowReferencedError, createDatabasePlugin, createDatabasePluginAdapter };
869
+ export { DatabaseAtomicCommitUnsupportedError, DatabasePluginInputError, DatabaseRowReferencedError, createDatabasePlugin, createDatabasePluginAdapter };
@@ -1,5 +1,4 @@
1
1
  import { StoragePlugin } from "./types/index.cjs";
2
-
3
2
  //#region src/createStoragePlugin.d.ts
4
3
  type CreateStoragePluginOptions = StoragePlugin;
5
4
  type StorageOperation = Exclude<keyof StoragePlugin, "name" | "protocol">;
@@ -1,5 +1,4 @@
1
1
  import { StoragePlugin } from "./types/index.mjs";
2
-
3
2
  //#region src/createStoragePlugin.d.ts
4
3
  type CreateStoragePluginOptions = StoragePlugin;
5
4
  type StorageOperation = Exclude<keyof StoragePlugin, "name" | "protocol">;
@@ -4,6 +4,7 @@ const require_databaseClientReads = require("./databaseClientReads.cjs");
4
4
  const require_databaseClientUpdates = require("./databaseClientUpdates.cjs");
5
5
  //#region src/databaseClient.ts
6
6
  var DatabaseBundleNotFoundError = class extends Error {
7
+ bundleId;
7
8
  name = "DatabaseBundleNotFoundError";
8
9
  constructor(bundleId) {
9
10
  super(`Bundle "${bundleId}" was not found.`);
@@ -11,6 +12,8 @@ var DatabaseBundleNotFoundError = class extends Error {
11
12
  }
12
13
  };
13
14
  var DatabasePatchInsertUnsupportedError = class extends Error {
15
+ bundleId;
16
+ pluginName;
14
17
  name = "DatabasePatchInsertUnsupportedError";
15
18
  constructor(bundleId, pluginName) {
16
19
  super(`Database plugin "${pluginName}" cannot atomically insert patches for bundle "${bundleId}".`);
@@ -29,12 +32,13 @@ const insertChanges = (bundle) => [{
29
32
  }))];
30
33
  const updateChanges = (bundleId, update) => {
31
34
  const rowUpdate = require_databaseClientUpdates.bundleUpdateToRow(update);
35
+ const patchesPresent = Object.hasOwn(update, "patches");
32
36
  return [{
33
37
  model: "bundles",
34
38
  operation: "update",
35
39
  where: { id: bundleId },
36
40
  update: rowUpdate
37
- }, ...Object.hasOwn(update, "patches") ? [{
41
+ }, ...patchesPresent ? [{
38
42
  model: "bundlePatches",
39
43
  operation: "delete",
40
44
  where: { bundleId }
@@ -109,4 +113,5 @@ const createDatabaseClient = (plugin) => {
109
113
  //#endregion
110
114
  exports.DatabaseBundleNotFoundError = DatabaseBundleNotFoundError;
111
115
  exports.DatabasePatchInsertUnsupportedError = DatabasePatchInsertUnsupportedError;
116
+ exports.DatabasePatchUpdateUnsupportedError = require_databaseClientUpdates.DatabasePatchUpdateUnsupportedError;
112
117
  exports.createDatabaseClient = createDatabaseClient;
@@ -3,7 +3,6 @@ import { BundleRepository, ChannelDeleteInput, ChannelDeleteResult, ChannelInser
3
3
  import { DatabaseBundleQueryOptions, PaginatedResult } from "./types/index.cjs";
4
4
  import { DatabasePatchUpdateUnsupportedError } from "./databaseClientUpdates.cjs";
5
5
  import { Bundle } from "@hot-updater/core";
6
-
7
6
  //#region src/databaseClient.d.ts
8
7
  interface DatabaseClient {
9
8
  getBundleById(id: string): Promise<Bundle | null>;
@@ -30,4 +29,4 @@ declare class DatabasePatchInsertUnsupportedError extends Error {
30
29
  }
31
30
  declare const createDatabaseClient: (plugin: BundleRepository) => DatabaseClient;
32
31
  //#endregion
33
- export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, createDatabaseClient };
32
+ export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, DatabasePatchUpdateUnsupportedError, createDatabaseClient };
@@ -3,7 +3,6 @@ import { BundleRepository, ChannelDeleteInput, ChannelDeleteResult, ChannelInser
3
3
  import { DatabaseBundleQueryOptions, PaginatedResult } from "./types/index.mjs";
4
4
  import { DatabasePatchUpdateUnsupportedError } from "./databaseClientUpdates.mjs";
5
5
  import { Bundle } from "@hot-updater/core";
6
-
7
6
  //#region src/databaseClient.d.ts
8
7
  interface DatabaseClient {
9
8
  getBundleById(id: string): Promise<Bundle | null>;
@@ -30,4 +29,4 @@ declare class DatabasePatchInsertUnsupportedError extends Error {
30
29
  }
31
30
  declare const createDatabaseClient: (plugin: BundleRepository) => DatabaseClient;
32
31
  //#endregion
33
- export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, createDatabaseClient };
32
+ export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, DatabasePatchUpdateUnsupportedError, createDatabaseClient };
@@ -4,6 +4,7 @@ import { hydrateRows, responsePage } from "./databaseClientReads.mjs";
4
4
  import { DatabasePatchUpdateUnsupportedError, bundleUpdateToPatchRows, bundleUpdateToRow } from "./databaseClientUpdates.mjs";
5
5
  //#region src/databaseClient.ts
6
6
  var DatabaseBundleNotFoundError = class extends Error {
7
+ bundleId;
7
8
  name = "DatabaseBundleNotFoundError";
8
9
  constructor(bundleId) {
9
10
  super(`Bundle "${bundleId}" was not found.`);
@@ -11,6 +12,8 @@ var DatabaseBundleNotFoundError = class extends Error {
11
12
  }
12
13
  };
13
14
  var DatabasePatchInsertUnsupportedError = class extends Error {
15
+ bundleId;
16
+ pluginName;
14
17
  name = "DatabasePatchInsertUnsupportedError";
15
18
  constructor(bundleId, pluginName) {
16
19
  super(`Database plugin "${pluginName}" cannot atomically insert patches for bundle "${bundleId}".`);
@@ -29,12 +32,13 @@ const insertChanges = (bundle) => [{
29
32
  }))];
30
33
  const updateChanges = (bundleId, update) => {
31
34
  const rowUpdate = bundleUpdateToRow(update);
35
+ const patchesPresent = Object.hasOwn(update, "patches");
32
36
  return [{
33
37
  model: "bundles",
34
38
  operation: "update",
35
39
  where: { id: bundleId },
36
40
  update: rowUpdate
37
- }, ...Object.hasOwn(update, "patches") ? [{
41
+ }, ...patchesPresent ? [{
38
42
  model: "bundlePatches",
39
43
  operation: "delete",
40
44
  where: { bundleId }
@@ -107,4 +111,4 @@ const createDatabaseClient = (plugin) => {
107
111
  };
108
112
  };
109
113
  //#endregion
110
- export { DatabaseBundleNotFoundError, DatabasePatchInsertUnsupportedError, createDatabaseClient };
114
+ export { DatabaseBundleNotFoundError, DatabasePatchInsertUnsupportedError, DatabasePatchUpdateUnsupportedError, createDatabaseClient };
@@ -59,7 +59,8 @@ const hydrateRows = async (database, ownerRows) => {
59
59
  const patchRows = await database.models.bundlePatches.findByBundleIds(ownerRows.map(({ id }) => id));
60
60
  const ownerIds = new Set(ownerRows.map(({ id }) => id));
61
61
  const referencedIds = [...new Set(patchRows.map(({ base_bundle_id }) => base_bundle_id).filter((id) => !ownerIds.has(id)))];
62
- return require_databaseRows.rowsToBundles(ownerRows, patchRows, referencedIds.length === 0 ? [] : await loadBundleRows(database, { id: { in: referencedIds } }));
62
+ const referencedRows = referencedIds.length === 0 ? [] : await loadBundleRows(database, { id: { in: referencedIds } });
63
+ return require_databaseRows.rowsToBundles(ownerRows, patchRows, referencedRows);
63
64
  };
64
65
  const cursorIdFilter = (cursor, direction) => {
65
66
  if (cursor?.after) return { [direction === "desc" ? "lt" : "gt"]: cursor.after };
@@ -110,4 +111,5 @@ const responsePage = async (database, options) => {
110
111
  };
111
112
  //#endregion
112
113
  exports.hydrateRows = hydrateRows;
114
+ exports.loadBundleRows = loadBundleRows;
113
115
  exports.responsePage = responsePage;
@@ -59,7 +59,8 @@ const hydrateRows = async (database, ownerRows) => {
59
59
  const patchRows = await database.models.bundlePatches.findByBundleIds(ownerRows.map(({ id }) => id));
60
60
  const ownerIds = new Set(ownerRows.map(({ id }) => id));
61
61
  const referencedIds = [...new Set(patchRows.map(({ base_bundle_id }) => base_bundle_id).filter((id) => !ownerIds.has(id)))];
62
- return rowsToBundles(ownerRows, patchRows, referencedIds.length === 0 ? [] : await loadBundleRows(database, { id: { in: referencedIds } }));
62
+ const referencedRows = referencedIds.length === 0 ? [] : await loadBundleRows(database, { id: { in: referencedIds } });
63
+ return rowsToBundles(ownerRows, patchRows, referencedRows);
63
64
  };
64
65
  const cursorIdFilter = (cursor, direction) => {
65
66
  if (cursor?.after) return { [direction === "desc" ? "lt" : "gt"]: cursor.after };
@@ -109,4 +110,4 @@ const responsePage = async (database, options) => {
109
110
  };
110
111
  };
111
112
  //#endregion
112
- export { hydrateRows, responsePage };
113
+ export { hydrateRows, loadBundleRows, responsePage };
@@ -1,8 +1,9 @@
1
- require("./_virtual/_rolldown/runtime.cjs");
2
1
  const require_databaseMetadata = require("./databaseMetadata.cjs");
3
2
  let _hot_updater_core = require("@hot-updater/core");
4
3
  //#region src/databaseClientUpdates.ts
5
4
  var DatabasePatchUpdateUnsupportedError = class extends Error {
5
+ bundleId;
6
+ pluginName;
6
7
  name = "DatabasePatchUpdateUnsupportedError";
7
8
  constructor(bundleId, pluginName) {
8
9
  super(`Database plugin "${pluginName}" cannot atomically replace patches for bundle "${bundleId}".`);
@@ -1,5 +1,5 @@
1
+ import "./types/index.cjs";
1
2
  import { Bundle } from "@hot-updater/core";
2
-
3
3
  //#region src/databaseClientUpdates.d.ts
4
4
  declare class DatabasePatchUpdateUnsupportedError extends Error {
5
5
  readonly bundleId: string;
@@ -1,5 +1,5 @@
1
+ import "./types/index.mjs";
1
2
  import { Bundle } from "@hot-updater/core";
2
-
3
3
  //#region src/databaseClientUpdates.d.ts
4
4
  declare class DatabasePatchUpdateUnsupportedError extends Error {
5
5
  readonly bundleId: string;
@@ -2,6 +2,8 @@ import { bundleMetadataToRow } from "./databaseMetadata.mjs";
2
2
  import { getBundlePatches } from "@hot-updater/core";
3
3
  //#region src/databaseClientUpdates.ts
4
4
  var DatabasePatchUpdateUnsupportedError = class extends Error {
5
+ bundleId;
6
+ pluginName;
5
7
  name = "DatabasePatchUpdateUnsupportedError";
6
8
  constructor(bundleId, pluginName) {
7
9
  super(`Database plugin "${pluginName}" cannot atomically replace patches for bundle "${bundleId}".`);
@@ -33,5 +33,9 @@ const isDatabaseJsonValue = (value) => {
33
33
  };
34
34
  const isDatabaseJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && isDatabaseJsonValue(value);
35
35
  const isDatabaseMetadataObject = (value) => isDatabaseJsonObject(value) && (!Object.hasOwn(value, "app_version") || typeof value["app_version"] === "string");
36
+ const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && (value.username === null || typeof value.username === "string") && 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");
36
37
  //#endregion
38
+ exports.isDatabaseBundleEventMetadata = isDatabaseBundleEventMetadata;
39
+ exports.isDatabaseJsonObject = isDatabaseJsonObject;
40
+ exports.isDatabaseJsonValue = isDatabaseJsonValue;
37
41
  exports.isDatabaseMetadataObject = isDatabaseMetadataObject;
@@ -1,5 +1,7 @@
1
- import { DatabaseBundleMetadata } from "./types/databaseRows.cjs";
1
+ import { DatabaseBundleEventMetadata, DatabaseBundleMetadata } from "./types/databaseRows.cjs";
2
+ import "./types/index.cjs";
2
3
  //#region src/databaseJsonValue.d.ts
3
4
  declare const isDatabaseMetadataObject: (value: unknown) => value is DatabaseBundleMetadata;
5
+ declare const isDatabaseBundleEventMetadata: (value: unknown) => value is DatabaseBundleEventMetadata;
4
6
  //#endregion
5
- export { isDatabaseMetadataObject };
7
+ export { isDatabaseBundleEventMetadata, isDatabaseMetadataObject };
@@ -1,5 +1,7 @@
1
- import { DatabaseBundleMetadata } from "./types/databaseRows.mjs";
1
+ import { DatabaseBundleEventMetadata, DatabaseBundleMetadata } from "./types/databaseRows.mjs";
2
+ import "./types/index.mjs";
2
3
  //#region src/databaseJsonValue.d.ts
3
4
  declare const isDatabaseMetadataObject: (value: unknown) => value is DatabaseBundleMetadata;
5
+ declare const isDatabaseBundleEventMetadata: (value: unknown) => value is DatabaseBundleEventMetadata;
4
6
  //#endregion
5
- export { isDatabaseMetadataObject };
7
+ export { isDatabaseBundleEventMetadata, isDatabaseMetadataObject };
@@ -33,5 +33,6 @@ const isDatabaseJsonValue = (value) => {
33
33
  };
34
34
  const isDatabaseJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && isDatabaseJsonValue(value);
35
35
  const isDatabaseMetadataObject = (value) => isDatabaseJsonObject(value) && (!Object.hasOwn(value, "app_version") || typeof value["app_version"] === "string");
36
+ const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && (value.username === null || typeof value.username === "string") && 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");
36
37
  //#endregion
37
- export { isDatabaseMetadataObject };
38
+ export { isDatabaseBundleEventMetadata, isDatabaseJsonObject, isDatabaseJsonValue, isDatabaseMetadataObject };
@@ -1,4 +1,3 @@
1
- require("./_virtual/_rolldown/runtime.cjs");
2
1
  const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
3
2
  const require_databaseJsonValue = require("./databaseJsonValue.cjs");
4
3
  let _hot_updater_core = require("@hot-updater/core");
@@ -83,4 +83,5 @@ const createDatabasePluginCrud = (implementation) => {
83
83
  };
84
84
  };
85
85
  //#endregion
86
+ exports.DatabasePluginInputError = require_databasePluginCrudValidationErrors.DatabasePluginInputError;
86
87
  exports.createDatabasePluginCrud = createDatabasePluginCrud;
@@ -1 +1,4 @@
1
- import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.cjs";
1
+ import "./types/internal.cjs";
2
+ import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.cjs";
3
+ import "./databasePluginCrudValidation.cjs";
4
+ export { DatabasePluginInputError, type DatabasePluginInputErrorCode };
@@ -1 +1,4 @@
1
- import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.mjs";
1
+ import "./types/internal.mjs";
2
+ import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.mjs";
3
+ import "./databasePluginCrudValidation.mjs";
4
+ export { DatabasePluginInputError, type DatabasePluginInputErrorCode };
@@ -83,4 +83,4 @@ const createDatabasePluginCrud = (implementation) => {
83
83
  };
84
84
  };
85
85
  //#endregion
86
- export { createDatabasePluginCrud };
86
+ export { DatabasePluginInputError, createDatabasePluginCrud };
@@ -1 +1,6 @@
1
- import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.cjs";
1
+ import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.cjs";
2
+ import "./databasePluginCrudValidationFields.cjs";
3
+ import "./databasePluginCrudValidationMutations.cjs";
4
+ import "./databasePluginCrudValidationQueries.cjs";
5
+ import "./databasePluginCrudValidationRows.cjs";
6
+ export { DatabasePluginInputError, type DatabasePluginInputErrorCode };
@@ -1 +1,6 @@
1
- import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.mjs";
1
+ import { DatabasePluginInputError, DatabasePluginInputErrorCode } from "./databasePluginCrudValidationErrors.mjs";
2
+ import "./databasePluginCrudValidationFields.mjs";
3
+ import "./databasePluginCrudValidationMutations.mjs";
4
+ import "./databasePluginCrudValidationQueries.mjs";
5
+ import "./databasePluginCrudValidationRows.mjs";
6
+ export { DatabasePluginInputError, type DatabasePluginInputErrorCode };
@@ -1,5 +1,6 @@
1
1
  //#region src/databasePluginCrudValidationErrors.ts
2
2
  var DatabasePluginInputError = class extends Error {
3
+ code;
3
4
  name = "DatabasePluginInputError";
4
5
  constructor(code) {
5
6
  super(`Invalid database plugin input: ${code}`);
@@ -1,5 +1,6 @@
1
1
  //#region src/databasePluginCrudValidationErrors.ts
2
2
  var DatabasePluginInputError = class extends Error {
3
+ code;
3
4
  name = "DatabasePluginInputError";
4
5
  constructor(code) {
5
6
  super(`Invalid database plugin input: ${code}`);
@@ -1,4 +1,3 @@
1
- require("./_virtual/_rolldown/runtime.cjs");
2
1
  const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
3
2
  const require_databaseJsonValue = require("./databaseJsonValue.cjs");
4
3
  const require_databaseFields = require("./types/databaseFields.cjs");
@@ -14,6 +13,8 @@ const isChannelText = (value) => {
14
13
  }
15
14
  return true;
16
15
  };
16
+ const isInsightsIdentityText = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
17
+ const isNullableInsightsIdentityText = (value) => value === null || isInsightsIdentityText(value);
17
18
  const modelValidators = {
18
19
  bundles: {
19
20
  id: (value) => typeof value === "string",
@@ -88,10 +89,9 @@ const modelValidators = {
88
89
  },
89
90
  bundle_events: {
90
91
  id: (value) => typeof value === "string",
91
- type: (value) => value === "UPDATE_APPLIED" || value === "RECOVERED" || value === "RELEASE_ADOPTED" || value === "UNCHANGED",
92
- install_id: (value) => typeof value === "string",
93
- user_id: (value) => value === null || typeof value === "string",
94
- username: (value) => value === null || typeof value === "string",
92
+ type: (value) => value === "UPDATE_DOWNLOADED" || value === "UPDATE_APPLIED" || value === "RECOVERED" || value === "UNCHANGED",
93
+ install_id: isInsightsIdentityText,
94
+ user_id: isNullableInsightsIdentityText,
95
95
  from_bundle_id: (value) => value === null || typeof value === "string",
96
96
  from_release_id: (value) => value === null || typeof value === "string",
97
97
  to_release_id: (value) => value === null || typeof value === "string",
@@ -99,10 +99,7 @@ const modelValidators = {
99
99
  platform: (value) => value === "ios" || value === "android",
100
100
  app_version: (value) => typeof value === "string",
101
101
  channel: (value) => typeof value === "string",
102
- cohort: (value) => typeof value === "string",
103
- update_strategy: (value) => value === null || value === "fingerprint" || value === "appVersion",
104
- fingerprint_hash: (value) => value === null || typeof value === "string",
105
- sdk_version: (value) => value === null || typeof value === "string",
102
+ metadata: require_databaseJsonValue.isDatabaseBundleEventMetadata,
106
103
  received_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
107
104
  },
108
105
  api_keys: {
@@ -115,7 +112,7 @@ const modelValidators = {
115
112
  revoked_at_ms: (value) => value === null || typeof value === "number" && Number.isSafeInteger(value) && value >= 0
116
113
  }
117
114
  };
118
- const stringFields = new Set([
115
+ const stringFields = /* @__PURE__ */ new Set([
119
116
  "id",
120
117
  "platform",
121
118
  "file_hash",
@@ -156,7 +153,7 @@ const stringFields = new Set([
156
153
  "prefix",
157
154
  "role"
158
155
  ]);
159
- const numberFields = new Set([
156
+ const numberFields = /* @__PURE__ */ new Set([
160
157
  "archive_byte_size",
161
158
  "byte_size",
162
159
  "rollout_cohort_count",
@@ -169,13 +166,13 @@ const numberFields = new Set([
169
166
  "created_at_ms",
170
167
  "revoked_at_ms"
171
168
  ]);
172
- const booleanFields = new Set([
169
+ const booleanFields = /* @__PURE__ */ new Set([
173
170
  "should_force_update",
174
171
  "enabled",
175
172
  "is_tombstone"
176
173
  ]);
177
174
  const sortableFields = {
178
- bundles: new Set([
175
+ bundles: /* @__PURE__ */ new Set([
179
176
  "id",
180
177
  "platform",
181
178
  "file_hash",
@@ -192,7 +189,7 @@ const sortableFields = {
192
189
  "manifest_file_hash",
193
190
  "asset_base_storage_uri"
194
191
  ]),
195
- bundle_patches: new Set([
192
+ bundle_patches: /* @__PURE__ */ new Set([
196
193
  "id",
197
194
  "bundle_id",
198
195
  "base_bundle_id",
@@ -202,7 +199,7 @@ const sortableFields = {
202
199
  "byte_size",
203
200
  "order_index"
204
201
  ]),
205
- releases: new Set([
202
+ releases: /* @__PURE__ */ new Set([
206
203
  "id",
207
204
  "revision",
208
205
  "scope_key",
@@ -222,7 +219,7 @@ const sortableFields = {
222
219
  "created_at_ms",
223
220
  "updated_at_ms"
224
221
  ]),
225
- release_catalogs: new Set([
222
+ release_catalogs: /* @__PURE__ */ new Set([
226
223
  "scope_key",
227
224
  "catalog_id",
228
225
  "strategy",
@@ -236,8 +233,8 @@ const sortableFields = {
236
233
  "is_tombstone",
237
234
  "updated_at_ms"
238
235
  ]),
239
- channels: new Set(["id", "name"]),
240
- bundle_events: new Set([
236
+ channels: /* @__PURE__ */ new Set(["id", "name"]),
237
+ bundle_events: /* @__PURE__ */ new Set([
241
238
  "id",
242
239
  "type",
243
240
  "install_id",
@@ -247,6 +244,8 @@ const sortableFields = {
247
244
  "from_release_id",
248
245
  "to_release_id",
249
246
  "to_bundle_id",
247
+ "pending_bundle_id",
248
+ "pending_release_id",
250
249
  "platform",
251
250
  "app_version",
252
251
  "channel",
@@ -256,7 +255,7 @@ const sortableFields = {
256
255
  "sdk_version",
257
256
  "received_at_ms"
258
257
  ]),
259
- api_keys: new Set([
258
+ api_keys: /* @__PURE__ */ new Set([
260
259
  "id",
261
260
  "hash",
262
261
  "name",
@@ -279,13 +278,16 @@ const isStringField = (field) => stringFields.has(field);
279
278
  const isNumberField = (field) => numberFields.has(field);
280
279
  const isBooleanField = (field) => booleanFields.has(field);
281
280
  //#endregion
281
+ exports.booleanFields = booleanFields;
282
282
  exports.isBooleanField = isBooleanField;
283
283
  exports.isChannelText = isChannelText;
284
284
  exports.isNumberField = isNumberField;
285
285
  exports.isRecord = isRecord;
286
286
  exports.isStringField = isStringField;
287
287
  exports.modelValidators = modelValidators;
288
+ exports.numberFields = numberFields;
288
289
  exports.sortableFields = sortableFields;
290
+ exports.stringFields = stringFields;
289
291
  exports.validateField = validateField;
290
292
  exports.validateFields = validateFields;
291
293
  exports.validateModel = validateModel;
@@ -1 +1 @@
1
- export { };
1
+ import "./types/internal.cjs";