UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

181 lines 8.97 kB
/** * @module SharedLock */ import { CORE, resolveOneOrMore, callInvokable, } from "../../../../utilities/_module-exports.js"; import {} from "../../../../utilities/_module-exports.js"; import { EventBus } from "../../../../event-bus/implementations/derivables/_module-exports.js"; import { MemoryEventBusAdapter } from "../../../../event-bus/implementations/adapters/_module.js"; import { v4 } from "uuid"; import { resolveDatabaseSharedLockAdapter } from "../../../../shared-lock/implementations/derivables/shared-lock-provider/resolve-database-shared-lock-adapter.js"; import { SharedLockSerdeTransformer } from "../../../../shared-lock/implementations/derivables/shared-lock-provider/shared-lock-serde-transformer.js"; import { SharedLock } from "../../../../shared-lock/implementations/derivables/shared-lock-provider/shared-lock.js"; import { Namespace } from "../../../../namespace/namespace.js"; import { TimeSpan } from "../../../../time-span/implementations/_module-exports.js"; /** * * IMPORT_PATH: `"@daiso-tech/core/shared-lock"` * @group Derivables */ export const DEFAULT_SHARED_LOCK_NAMESPACE = new Namespace("@shared-lock"); /** * `SharedLockProvider` class can be derived from any {@link ISharedLockAdapter | `ISharedLockAdapter`} or {@link IDatabaseSharedLockAdapter | `IDatabaseSharedLockAdapter`}. * * Note the {@link ISharedLock | `ISharedLock`} instances created by the `SharedLockProvider` class are serializable and deserializable, * allowing them to be seamlessly transferred across different servers, processes, and databases. * This can be done directly using {@link ISerderRegister | `ISerderRegister`} or indirectly through components that rely on {@link ISerderRegister | `ISerderRegister`} internally. * * IMPORT_PATH: `"@daiso-tech/core/shared-lock"` * @group Derivables */ export class SharedLockProvider { eventBus; originalAdapter; adapter; namespace; creatLockId; defaultTtl; defaultBlockingInterval; defaultBlockingTime; defaultRefreshTime; serde; serdeTransformerName; /** * @example * ```ts * import { KyselySharedLockAdapter } from "@daiso-tech/core/shared-lock/kysely-shared-lock-adapter"; * import { SharedLockProvider } from "@daiso-tech/core/shared-lock"; * import { Serde } from "@daiso-tech/core/serde"; * import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/super-json-serde-adapter"; * import Sqlite from "better-sqlite3"; * import { Kysely, SqliteDialect } from "kysely"; * * const sharedLockAdapter = new KyselySharedLockAdapter({ * kysely: new Kysely({ * dialect: new SqliteDialect({ * database: new Sqlite("local.db"), * }), * }); * }); * // You need initialize the adapter once before using it. * await sharedLockAdapter.init(); * * const serde = new Serde(new SuperJsonSerdeAdapter()) * const lockProvider = new SharedLockProvider({ * serde, * adapter: sharedLockAdapter, * }); * ``` */ constructor(settings) { const { defaultTtl = TimeSpan.fromMinutes(5), defaultBlockingInterval = TimeSpan.fromSeconds(1), defaultBlockingTime = TimeSpan.fromMinutes(1), defaultRefreshTime = TimeSpan.fromMinutes(5), createLockId = () => v4(), serde, namespace = DEFAULT_SHARED_LOCK_NAMESPACE, adapter, eventBus = new EventBus({ adapter: new MemoryEventBusAdapter(), }), serdeTransformerName = "", } = settings; this.serde = serde; this.defaultBlockingInterval = TimeSpan.fromTimeSpan(defaultBlockingInterval); this.defaultBlockingTime = TimeSpan.fromTimeSpan(defaultBlockingTime); this.defaultRefreshTime = TimeSpan.fromTimeSpan(defaultRefreshTime); this.creatLockId = createLockId; this.namespace = namespace; this.defaultTtl = defaultTtl === null ? null : TimeSpan.fromTimeSpan(defaultTtl); this.eventBus = eventBus; this.serdeTransformerName = serdeTransformerName; this.originalAdapter = adapter; this.adapter = resolveDatabaseSharedLockAdapter(adapter); this.registerToSerde(); } registerToSerde() { const transformer = new SharedLockSerdeTransformer({ originalAdapter: this.originalAdapter, adapter: this.adapter, defaultBlockingInterval: this.defaultBlockingInterval, defaultBlockingTime: this.defaultBlockingTime, defaultRefreshTime: this.defaultRefreshTime, eventBus: this.eventBus, namespace: this.namespace, serdeTransformerName: this.serdeTransformerName, }); for (const serde of resolveOneOrMore(this.serde)) { serde.registerCustom(transformer, CORE); } } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ addListener(eventName, listener) { return this.eventBus.addListener(eventName, listener); } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ removeListener(eventName, listener) { return this.eventBus.removeListener(eventName, listener); } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ listenOnce(eventName, listener) { return this.eventBus.listenOnce(eventName, listener); } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ asPromise(eventName) { return this.eventBus.asPromise(eventName); } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ subscribeOnce(eventName, listener) { return this.eventBus.subscribeOnce(eventName, listener); } /** * You can listen to the following {@link SharedLockEventMap | `SharedLockEventMap`} of all {@link ISharedLock | `ISharedLock`} instances created by the {@link ISharedLockProvider | `ISharedLockProvider`}. * To understand how this method works, refer to {@link IEventListenable | `IEventListenable `}. */ subscribe(eventName, listener) { return this.eventBus.subscribe(eventName, listener); } /** * @example * ```ts * import { SharedLockProvider } from "@daiso-tech/core/shared-lock"; * import { MemorySharedLockAdapter } from "@daiso-tech/core/shared-lock/memory-shared-lock-adapter"; * import { Namespace } from "@daiso-tech/core/namespace"; * import { Serde } from "@daiso-tech/core/serde"; * import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/super-json-serde-adapter"; * * const lockProvider = new SharedLockProvider({ * adapter: new MemorySharedLockAdapter(), * namespace: new Namespace("shared_lock"), * serde: new Serde(new SuperJsonSerdeAdapter()) * }); * * const sharedLock = lockProvider.create("a"); * ``` */ create(key, settings) { const { ttl = this.defaultTtl, lockId = callInvokable(this.creatLockId), limit, } = settings; const keyObj = this.namespace.create(key); return new SharedLock({ limit, namespace: this.namespace, adapter: this.adapter, originalAdapter: this.originalAdapter, eventDispatcher: this.eventBus, key: keyObj, lockId, ttl: ttl === null ? null : TimeSpan.fromTimeSpan(ttl), serdeTransformerName: this.serdeTransformerName, defaultBlockingInterval: this.defaultBlockingInterval, defaultBlockingTime: this.defaultBlockingTime, defaultRefreshTime: this.defaultRefreshTime, }); } } //# sourceMappingURL=shared-lock-provider.js.map