@yihuangdb/storage-object
Version:
A Node.js storage object layer library using Redis OM
278 lines • 9.92 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStorage = createStorage;
exports.getStorage = getStorage;
exports.getOrCreateStorage = getOrCreateStorage;
exports.listStorages = listStorages;
exports.getStorageMetadata = getStorageMetadata;
exports.deleteStorage = deleteStorage;
exports.validateStorage = validateStorage;
exports.getStorageStats = getStorageStats;
exports.backupStorages = backupStorages;
exports.restoreStorages = restoreStorages;
exports.cleanupStorages = cleanupStorages;
exports.getGlobalStats = getGlobalStats;
exports.monitorStorage = monitorStorage;
exports.migrateStorage = migrateStorage;
const storage_1 = require("./storage");
const schema_registry_1 = require("./schema-registry");
const redis_key_manager_1 = require("./redis-key-manager");
/**
* Create a new storage instance and register it with the schema registry
*/
async function createStorage(name, schema, options) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
// Apply default options (change tracking enabled by default)
const mergedOptions = {
enableChangeTracking: true, // Default to true
...options,
};
// Register the schema
await registry.register(name, schema, mergedOptions);
// Create and initialize the storage
const storage = new storage_1.StorageObject(name, schema, mergedOptions);
await storage.initialize();
// Register the storage instance with the registry to enable statistics tracking
await registry.registerStorageInstance(name, storage);
// Initialize version tracking (enabled by default unless explicitly disabled)
if (mergedOptions.enableChangeTracking !== false) {
const keyManager = (0, redis_key_manager_1.getRedisKeyManager)();
const redis = storage.getRedis();
const { StorageVersionManager } = await Promise.resolve().then(() => __importStar(require('./storage-version-manager')));
const storageVersionManager = new StorageVersionManager(keyManager, redis);
storage.enableChangeTracking(storageVersionManager);
}
return storage;
}
/**
* Get an existing storage instance by name only
* The schema will be retrieved from the registry
*/
async function getStorage(name) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.getStorage(name);
}
/**
* Get or create a storage instance
* If the storage doesn't exist, it will be created with the provided schema
*/
async function getOrCreateStorage(name, schema, options) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
// Try to get existing storage
let storage = await registry.getStorage(name);
if (storage) {
return storage;
}
// Create new storage if schema is provided
if (!schema) {
throw new Error(`Storage ${name} not found and no schema provided`);
}
return createStorage(name, schema, options);
}
/**
* List all registered storage schemas
*/
async function listStorages() {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.getAllSchemas();
}
/**
* Get storage metadata including statistics
*/
async function getStorageMetadata(name) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.getSchemaMetadata(name);
}
/**
* Delete a storage and all its data
*/
async function deleteStorage(name) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
// Use the new unregister method that properly cleans up cache
return await registry.unregister(name);
}
/**
* Validate a storage schema against its data
*/
async function validateStorage(name) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.validate(name);
}
/**
* Get storage statistics
*/
async function getStorageStats(name) {
const metadata = await getStorageMetadata(name);
if (!metadata) {
return null;
}
return {
objectCount: metadata.statistics.objectCount,
totalOperations: metadata.statistics.totalOperations,
averageObjectSize: metadata.statistics.averageObjectSize,
performance: {
averageCreateTime: metadata.performance.averageCreateTime,
averageReadTime: metadata.performance.averageReadTime,
averageUpdateTime: metadata.performance.averageUpdateTime,
averageDeleteTime: metadata.performance.averageDeleteTime,
},
};
}
/**
* Backup all storages or a specific storage
*/
async function backupStorages(options) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
if (options?.names) {
// Backup specific storages
const backup = {
version: '1.0.0',
timestamp: new Date(),
schemas: {},
data: {},
};
for (const name of options.names) {
const metadata = await registry.getSchemaMetadata(name);
if (metadata) {
backup.schemas[name] = metadata;
if (options.includeData) {
const storage = await registry.getStorage(name);
if (storage) {
backup.data[name] = await storage.findAll();
}
}
}
}
return JSON.stringify(backup, null, 2);
}
// Backup all storages
return registry.backup({
includeData: options?.includeData,
compress: options?.compress,
});
}
/**
* Restore storages from backup
*/
async function restoreStorages(backupJson, options) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.restore(backupJson, options);
}
/**
* Clean up inactive storages
*/
async function cleanupStorages(inactiveDays = 30) {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.cleanup(inactiveDays);
}
/**
* Get global statistics across all storages
*/
async function getGlobalStats() {
const registry = (0, schema_registry_1.getSchemaRegistry)();
return registry.getStatistics();
}
/**
* Monitor storage changes with a callback
*/
function monitorStorage(name, callback) {
// This would require implementing event emitters in StorageObject
// For now, returning a no-op unsubscribe function
console.log(`Monitoring for ${name} not yet implemented`);
return () => { };
}
/**
* Migrate data from one schema version to another
*/
async function migrateStorage(name, newSchema, transform) {
const result = {
success: true,
migrated: 0,
failed: 0,
errors: [],
};
try {
const storage = await getStorage(name);
if (!storage) {
throw new Error(`Storage ${name} not found`);
}
// Get all existing data
const allData = await storage.findAll();
// Create new storage with new schema
const tempName = `${name}_migration_${Date.now()}`;
const newStorage = await createStorage(tempName, newSchema, {
prefix: `migration_${name}`,
});
// Migrate data
for (const item of allData) {
try {
const { entityId, ...data } = item;
const transformedData = transform ? transform(data) : data;
await newStorage.create(transformedData);
result.migrated++;
}
catch (error) {
result.failed++;
result.errors.push(error instanceof Error ? error.message : String(error));
}
}
if (result.failed === 0) {
// Clear old storage and copy data back
await storage.clear();
// Update schema in registry
const registry = (0, schema_registry_1.getSchemaRegistry)();
await registry.register(name, newSchema);
// Copy data back
const migratedData = await newStorage.findAll();
for (const item of migratedData) {
const { entityId, ...data } = item;
await storage.create(data);
}
// Clean up temp storage
await newStorage.clear();
await newStorage.disconnect();
}
else {
result.success = false;
}
}
catch (error) {
result.success = false;
result.errors.push(error instanceof Error ? error.message : String(error));
}
return result;
}
//# sourceMappingURL=storage-factory.js.map
;