s3db.js 10.0.16 → 10.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Configuration handling for EventualConsistencyPlugin
3
+ * @module eventual-consistency/config
4
+ */
5
+
6
+ /**
7
+ * Create default configuration with options
8
+ * @param {Object} options - User-provided options (nested format)
9
+ * @param {string} detectedTimezone - Auto-detected timezone
10
+ * @returns {Object} Complete configuration object
11
+ */
12
+ export function createConfig(options, detectedTimezone) {
13
+ // Extract nested configs with defaults
14
+ const consolidation = options.consolidation || {};
15
+ const locks = options.locks || {};
16
+ const gc = options.garbageCollection || {};
17
+ const analytics = options.analytics || {};
18
+ const batch = options.batch || {};
19
+ const lateArrivals = options.lateArrivals || {};
20
+ const checkpoints = options.checkpoints || {};
21
+
22
+ return {
23
+ // Cohort (timezone)
24
+ cohort: {
25
+ timezone: options.cohort?.timezone || detectedTimezone
26
+ },
27
+
28
+ // Reducer function
29
+ reducer: options.reducer || ((transactions) => {
30
+ let baseValue = 0;
31
+ for (const t of transactions) {
32
+ if (t.operation === 'set') {
33
+ baseValue = t.value;
34
+ } else if (t.operation === 'add') {
35
+ baseValue += t.value;
36
+ } else if (t.operation === 'sub') {
37
+ baseValue -= t.value;
38
+ }
39
+ }
40
+ return baseValue;
41
+ }),
42
+
43
+ // Consolidation settings
44
+ consolidationInterval: consolidation.interval ?? 300,
45
+ consolidationConcurrency: consolidation.concurrency ?? 5,
46
+ consolidationWindow: consolidation.window ?? 24,
47
+ autoConsolidate: consolidation.auto !== false,
48
+ mode: consolidation.mode || 'async',
49
+
50
+ // Late arrivals
51
+ lateArrivalStrategy: lateArrivals.strategy || 'warn',
52
+
53
+ // Batch transactions
54
+ batchTransactions: batch.enabled || false,
55
+ batchSize: batch.size || 100,
56
+
57
+ // Locks
58
+ lockTimeout: locks.timeout || 300,
59
+
60
+ // Garbage collection
61
+ transactionRetention: gc.retention ?? 30,
62
+ gcInterval: gc.interval ?? 86400,
63
+
64
+ // Analytics
65
+ enableAnalytics: analytics.enabled || false,
66
+ analyticsConfig: {
67
+ periods: analytics.periods || ['hour', 'day', 'month'],
68
+ metrics: analytics.metrics || ['count', 'sum', 'avg', 'min', 'max'],
69
+ rollupStrategy: analytics.rollupStrategy || 'incremental',
70
+ retentionDays: analytics.retentionDays ?? 365
71
+ },
72
+
73
+ // Checkpoints
74
+ enableCheckpoints: checkpoints.enabled !== false,
75
+ checkpointStrategy: checkpoints.strategy || 'hourly',
76
+ checkpointRetention: checkpoints.retention ?? 90,
77
+ checkpointThreshold: checkpoints.threshold ?? 1000,
78
+ deleteConsolidatedTransactions: checkpoints.deleteConsolidated !== false,
79
+ autoCheckpoint: checkpoints.auto !== false,
80
+
81
+ // Debug
82
+ verbose: options.verbose || false
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Validate resources configuration
88
+ * @param {Object} resources - Resources configuration
89
+ * @throws {Error} If configuration is invalid
90
+ */
91
+ export function validateResourcesConfig(resources) {
92
+ if (!resources || typeof resources !== 'object') {
93
+ throw new Error(
94
+ "EventualConsistencyPlugin requires 'resources' option.\n" +
95
+ "Example: { resources: { urls: ['clicks', 'views'], posts: ['likes'] } }"
96
+ );
97
+ }
98
+
99
+ for (const [resourceName, fields] of Object.entries(resources)) {
100
+ if (!Array.isArray(fields)) {
101
+ throw new Error(
102
+ `EventualConsistencyPlugin resources.${resourceName} must be an array of field names`
103
+ );
104
+ }
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Log configuration warnings
110
+ * @param {Object} config - Configuration object
111
+ */
112
+ export function logConfigWarnings(config) {
113
+ // Warn about batching in distributed environments
114
+ if (config.batchTransactions && !config.verbose) {
115
+ console.warn(
116
+ `[EventualConsistency] WARNING: batch.enabled is true. ` +
117
+ `This stores transactions in memory and will lose data if container crashes. ` +
118
+ `Not recommended for distributed/production environments.`
119
+ );
120
+ }
121
+
122
+ // Warn if checkpoints are disabled in high-volume scenarios
123
+ if (!config.enableCheckpoints && !config.verbose) {
124
+ console.warn(
125
+ `[EventualConsistency] INFO: checkpoints.enabled is false. ` +
126
+ `Checkpoints improve performance in high-volume scenarios by creating snapshots. ` +
127
+ `Consider enabling for production use.`
128
+ );
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Log initialization information
134
+ * @param {Object} config - Configuration object
135
+ * @param {Map} fieldHandlers - Field handlers map
136
+ * @param {boolean} timezoneAutoDetected - Whether timezone was auto-detected
137
+ */
138
+ export function logInitialization(config, fieldHandlers, timezoneAutoDetected) {
139
+ if (!config.verbose) return;
140
+
141
+ const totalFields = Array.from(fieldHandlers.values())
142
+ .reduce((sum, handlers) => sum + handlers.size, 0);
143
+
144
+ console.log(
145
+ `[EventualConsistency] Initialized with ${fieldHandlers.size} resource(s), ` +
146
+ `${totalFields} field(s) total`
147
+ );
148
+
149
+ // Log timezone if not explicitly set by user
150
+ if (timezoneAutoDetected) {
151
+ console.log(
152
+ `[EventualConsistency] Using timezone: ${config.cohort.timezone} ` +
153
+ `(${process.env.TZ ? 'from TZ env var' : 'default UTC'})`
154
+ );
155
+ }
156
+ }