@asaidimu/utils-database 3.0.0 → 3.1.1
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/README.md +16 -13
- package/index.d.mts +18 -70
- package/index.d.ts +18 -70
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ const db = await DatabaseConnection(
|
|
|
83
83
|
enableTelemetry: true,
|
|
84
84
|
predicates: {}, // custom validation predicates (optional)
|
|
85
85
|
},
|
|
86
|
-
createIndexedDbStore
|
|
86
|
+
createIndexedDbStore,
|
|
87
87
|
);
|
|
88
88
|
```
|
|
89
89
|
|
|
@@ -171,7 +171,7 @@ await db.migrateCollection(
|
|
|
171
171
|
},
|
|
172
172
|
description: "Add active flag",
|
|
173
173
|
},
|
|
174
|
-
100 // batch size (optional)
|
|
174
|
+
100, // batch size (optional)
|
|
175
175
|
);
|
|
176
176
|
```
|
|
177
177
|
|
|
@@ -199,7 +199,9 @@ const unsubDoc = doc.subscribe("document:update", (event) => {
|
|
|
199
199
|
|
|
200
200
|
// Telemetry (when enableTelemetry: true)
|
|
201
201
|
db.subscribe("telemetry", (event) => {
|
|
202
|
-
console.log(
|
|
202
|
+
console.log(
|
|
203
|
+
`${event.method} took ${event.metadata.performance.durationMs}ms`,
|
|
204
|
+
);
|
|
203
205
|
});
|
|
204
206
|
```
|
|
205
207
|
|
|
@@ -291,10 +293,10 @@ For migrations: `migrateCollection` streams documents from the store, passes the
|
|
|
291
293
|
|
|
292
294
|
### Available Scripts
|
|
293
295
|
|
|
294
|
-
| Command
|
|
295
|
-
|
|
|
296
|
-
| `npm test`
|
|
297
|
-
| `npm run test:watch`
|
|
296
|
+
| Command | Description |
|
|
297
|
+
| ---------------------- | ------------------------------------------------- |
|
|
298
|
+
| `npm test` | Run tests once (Vitest) |
|
|
299
|
+
| `npm run test:watch` | Run tests in watch mode |
|
|
298
300
|
| `npm run test:browser` | Run tests in a real browser (Vitest browser mode) |
|
|
299
301
|
|
|
300
302
|
### Testing
|
|
@@ -323,12 +325,12 @@ Use the [GitHub issue tracker](https://github.com/asaidimu/erp-utils/issues) to
|
|
|
323
325
|
|
|
324
326
|
### Troubleshooting
|
|
325
327
|
|
|
326
|
-
| Error
|
|
327
|
-
|
|
|
328
|
-
| `SCHEMA_NOT_FOUND`
|
|
329
|
-
| `CONFLICT`
|
|
330
|
-
| `TRANSACTION_FAILED`
|
|
331
|
-
| `INVALID_DATA`
|
|
328
|
+
| Error | Likely cause & solution |
|
|
329
|
+
| -------------------- | ----------------------------------------------------------------- |
|
|
330
|
+
| `SCHEMA_NOT_FOUND` | The collection was not created. Call `createCollection` first. |
|
|
331
|
+
| `CONFLICT` | Another operation updated the document. Re‑fetch and retry. |
|
|
332
|
+
| `TRANSACTION_FAILED` | One of the batched writes failed. Check individual operations. |
|
|
333
|
+
| `INVALID_DATA` | The document does not match the schema. Review validation errors. |
|
|
332
334
|
|
|
333
335
|
### FAQ
|
|
334
336
|
|
|
@@ -355,6 +357,7 @@ This project is licensed under the **MIT License**. See the [LICENSE](https://gi
|
|
|
355
357
|
### Acknowledgments
|
|
356
358
|
|
|
357
359
|
Built with ❤️ using:
|
|
360
|
+
|
|
358
361
|
- [`@asaidimu/anansi`](https://github.com/asaidimu/anansi) – schema validation and migrations.
|
|
359
362
|
- [`@standard-schema/spec`](https://github.com/standard-schema/standard-schema) – Standard Schema interoperability.
|
|
360
363
|
- [`uuid`](https://github.com/uuidjs/uuid) – for v7 UUIDs.
|
package/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
2
|
import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform, PredicateMap } from '@asaidimu/anansi';
|
|
3
|
+
import { EventBus } from '@core/events';
|
|
3
4
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -740,6 +741,23 @@ declare const createIndexedDbStore: <T extends Record<string, any>>(config: Stor
|
|
|
740
741
|
|
|
741
742
|
declare function DatabaseConnection(config: Omit<DatabaseConfig, "keyPath">, createStore: <T extends Record<string, any>>(config: StoreConfig, indexes: IndexDefinition[]) => Store<T>): Promise<Database>;
|
|
742
743
|
|
|
744
|
+
interface MiddlewareContext {
|
|
745
|
+
collection?: string;
|
|
746
|
+
documentId?: string;
|
|
747
|
+
operation: string;
|
|
748
|
+
args: any[];
|
|
749
|
+
eventBus?: EventBus<any>;
|
|
750
|
+
}
|
|
751
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
752
|
+
type MiddlewareNext = () => MaybePromise<any>;
|
|
753
|
+
type Middleware = (ctx: MiddlewareContext, next: MiddlewareNext) => MaybePromise<any>;
|
|
754
|
+
declare class Pipeline {
|
|
755
|
+
private middlewares;
|
|
756
|
+
use(middleware: Middleware): void;
|
|
757
|
+
execute(ctx: MiddlewareContext, finalOperation: () => MaybePromise<any>): MaybePromise<any>;
|
|
758
|
+
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
759
|
+
}
|
|
760
|
+
|
|
743
761
|
interface MutexOptions {
|
|
744
762
|
/**
|
|
745
763
|
* Maximum number of pending requests allowed in the queue.
|
|
@@ -807,76 +825,6 @@ declare class Mutex {
|
|
|
807
825
|
pending(): number;
|
|
808
826
|
}
|
|
809
827
|
|
|
810
|
-
/**
|
|
811
|
-
* Interface defining the shape of the EventBus.
|
|
812
|
-
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
813
|
-
*/
|
|
814
|
-
interface EventBus<TEventMap extends Record<string, any>> {
|
|
815
|
-
/**
|
|
816
|
-
* Subscribes to a specific event by name.
|
|
817
|
-
* @param eventName - The name of the event to subscribe to.
|
|
818
|
-
* @param callback - The function to call when the event is emitted.
|
|
819
|
-
* @returns A function to unsubscribe from the event.
|
|
820
|
-
*/
|
|
821
|
-
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
822
|
-
/**
|
|
823
|
-
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
824
|
-
* @param eventName - The name of the event to subscribe to.
|
|
825
|
-
* @param callback - The function to call when the event is emitted.
|
|
826
|
-
* @returns A function to cancel the one-shot subscription before it fires.
|
|
827
|
-
*/
|
|
828
|
-
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
829
|
-
/**
|
|
830
|
-
* Emits an event with a payload to all subscribed listeners.
|
|
831
|
-
* @param event - An object containing the event name and payload.
|
|
832
|
-
*/
|
|
833
|
-
emit: <TEventName extends keyof TEventMap>(event: {
|
|
834
|
-
name: TEventName;
|
|
835
|
-
payload: TEventMap[TEventName];
|
|
836
|
-
}) => void;
|
|
837
|
-
/**
|
|
838
|
-
* Retrieves metrics about event bus usage.
|
|
839
|
-
* @returns An object containing various metrics.
|
|
840
|
-
*/
|
|
841
|
-
metrics: () => EventMetrics;
|
|
842
|
-
/**
|
|
843
|
-
* Clears all subscriptions and resets metrics.
|
|
844
|
-
* After calling clear(), the bus is fully reset and can be reused —
|
|
845
|
-
* cross-tab communication is re-established if it was previously enabled.
|
|
846
|
-
*/
|
|
847
|
-
clear: () => void;
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
* Interface defining the metrics tracked by the EventBus.
|
|
851
|
-
*/
|
|
852
|
-
interface EventMetrics {
|
|
853
|
-
/** Total number of events emitted (both sync and deferred paths). */
|
|
854
|
-
totalEvents: number;
|
|
855
|
-
/** Number of active subscriptions across all event names. */
|
|
856
|
-
activeSubscriptions: number;
|
|
857
|
-
/** Map of event names to their emission counts. */
|
|
858
|
-
eventCounts: Map<string, number>;
|
|
859
|
-
/** Average duration of event dispatch in milliseconds. */
|
|
860
|
-
averageEmitDuration: number;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
interface MiddlewareContext {
|
|
864
|
-
collection?: string;
|
|
865
|
-
documentId?: string;
|
|
866
|
-
operation: string;
|
|
867
|
-
args: any[];
|
|
868
|
-
eventBus?: EventBus<any>;
|
|
869
|
-
}
|
|
870
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
871
|
-
type MiddlewareNext = () => MaybePromise<any>;
|
|
872
|
-
type Middleware = (ctx: MiddlewareContext, next: MiddlewareNext) => MaybePromise<any>;
|
|
873
|
-
declare class Pipeline {
|
|
874
|
-
private middlewares;
|
|
875
|
-
use(middleware: Middleware): void;
|
|
876
|
-
execute(ctx: MiddlewareContext, finalOperation: () => MaybePromise<any>): MaybePromise<any>;
|
|
877
|
-
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
828
|
interface DocumentOptions<T extends Record<string, any>> {
|
|
881
829
|
/**
|
|
882
830
|
* The already-persisted initial state of the document.
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
2
|
import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform, PredicateMap } from '@asaidimu/anansi';
|
|
3
|
+
import { EventBus } from '@core/events';
|
|
3
4
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -740,6 +741,23 @@ declare const createIndexedDbStore: <T extends Record<string, any>>(config: Stor
|
|
|
740
741
|
|
|
741
742
|
declare function DatabaseConnection(config: Omit<DatabaseConfig, "keyPath">, createStore: <T extends Record<string, any>>(config: StoreConfig, indexes: IndexDefinition[]) => Store<T>): Promise<Database>;
|
|
742
743
|
|
|
744
|
+
interface MiddlewareContext {
|
|
745
|
+
collection?: string;
|
|
746
|
+
documentId?: string;
|
|
747
|
+
operation: string;
|
|
748
|
+
args: any[];
|
|
749
|
+
eventBus?: EventBus<any>;
|
|
750
|
+
}
|
|
751
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
752
|
+
type MiddlewareNext = () => MaybePromise<any>;
|
|
753
|
+
type Middleware = (ctx: MiddlewareContext, next: MiddlewareNext) => MaybePromise<any>;
|
|
754
|
+
declare class Pipeline {
|
|
755
|
+
private middlewares;
|
|
756
|
+
use(middleware: Middleware): void;
|
|
757
|
+
execute(ctx: MiddlewareContext, finalOperation: () => MaybePromise<any>): MaybePromise<any>;
|
|
758
|
+
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
759
|
+
}
|
|
760
|
+
|
|
743
761
|
interface MutexOptions {
|
|
744
762
|
/**
|
|
745
763
|
* Maximum number of pending requests allowed in the queue.
|
|
@@ -807,76 +825,6 @@ declare class Mutex {
|
|
|
807
825
|
pending(): number;
|
|
808
826
|
}
|
|
809
827
|
|
|
810
|
-
/**
|
|
811
|
-
* Interface defining the shape of the EventBus.
|
|
812
|
-
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
813
|
-
*/
|
|
814
|
-
interface EventBus<TEventMap extends Record<string, any>> {
|
|
815
|
-
/**
|
|
816
|
-
* Subscribes to a specific event by name.
|
|
817
|
-
* @param eventName - The name of the event to subscribe to.
|
|
818
|
-
* @param callback - The function to call when the event is emitted.
|
|
819
|
-
* @returns A function to unsubscribe from the event.
|
|
820
|
-
*/
|
|
821
|
-
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
822
|
-
/**
|
|
823
|
-
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
824
|
-
* @param eventName - The name of the event to subscribe to.
|
|
825
|
-
* @param callback - The function to call when the event is emitted.
|
|
826
|
-
* @returns A function to cancel the one-shot subscription before it fires.
|
|
827
|
-
*/
|
|
828
|
-
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
829
|
-
/**
|
|
830
|
-
* Emits an event with a payload to all subscribed listeners.
|
|
831
|
-
* @param event - An object containing the event name and payload.
|
|
832
|
-
*/
|
|
833
|
-
emit: <TEventName extends keyof TEventMap>(event: {
|
|
834
|
-
name: TEventName;
|
|
835
|
-
payload: TEventMap[TEventName];
|
|
836
|
-
}) => void;
|
|
837
|
-
/**
|
|
838
|
-
* Retrieves metrics about event bus usage.
|
|
839
|
-
* @returns An object containing various metrics.
|
|
840
|
-
*/
|
|
841
|
-
metrics: () => EventMetrics;
|
|
842
|
-
/**
|
|
843
|
-
* Clears all subscriptions and resets metrics.
|
|
844
|
-
* After calling clear(), the bus is fully reset and can be reused —
|
|
845
|
-
* cross-tab communication is re-established if it was previously enabled.
|
|
846
|
-
*/
|
|
847
|
-
clear: () => void;
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
* Interface defining the metrics tracked by the EventBus.
|
|
851
|
-
*/
|
|
852
|
-
interface EventMetrics {
|
|
853
|
-
/** Total number of events emitted (both sync and deferred paths). */
|
|
854
|
-
totalEvents: number;
|
|
855
|
-
/** Number of active subscriptions across all event names. */
|
|
856
|
-
activeSubscriptions: number;
|
|
857
|
-
/** Map of event names to their emission counts. */
|
|
858
|
-
eventCounts: Map<string, number>;
|
|
859
|
-
/** Average duration of event dispatch in milliseconds. */
|
|
860
|
-
averageEmitDuration: number;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
interface MiddlewareContext {
|
|
864
|
-
collection?: string;
|
|
865
|
-
documentId?: string;
|
|
866
|
-
operation: string;
|
|
867
|
-
args: any[];
|
|
868
|
-
eventBus?: EventBus<any>;
|
|
869
|
-
}
|
|
870
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
871
|
-
type MiddlewareNext = () => MaybePromise<any>;
|
|
872
|
-
type Middleware = (ctx: MiddlewareContext, next: MiddlewareNext) => MaybePromise<any>;
|
|
873
|
-
declare class Pipeline {
|
|
874
|
-
private middlewares;
|
|
875
|
-
use(middleware: Middleware): void;
|
|
876
|
-
execute(ctx: MiddlewareContext, finalOperation: () => MaybePromise<any>): MaybePromise<any>;
|
|
877
|
-
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
828
|
interface DocumentOptions<T extends Record<string, any>> {
|
|
881
829
|
/**
|
|
882
830
|
* The already-persisted initial state of the document.
|