s3db.js 11.2.0 → 11.2.2
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/s3db-cli.js +55029 -0
- package/dist/s3db.cjs.js +52 -5
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +52 -5
- package/dist/s3db.es.js.map +1 -1
- package/package.json +1 -4
- package/src/plugins/eventual-consistency/config.js +4 -1
- package/src/plugins/eventual-consistency/consolidation.js +38 -4
- package/src/plugins/eventual-consistency/install.js +22 -0
package/dist/s3db.es.js
CHANGED
|
@@ -5101,8 +5101,10 @@ function createConfig(options, detectedTimezone) {
|
|
|
5101
5101
|
consolidationWindow: consolidation.window ?? 24,
|
|
5102
5102
|
autoConsolidate: consolidation.auto !== false,
|
|
5103
5103
|
mode: consolidation.mode || "async",
|
|
5104
|
-
// ✅
|
|
5104
|
+
// ✅ Performance tuning - Mark applied concurrency (default 50, up from 10)
|
|
5105
5105
|
markAppliedConcurrency: consolidation.markAppliedConcurrency ?? 50,
|
|
5106
|
+
// ✅ Performance tuning - Recalculate concurrency (default 50, up from 10)
|
|
5107
|
+
recalculateConcurrency: consolidation.recalculateConcurrency ?? 50,
|
|
5106
5108
|
// Late arrivals
|
|
5107
5109
|
lateArrivalStrategy: lateArrivals.strategy || "warn",
|
|
5108
5110
|
// Batch transactions
|
|
@@ -5931,11 +5933,33 @@ async function consolidateRecord(originalId, transactionResource, targetResource
|
|
|
5931
5933
|
const transactionsToUpdate = transactions.filter((txn) => txn.id !== "__synthetic__");
|
|
5932
5934
|
const markAppliedConcurrency = config.markAppliedConcurrency || 50;
|
|
5933
5935
|
const { results, errors } = await PromisePool.for(transactionsToUpdate).withConcurrency(markAppliedConcurrency).process(async (txn) => {
|
|
5936
|
+
const txnWithCohorts = ensureCohortHour(txn, config.cohort.timezone, false);
|
|
5937
|
+
const updateData = { applied: true };
|
|
5938
|
+
if (txnWithCohorts.cohortHour && !txn.cohortHour) {
|
|
5939
|
+
updateData.cohortHour = txnWithCohorts.cohortHour;
|
|
5940
|
+
}
|
|
5941
|
+
if (txnWithCohorts.cohortDate && !txn.cohortDate) {
|
|
5942
|
+
updateData.cohortDate = txnWithCohorts.cohortDate;
|
|
5943
|
+
}
|
|
5944
|
+
if (txnWithCohorts.cohortWeek && !txn.cohortWeek) {
|
|
5945
|
+
updateData.cohortWeek = txnWithCohorts.cohortWeek;
|
|
5946
|
+
}
|
|
5947
|
+
if (txnWithCohorts.cohortMonth && !txn.cohortMonth) {
|
|
5948
|
+
updateData.cohortMonth = txnWithCohorts.cohortMonth;
|
|
5949
|
+
}
|
|
5950
|
+
if (txn.value === null || txn.value === void 0) {
|
|
5951
|
+
updateData.value = 1;
|
|
5952
|
+
}
|
|
5934
5953
|
const [ok2, err2] = await tryFn(
|
|
5935
|
-
() => transactionResource.update(txn.id,
|
|
5954
|
+
() => transactionResource.update(txn.id, updateData)
|
|
5936
5955
|
);
|
|
5937
5956
|
if (!ok2 && config.verbose) {
|
|
5938
|
-
console.warn(
|
|
5957
|
+
console.warn(
|
|
5958
|
+
`[EventualConsistency] Failed to mark transaction ${txn.id} as applied:`,
|
|
5959
|
+
err2?.message,
|
|
5960
|
+
"Update data:",
|
|
5961
|
+
updateData
|
|
5962
|
+
);
|
|
5939
5963
|
}
|
|
5940
5964
|
return ok2;
|
|
5941
5965
|
});
|
|
@@ -6127,7 +6151,8 @@ async function recalculateRecord(originalId, transactionResource, targetResource
|
|
|
6127
6151
|
}
|
|
6128
6152
|
}
|
|
6129
6153
|
const transactionsToReset = allTransactions.filter((txn) => txn.source !== "anchor");
|
|
6130
|
-
const
|
|
6154
|
+
const recalculateConcurrency = config.recalculateConcurrency || 50;
|
|
6155
|
+
const { results, errors } = await PromisePool.for(transactionsToReset).withConcurrency(recalculateConcurrency).process(async (txn) => {
|
|
6131
6156
|
const [ok, err] = await tryFn(
|
|
6132
6157
|
() => transactionResource.update(txn.id, { applied: false })
|
|
6133
6158
|
);
|
|
@@ -7218,6 +7243,28 @@ async function createAnalyticsResource(handler, database, resourceName, fieldNam
|
|
|
7218
7243
|
},
|
|
7219
7244
|
behavior: "body-overflow",
|
|
7220
7245
|
timestamps: false,
|
|
7246
|
+
asyncPartitions: true,
|
|
7247
|
+
// ✅ Multi-attribute partitions for optimal analytics query performance
|
|
7248
|
+
partitions: {
|
|
7249
|
+
// Query by period (hour/day/week/month)
|
|
7250
|
+
byPeriod: {
|
|
7251
|
+
fields: { period: "string" }
|
|
7252
|
+
},
|
|
7253
|
+
// Query by period + cohort (e.g., all hour records for specific hours)
|
|
7254
|
+
byPeriodCohort: {
|
|
7255
|
+
fields: {
|
|
7256
|
+
period: "string",
|
|
7257
|
+
cohort: "string"
|
|
7258
|
+
}
|
|
7259
|
+
},
|
|
7260
|
+
// Query by field + period (e.g., all daily analytics for clicks field)
|
|
7261
|
+
byFieldPeriod: {
|
|
7262
|
+
fields: {
|
|
7263
|
+
field: "string",
|
|
7264
|
+
period: "string"
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
},
|
|
7221
7268
|
createdBy: "EventualConsistencyPlugin"
|
|
7222
7269
|
})
|
|
7223
7270
|
);
|
|
@@ -13747,7 +13794,7 @@ class Database extends EventEmitter {
|
|
|
13747
13794
|
this.id = idGenerator(7);
|
|
13748
13795
|
this.version = "1";
|
|
13749
13796
|
this.s3dbVersion = (() => {
|
|
13750
|
-
const [ok, err, version] = tryFn(() => true ? "11.2.
|
|
13797
|
+
const [ok, err, version] = tryFn(() => true ? "11.2.2" : "latest");
|
|
13751
13798
|
return ok ? version : "latest";
|
|
13752
13799
|
})();
|
|
13753
13800
|
this.resources = {};
|