@asaidimu/utils-persistence 2.2.0 → 2.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/index.d.mts CHANGED
@@ -1,5 +1,127 @@
1
- import { S as SimplePersistence, a as StoreConfig } from '../types-ZDD-bdCz.js';
2
- export { b as StorageEvents, c as author } from '../types-ZDD-bdCz.js';
1
+ /**
2
+ * Configuration object for initializing a persistence store.
3
+ *
4
+ * This configuration allows you to:
5
+ * - Define the **schema/application version** of the data being persisted.
6
+ * - Distinguish between multiple **applications** that may run on the same host
7
+ * (so they don’t overwrite each other’s storage).
8
+ * - Optionally provide an **upgrade handler** to migrate persisted data when
9
+ * the version changes.
10
+ *
11
+ * @template T The type of data being persisted.
12
+ */
13
+ interface StoreConfig<T> {
14
+ /**
15
+ * The semantic version string (e.g., "1.0.0") of the data schema or application.
16
+ *
17
+ * This is used for version control and data migrations.
18
+ * When the persisted state’s version does not match the current version,
19
+ * the `onUpgrade` function will be invoked (if provided).
20
+ */
21
+ version: string;
22
+ /**
23
+ * A unique application identifier (e.g., "chat-app" or "my-dashboard").
24
+ *
25
+ * This prevents collisions between different apps or modules
26
+ * that might share the same persistence backend (e.g., localStorage).
27
+ *
28
+ * Example: If two apps both persist under the key "user", the `app`
29
+ * value ensures they can be distinguished.
30
+ */
31
+ app: string;
32
+ /**
33
+ * Optional handler for upgrading persisted state across versions.
34
+ *
35
+ * This function will be called when the persisted state’s `version`
36
+ * does not match the `version` specified in this config.
37
+ *
38
+ * @param state The existing state object, including:
39
+ * - `data`: The current persisted data (or null if none exists).
40
+ * - `version`: The version string stored with the data.
41
+ * - `app`: The application identifier stored with the data.
42
+ *
43
+ * @returns A new state object with:
44
+ * - `state`: The migrated data (or null if clearing/resetting).
45
+ * - `version`: The new version string (must match `config.version`).
46
+ *
47
+ * Example:
48
+ * ```ts
49
+ * onUpgrade: ({ data, version, app }) => {
50
+ * if (version === "1.0.0") {
51
+ * // Migrate from 1.0.0 to 2.0.0
52
+ * return { state: { ...data, newField: "default" }, version: "2.0.0" };
53
+ * }
54
+ * return { state: data, version: "2.0.0" };
55
+ * }
56
+ * ```
57
+ */
58
+ onUpgrade?: (state: {
59
+ data: T | null;
60
+ version: string;
61
+ app: string;
62
+ }) => {
63
+ state: T | null;
64
+ version: string;
65
+ };
66
+ }
67
+ interface SimplePersistence<T> {
68
+ /**
69
+ * Persists data to storage.
70
+ *
71
+ * @param id The **unique identifier of the *consumer instance*** making the change. This is NOT the ID of the data (`T`) itself.
72
+ * Think of it as the ID of the specific browser tab, component, or module that's currently interacting with the persistence layer.
73
+ * It should typically be a **UUID** generated once at the consumer instance's instantiation.
74
+ * This `id` is crucial for the `subscribe` method, helping to differentiate updates originating from the current instance versus other instances/tabs, thereby preventing self-triggered notification loops.
75
+ * @param state The state (of type T) to persist. This state is generally considered the **global or shared state** that all instances interact with.
76
+ * @returns `true` if the operation was successful, `false` if an error occurred. For asynchronous implementations (like `IndexedDBPersistence`), this returns a `Promise<boolean>`.
77
+ */
78
+ set(id: string, state: T): boolean | Promise<boolean>;
79
+ /**
80
+ * Retrieves the global persisted data from storage.
81
+ *
82
+ * @returns The retrieved state of type `T`, or `null` if no data is found or if an error occurs during retrieval/parsing.
83
+ * For asynchronous implementations, this returns a `Promise<T | null>`.
84
+ */
85
+ get(): (T | null) | (Promise<T | null>);
86
+ /**
87
+ * Subscribes to changes in the global persisted data that originate from *other* instances of your application (e.g., other tabs or independent components using the same persistence layer).
88
+ *
89
+ * @param id The **unique identifier of the *consumer instance* subscribing**. This allows the persistence implementation to filter out notifications that were initiated by the subscribing instance itself.
90
+ * @param callback The function to call when the global persisted data changes from *another* source. The new state (`T`) is passed as an argument to this callback.
91
+ * @returns A function that, when called, will unsubscribe the provided callback from future updates. Call this when your component or instance is no longer active to prevent memory leaks.
92
+ */
93
+ subscribe(id: string, callback: (state: T) => void): () => void;
94
+ /**
95
+ * Clears (removes) the entire global persisted data from storage.
96
+ *
97
+ * @returns `true` if the operation was successful, `false` if an error occurred. For asynchronous implementations, this returns a `Promise<boolean>`.
98
+ */
99
+ clear(): boolean | Promise<boolean>;
100
+ /**
101
+ * Returns metadata about the persistence layer.
102
+ *
103
+ * This is useful for distinguishing between multiple apps running on the same host
104
+ * (e.g., several apps served at `localhost:3000` that share the same storage key).
105
+ *
106
+ * @returns An object containing:
107
+ * - `version`: The semantic version string of the persistence schema or application.
108
+ * - `id`: A unique identifier for the application using this persistence instance.
109
+ */
110
+ stats(): {
111
+ version: string;
112
+ id: string;
113
+ };
114
+ }
115
+ interface StorageEvents {
116
+ "store:updated": {
117
+ storageKey: string;
118
+ instanceId: string;
119
+ state: any;
120
+ timestamp?: number;
121
+ version: string;
122
+ app: string;
123
+ };
124
+ }
3
125
 
4
126
  /**
5
127
  * Configuration options specific to the WebStoragePersistence adapter.
@@ -37,18 +159,12 @@ declare class WebStoragePersistence<T> implements SimplePersistence<T> {
37
159
  };
38
160
  }
39
161
 
40
- /**
41
- * Configuration for database connections
42
- */
43
162
  interface IndexedDBPersistenceConfig {
44
163
  store: string;
45
164
  database: string;
46
165
  collection: string;
47
166
  enableTelemetry?: boolean;
48
167
  }
49
- /**
50
- * IndexedDB persistence adapter with configurable database support
51
- */
52
168
  declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
53
169
  private collection;
54
170
  private collectionPromise;
@@ -56,12 +172,14 @@ declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
56
172
  private eventBus;
57
173
  private initialized;
58
174
  private initializationCallbacks;
175
+ private doc;
59
176
  private getStoreName;
60
177
  constructor(config: StoreConfig<T> & IndexedDBPersistenceConfig);
61
178
  private initialize;
62
179
  private _onInitialized;
63
180
  private getCollection;
64
181
  set(id: string, state: T): Promise<boolean>;
182
+ private _read;
65
183
  private _get;
66
184
  get(): Promise<T | null>;
67
185
  subscribe(id: string, callback: (state: T) => void): () => void;
@@ -70,10 +188,7 @@ declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
70
188
  version: string;
71
189
  id: string;
72
190
  };
73
- /**
74
- * Close a specific database
75
- */
76
191
  close(): Promise<void>;
77
192
  }
78
193
 
79
- export { IndexedDBPersistence, type IndexedDBPersistenceConfig, SimplePersistence, StoreConfig, WebStoragePersistence, type WebStoragePersistenceConfig };
194
+ export { IndexedDBPersistence, type IndexedDBPersistenceConfig, type SimplePersistence, type StorageEvents, type StoreConfig, WebStoragePersistence, type WebStoragePersistenceConfig };
package/index.d.ts CHANGED
@@ -1,5 +1,127 @@
1
- import { S as SimplePersistence, a as StoreConfig } from '../types-ZDD-bdCz.js';
2
- export { b as StorageEvents, c as author } from '../types-ZDD-bdCz.js';
1
+ /**
2
+ * Configuration object for initializing a persistence store.
3
+ *
4
+ * This configuration allows you to:
5
+ * - Define the **schema/application version** of the data being persisted.
6
+ * - Distinguish between multiple **applications** that may run on the same host
7
+ * (so they don’t overwrite each other’s storage).
8
+ * - Optionally provide an **upgrade handler** to migrate persisted data when
9
+ * the version changes.
10
+ *
11
+ * @template T The type of data being persisted.
12
+ */
13
+ interface StoreConfig<T> {
14
+ /**
15
+ * The semantic version string (e.g., "1.0.0") of the data schema or application.
16
+ *
17
+ * This is used for version control and data migrations.
18
+ * When the persisted state’s version does not match the current version,
19
+ * the `onUpgrade` function will be invoked (if provided).
20
+ */
21
+ version: string;
22
+ /**
23
+ * A unique application identifier (e.g., "chat-app" or "my-dashboard").
24
+ *
25
+ * This prevents collisions between different apps or modules
26
+ * that might share the same persistence backend (e.g., localStorage).
27
+ *
28
+ * Example: If two apps both persist under the key "user", the `app`
29
+ * value ensures they can be distinguished.
30
+ */
31
+ app: string;
32
+ /**
33
+ * Optional handler for upgrading persisted state across versions.
34
+ *
35
+ * This function will be called when the persisted state’s `version`
36
+ * does not match the `version` specified in this config.
37
+ *
38
+ * @param state The existing state object, including:
39
+ * - `data`: The current persisted data (or null if none exists).
40
+ * - `version`: The version string stored with the data.
41
+ * - `app`: The application identifier stored with the data.
42
+ *
43
+ * @returns A new state object with:
44
+ * - `state`: The migrated data (or null if clearing/resetting).
45
+ * - `version`: The new version string (must match `config.version`).
46
+ *
47
+ * Example:
48
+ * ```ts
49
+ * onUpgrade: ({ data, version, app }) => {
50
+ * if (version === "1.0.0") {
51
+ * // Migrate from 1.0.0 to 2.0.0
52
+ * return { state: { ...data, newField: "default" }, version: "2.0.0" };
53
+ * }
54
+ * return { state: data, version: "2.0.0" };
55
+ * }
56
+ * ```
57
+ */
58
+ onUpgrade?: (state: {
59
+ data: T | null;
60
+ version: string;
61
+ app: string;
62
+ }) => {
63
+ state: T | null;
64
+ version: string;
65
+ };
66
+ }
67
+ interface SimplePersistence<T> {
68
+ /**
69
+ * Persists data to storage.
70
+ *
71
+ * @param id The **unique identifier of the *consumer instance*** making the change. This is NOT the ID of the data (`T`) itself.
72
+ * Think of it as the ID of the specific browser tab, component, or module that's currently interacting with the persistence layer.
73
+ * It should typically be a **UUID** generated once at the consumer instance's instantiation.
74
+ * This `id` is crucial for the `subscribe` method, helping to differentiate updates originating from the current instance versus other instances/tabs, thereby preventing self-triggered notification loops.
75
+ * @param state The state (of type T) to persist. This state is generally considered the **global or shared state** that all instances interact with.
76
+ * @returns `true` if the operation was successful, `false` if an error occurred. For asynchronous implementations (like `IndexedDBPersistence`), this returns a `Promise<boolean>`.
77
+ */
78
+ set(id: string, state: T): boolean | Promise<boolean>;
79
+ /**
80
+ * Retrieves the global persisted data from storage.
81
+ *
82
+ * @returns The retrieved state of type `T`, or `null` if no data is found or if an error occurs during retrieval/parsing.
83
+ * For asynchronous implementations, this returns a `Promise<T | null>`.
84
+ */
85
+ get(): (T | null) | (Promise<T | null>);
86
+ /**
87
+ * Subscribes to changes in the global persisted data that originate from *other* instances of your application (e.g., other tabs or independent components using the same persistence layer).
88
+ *
89
+ * @param id The **unique identifier of the *consumer instance* subscribing**. This allows the persistence implementation to filter out notifications that were initiated by the subscribing instance itself.
90
+ * @param callback The function to call when the global persisted data changes from *another* source. The new state (`T`) is passed as an argument to this callback.
91
+ * @returns A function that, when called, will unsubscribe the provided callback from future updates. Call this when your component or instance is no longer active to prevent memory leaks.
92
+ */
93
+ subscribe(id: string, callback: (state: T) => void): () => void;
94
+ /**
95
+ * Clears (removes) the entire global persisted data from storage.
96
+ *
97
+ * @returns `true` if the operation was successful, `false` if an error occurred. For asynchronous implementations, this returns a `Promise<boolean>`.
98
+ */
99
+ clear(): boolean | Promise<boolean>;
100
+ /**
101
+ * Returns metadata about the persistence layer.
102
+ *
103
+ * This is useful for distinguishing between multiple apps running on the same host
104
+ * (e.g., several apps served at `localhost:3000` that share the same storage key).
105
+ *
106
+ * @returns An object containing:
107
+ * - `version`: The semantic version string of the persistence schema or application.
108
+ * - `id`: A unique identifier for the application using this persistence instance.
109
+ */
110
+ stats(): {
111
+ version: string;
112
+ id: string;
113
+ };
114
+ }
115
+ interface StorageEvents {
116
+ "store:updated": {
117
+ storageKey: string;
118
+ instanceId: string;
119
+ state: any;
120
+ timestamp?: number;
121
+ version: string;
122
+ app: string;
123
+ };
124
+ }
3
125
 
4
126
  /**
5
127
  * Configuration options specific to the WebStoragePersistence adapter.
@@ -37,18 +159,12 @@ declare class WebStoragePersistence<T> implements SimplePersistence<T> {
37
159
  };
38
160
  }
39
161
 
40
- /**
41
- * Configuration for database connections
42
- */
43
162
  interface IndexedDBPersistenceConfig {
44
163
  store: string;
45
164
  database: string;
46
165
  collection: string;
47
166
  enableTelemetry?: boolean;
48
167
  }
49
- /**
50
- * IndexedDB persistence adapter with configurable database support
51
- */
52
168
  declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
53
169
  private collection;
54
170
  private collectionPromise;
@@ -56,12 +172,14 @@ declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
56
172
  private eventBus;
57
173
  private initialized;
58
174
  private initializationCallbacks;
175
+ private doc;
59
176
  private getStoreName;
60
177
  constructor(config: StoreConfig<T> & IndexedDBPersistenceConfig);
61
178
  private initialize;
62
179
  private _onInitialized;
63
180
  private getCollection;
64
181
  set(id: string, state: T): Promise<boolean>;
182
+ private _read;
65
183
  private _get;
66
184
  get(): Promise<T | null>;
67
185
  subscribe(id: string, callback: (state: T) => void): () => void;
@@ -70,10 +188,7 @@ declare class IndexedDBPersistence<T> implements SimplePersistence<T> {
70
188
  version: string;
71
189
  id: string;
72
190
  };
73
- /**
74
- * Close a specific database
75
- */
76
191
  close(): Promise<void>;
77
192
  }
78
193
 
79
- export { IndexedDBPersistence, type IndexedDBPersistenceConfig, SimplePersistence, StoreConfig, WebStoragePersistence, type WebStoragePersistenceConfig };
194
+ export { IndexedDBPersistence, type IndexedDBPersistenceConfig, type SimplePersistence, type StorageEvents, type StoreConfig, WebStoragePersistence, type WebStoragePersistenceConfig };
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@asaidimu/indexed"),t=Object.create,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,a=(e,t)=>function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports},c=(e,a,c)=>(c=null!=e?t(o(e)):{},((e,t,o,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))s.call(e,c)||c===o||r(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(e&&e.__esModule?c:r(c,"default",{value:e,enumerable:!0}),e)),l=a({"node_modules/@asaidimu/events/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))s.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],n=0,i=0;const o=new Map,s=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{n++,i+=t,o.set(e,(o.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const n=performance.now();try{(s.get(t)||[]).forEach((e=>e(r)))}catch(n){e.errorHandler({...n,eventName:t,payload:r})}c(t,performance.now()-n)}))},u=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(l,e.batchDelay)}})(),p=e=>{const r=t.get(e);r?s.set(e,Array.from(r)):s.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:r}=e.data;(s.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const n=t.get(e);return n.add(r),p(e),()=>{n.delete(r),0===n.size?(t.delete(e),s.delete(e)):p(e)}},emit:({name:t,payload:n})=>{if(e.async)return r.push({name:t,payload:n}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:n}));const i=performance.now();try{(s.get(t)||[]).forEach((e=>e(n))),a&&a.postMessage({name:t,payload:n})}catch(r){e.errorHandler({...r,eventName:t,payload:n})}c(t,performance.now()-i)},getMetrics:()=>({totalEvents:n,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:n>0?i/n:0}),clear:()=>{t.clear(),s.clear(),r=[],n=0,i=0,o.clear(),a&&(a.close(),a=null)}}}}}),u=a({"node_modules/@asaidimu/query/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>g,createMatcher:()=>u,createPaginator:()=>E,createProjector:()=>q,createSorter:()=>j}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!s.call(e,c)&&c!==r&&n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,r){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:r},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,r){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:r}),this}join(e,t,r){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:r,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function l(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?n(t,e):function(e){return"computed"===e?.type}(t)?n(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(i(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>i(e,t)))],["or",(e,t)=>t.some((t=>i(e,t)))],["not",(e,t)=>!t.every((t=>i(e,t)))],["nor",(e,t)=>!t.some((t=>i(e,t)))],["xor",(e,t)=>1===t.filter((t=>i(e,t))).length]]);function n(r,n){let i=r.arguments.map((e=>t(n,e)));if(e[r.function])return e[r.function](...i);throw new Error(`Function ${r.function} not found!`)}function i(n,i){if(function(e){return!!e&&void 0!==e.conditions}(i))return function(e,t){let{operator:n,conditions:i}=t,o=r.get(n);if(o)return o(e,i);throw new Error(`Unsupported logical operator: ${n}`)}(n,i);if(!i||!i.field)return!1;let{field:o,operator:s,value:a}=i,c=n[o],l=t(n,a),u=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),p=e[s]||u.get(s);if(p)return p(c,l);throw new Error(`Unsupported comparison operator: ${s}`)}return{resolve:t,evaluate:i}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function n(e,n){let i=r.get(e);i||(i=new Map,r.set(e,i));let o=JSON.stringify(n);if(i.has(o))return i.get(o);let s=t(e,n);return i.set(o,s),s}return{matcher:n,match:n}}var p=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},h=e=>e&&"field"in e&&"operator"in e&&"value"in e,f=(e,t)=>{if(e){if(h(e)&&e){let r=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:r}}if((e=>"operator"in e&&"conditions"in e)(e)){let r={...e};return e.conditions&&(r.conditions=e.conditions.map((e=>f(e,t)))),r}return e}},d=async(e,t,r,n)=>{try{if(((e,t)=>{if(!e.relation)throw new p("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new p(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new p("Join alias must be a string","INVALID_ALIAS")})(r,e),!Array.isArray(t))throw new p("Source data must be an array","INVALID_SOURCE_DATA");let i,o=e[r.relation];return r.query?.filters&&h(r.query.filters)&&(i=((e,t)=>{let r=new Map;return e.forEach((e=>{let n=e[t];r.has(n)||r.set(n,[]),r.get(n).push(e)})),r})(o,r.query.filters.field)),(await Promise.all(t.map((async e=>{let t,s=((e,t)=>{if(!e)return{};let r=f(e.filters,t);return{...e,filters:r}})(r.query,e);return t=s.filters&&h(s.filters)&&i?.has(s.filters.value)?i.get(s.filters.value)||[]:o.filter((e=>n.matcher(e,s.filters))),((e,t,r)=>{let n=r.alias||r.relation;return[{...e,[n]:t}]})(e,await[e=>s.sort?n.sorter(e,s.sort):e,e=>s.projection?n.projector(e,s.projection):e,async e=>s.pagination?await n.paginator(e,s.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),r)})))).flat()}catch(e){throw e instanceof p?e:new p(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},y=async(e,t,r,n)=>r.reduce((async(t,r)=>d(e,await t,r,n)),Promise.resolve(t));function g(){return{join:y}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},b=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function w(e,t,r){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===r?-1:1:"asc"===r?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===r?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===r?e-t:t-e;throw new m(e,t)}function v(e,t){let r=Array.from(e);return 0===t.length?r:r.sort(((e,r)=>{for(let n of t){let{field:t,direction:i}=n,o=e[t],s=r[t];try{if("asc"!==i&&"desc"!==i)throw new b(i);let e=w(o,s,i);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof b?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function j(){return{sort:v}}function q(e){let{resolve:t}=l(e);function r(e,n){let i={};return n.include?.length&&function(e,t,n){for(let i of t)if("string"!=typeof i){for(let[t,o]of Object.entries(i))if(Object.prototype.hasOwnProperty.call(e,t)){let i=r(e[t],o);n[t]=i}}else{let t=i;n[t]=e[t]}}(e,n.include,i),n.exclude?.length&&function(e,t,n){0===Object.keys(n).length&&Object.assign(n,e);for(let e of t)if("string"!=typeof e)for(let[t,i]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,t))continue;let e=n[t];e&&"object"==typeof e?n[t]=r(e,i):delete n[t]}else delete n[e]}(e,n.exclude,i),n.computed?.length&&function(e,r,n){for(let i of r)n[i.alias]=t(e,i)}(e,n.computed,i),i}return{project:r}}async function*S(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:n}=t,i=0,o=n,s=[];for await(let t of e)o<=0&&(yield s,s=[],o=n),i<r?i++:(s.push(t),o--);s.length>0&&(yield s)}(e,t):yield*async function*(e,t,r){let{cursor:n,limit:i,direction:o}=t,s=i,a=void 0===n,c=[];if("forward"===o)for await(let t of e)s<=0&&(yield c,c=[],s=i),a?(c.push(t),s--):a=r(t)===n;else{let t=[];for await(let r of e)t.push(r);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),s--,s<=0&&(yield c,c=[],s=i)):a=r(o)===n}}c.length>0&&(yield c)}(e,t,r)}function E(){return{paginate:S}}}}),p=c(l()),h=c(l()),f=c(u()),d=class t{static dbInstances=new Map;static collectionInstances=new Map;static eventBusMap=new Map;static defaultModelName="stores";static getDatabase(r){const{database:n,enableTelemetry:i=!1,collection:o=t.defaultModelName}=r;if(!t.dbInstances.has(n)){const r=e.DatabaseConnection({name:n,enableTelemetry:i}).then((async t=>{try{await t.createCollection({name:o,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(t){if(t instanceof e.DatabaseError&&"SCHEMA_ALREADY_EXISTS"!==t.type)throw t}return t}));t.dbInstances.set(n,r)}return t.dbInstances.get(n)}static getEventBus(e,r){const n=`${e}_store_${r}`;return t.eventBusMap.has(n)||t.eventBusMap.set(n,(0,h.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:t=>console.error(`Event bus error for ${e}:${r}:`,t),crossTab:!0,channelName:n})),t.eventBusMap.get(n)}static getCollection(e){const{database:r,collection:n=t.defaultModelName}=e,i=`${r}:${n}`;if(!t.collectionInstances.has(i)){const r=t.getDatabase(e).then((e=>e.collection(n)));t.collectionInstances.set(i,r)}return t.collectionInstances.get(i)}static async closeDatabase(e){const r=t.dbInstances.get(e);if(r){(await r).close(),t.dbInstances.delete(e);const n=[];t.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&n.push(r)})),n.forEach((e=>t.collectionInstances.delete(e)));const i=[];t.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>t.eventBusMap.delete(e)))}}static async closeAll(){const e=Array.from(t.dbInstances.keys()).map((e=>t.closeDatabase(e)));await Promise.all(e)}static getActiveDatabases(){return Array.from(t.dbInstances.keys())}};exports.IndexedDBPersistence=class{collection=null;collectionPromise;config;eventBus;initialized=!1;initializationCallbacks=[];getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=d.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=d.getEventBus(this.config.database,this.getStoreName())}async initialize(){try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection?this.collection:this.collectionPromise}async set(e,t){try{const r=await this.getCollection(),n=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),i=await r.find(n.filters),o={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let s;return i?s=await i.update(o):(await r.create(o),s=!0),s&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),s}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _get(){try{const e=await this.getCollection(),t=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return r?r.read().then((()=>r)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.getStoreName()&&n!==e&&t(i)}))}async clear(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));try{const e=await this.collectionPromise,t=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return!r||await r.delete()}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){await d.closeDatabase(this.config.database)}},exports.WebStoragePersistence=class{eventBus;storage;config;constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}initialize(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return;const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}initializeEventBus(){return(0,p.createEventBus)({async:!0,batchSize:5,batchDelay:16,errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e),crossTab:!0,channelName:`storage_${this.getStoreName()}`})}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const r={state:structuredClone(t),version:this.config.version,app:this.config.app},n=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),n),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.config.storageKey&&n!==e&&t(i)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},exports.author="https://github.com/asaidimu";
1
+ "use strict";var e=require("@asaidimu/indexed"),t=Object.create,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,a=(e,t)=>function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports},c=(e,a,c)=>(c=null!=e?t(o(e)):{},((e,t,o,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))s.call(e,c)||c===o||r(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(e&&e.__esModule?c:r(c,"default",{value:e,enumerable:!0}),e)),l=a({"node_modules/@asaidimu/events/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))s.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],n=0,i=0;const o=new Map,s=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{n++,i+=t,o.set(e,(o.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const n=performance.now();try{(s.get(t)||[]).forEach((e=>e(r)))}catch(n){e.errorHandler({...n,eventName:t,payload:r})}c(t,performance.now()-n)}))},u=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(l,e.batchDelay)}})(),h=e=>{const r=t.get(e);r?s.set(e,Array.from(r)):s.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:r}=e.data;(s.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const n=t.get(e);return n.add(r),h(e),()=>{n.delete(r),0===n.size?(t.delete(e),s.delete(e)):h(e)}},emit:({name:t,payload:n})=>{if(e.async)return r.push({name:t,payload:n}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:n}));const i=performance.now();try{(s.get(t)||[]).forEach((e=>e(n))),a&&a.postMessage({name:t,payload:n})}catch(r){e.errorHandler({...r,eventName:t,payload:n})}c(t,performance.now()-i)},getMetrics:()=>({totalEvents:n,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:n>0?i/n:0}),clear:()=>{t.clear(),s.clear(),r=[],n=0,i=0,o.clear(),a&&(a.close(),a=null)}}}}}),u=a({"node_modules/@asaidimu/query/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>g,createMatcher:()=>u,createPaginator:()=>O,createProjector:()=>q,createSorter:()=>j}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!s.call(e,c)&&c!==r&&n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,r){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:r},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,r){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:r}),this}join(e,t,r){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:r,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function l(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?n(t,e):function(e){return"computed"===e?.type}(t)?n(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(i(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>i(e,t)))],["or",(e,t)=>t.some((t=>i(e,t)))],["not",(e,t)=>!t.every((t=>i(e,t)))],["nor",(e,t)=>!t.some((t=>i(e,t)))],["xor",(e,t)=>1===t.filter((t=>i(e,t))).length]]);function n(r,n){let i=r.arguments.map((e=>t(n,e)));if(e[r.function])return e[r.function](...i);throw new Error(`Function ${r.function} not found!`)}function i(n,i){if(function(e){return!!e&&void 0!==e.conditions}(i))return function(e,t){let{operator:n,conditions:i}=t,o=r.get(n);if(o)return o(e,i);throw new Error(`Unsupported logical operator: ${n}`)}(n,i);if(!i||!i.field)return!1;let{field:o,operator:s,value:a}=i,c=n[o],l=t(n,a),u=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),h=e[s]||u.get(s);if(h)return h(c,l);throw new Error(`Unsupported comparison operator: ${s}`)}return{resolve:t,evaluate:i}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function n(e,n){let i=r.get(e);i||(i=new Map,r.set(e,i));let o=JSON.stringify(n);if(i.has(o))return i.get(o);let s=t(e,n);return i.set(o,s),s}return{matcher:n,match:n}}var h=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},p=e=>e&&"field"in e&&"operator"in e&&"value"in e,f=(e,t)=>{if(e){if(p(e)&&e){let r=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:r}}if((e=>"operator"in e&&"conditions"in e)(e)){let r={...e};return e.conditions&&(r.conditions=e.conditions.map((e=>f(e,t)))),r}return e}},d=async(e,t,r,n)=>{try{if(((e,t)=>{if(!e.relation)throw new h("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new h(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new h("Join alias must be a string","INVALID_ALIAS")})(r,e),!Array.isArray(t))throw new h("Source data must be an array","INVALID_SOURCE_DATA");let i,o=e[r.relation];return r.query?.filters&&p(r.query.filters)&&(i=((e,t)=>{let r=new Map;return e.forEach((e=>{let n=e[t];r.has(n)||r.set(n,[]),r.get(n).push(e)})),r})(o,r.query.filters.field)),(await Promise.all(t.map((async e=>{let t,s=((e,t)=>{if(!e)return{};let r=f(e.filters,t);return{...e,filters:r}})(r.query,e);return t=s.filters&&p(s.filters)&&i?.has(s.filters.value)?i.get(s.filters.value)||[]:o.filter((e=>n.matcher(e,s.filters))),((e,t,r)=>{let n=r.alias||r.relation;return[{...e,[n]:t}]})(e,await[e=>s.sort?n.sorter(e,s.sort):e,e=>s.projection?n.projector(e,s.projection):e,async e=>s.pagination?await n.paginator(e,s.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),r)})))).flat()}catch(e){throw e instanceof h?e:new h(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},y=async(e,t,r,n)=>r.reduce((async(t,r)=>d(e,await t,r,n)),Promise.resolve(t));function g(){return{join:y}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},b=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,r){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===r?-1:1:"asc"===r?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===r?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===r?e-t:t-e;throw new m(e,t)}function w(e,t){let r=Array.from(e);return 0===t.length?r:r.sort(((e,r)=>{for(let n of t){let{field:t,direction:i}=n,o=e[t],s=r[t];try{if("asc"!==i&&"desc"!==i)throw new b(i);let e=v(o,s,i);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof b?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function j(){return{sort:w}}function q(e){let{resolve:t}=l(e);function r(e,n){let i={};return n.include?.length&&function(e,t,n){for(let i of t)if("string"!=typeof i){for(let[t,o]of Object.entries(i))if(Object.prototype.hasOwnProperty.call(e,t)){let i=r(e[t],o);n[t]=i}}else{let t=i;n[t]=e[t]}}(e,n.include,i),n.exclude?.length&&function(e,t,n){0===Object.keys(n).length&&Object.assign(n,e);for(let e of t)if("string"!=typeof e)for(let[t,i]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,t))continue;let e=n[t];e&&"object"==typeof e?n[t]=r(e,i):delete n[t]}else delete n[e]}(e,n.exclude,i),n.computed?.length&&function(e,r,n){for(let i of r)n[i.alias]=t(e,i)}(e,n.computed,i),i}return{project:r}}async function*E(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:n}=t,i=0,o=n,s=[];for await(let t of e)o<=0&&(yield s,s=[],o=n),i<r?i++:(s.push(t),o--);s.length>0&&(yield s)}(e,t):yield*async function*(e,t,r){let{cursor:n,limit:i,direction:o}=t,s=i,a=void 0===n,c=[];if("forward"===o)for await(let t of e)s<=0&&(yield c,c=[],s=i),a?(c.push(t),s--):a=r(t)===n;else{let t=[];for await(let r of e)t.push(r);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),s--,s<=0&&(yield c,c=[],s=i)):a=r(o)===n}}c.length>0&&(yield c)}(e,t,r)}function O(){return{paginate:E}}}}),h=c(l()),p=c(l()),f=c(u()),d=class t{static dbInstances=new Map;static collectionInstances=new Map;static eventBusMap=new Map;static defaultModelName="stores";static getDatabase(r){const{database:n,enableTelemetry:i=!1,collection:o=t.defaultModelName}=r;if(!t.dbInstances.has(n)){const r=e.DatabaseConnection({name:n,enableTelemetry:i}).then((async t=>{try{await t.createCollection({name:o,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(t){if(t instanceof e.DatabaseError&&"SCHEMA_ALREADY_EXISTS"!==t.type)throw t}return t}));t.dbInstances.set(n,r)}return t.dbInstances.get(n)}static getEventBus(e,r){const n=`${e}_store_${r}`;return t.eventBusMap.has(n)||t.eventBusMap.set(n,(0,p.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:t=>console.error(`Event bus error for ${e}:${r}:`,t),crossTab:!0,channelName:n})),t.eventBusMap.get(n)}static getCollection(e){const{database:r,collection:n=t.defaultModelName}=e,i=`${r}:${n}`;if(!t.collectionInstances.has(i)){const r=t.getDatabase(e).then((e=>e.collection(n)));t.collectionInstances.set(i,r)}return t.collectionInstances.get(i)}static async closeDatabase(e){const r=t.dbInstances.get(e);if(r){(await r).close(),t.dbInstances.delete(e);const n=[];t.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&n.push(r)})),n.forEach((e=>t.collectionInstances.delete(e)));const i=[];t.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>t.eventBusMap.delete(e)))}}static async closeAll(){const e=Array.from(t.dbInstances.keys()).map((e=>t.closeDatabase(e)));await Promise.all(e)}static getActiveDatabases(){return Array.from(t.dbInstances.keys())}};exports.IndexedDBPersistence=class{collection=null;collectionPromise;config;eventBus;initialized=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=d.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=d.getEventBus(this.config.database,this.getStoreName())}async initialize(){try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection?this.collection:this.collectionPromise}async set(e,t){try{const r=await this.getCollection(),n=await this._read(),i={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return n?o=await n.update(i):(this.doc=await r.create(i),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return this.doc=r,this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.getStoreName()&&n!==e&&t(i)}))}async clear(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){await d.closeDatabase(this.config.database)}},exports.WebStoragePersistence=class{eventBus;storage;config;constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}initialize(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return;const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}initializeEventBus(){return(0,h.createEventBus)({async:!0,batchSize:5,batchDelay:16,errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e),crossTab:!0,channelName:`storage_${this.getStoreName()}`})}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const r={state:structuredClone(t),version:this.config.version,app:this.config.app},n=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),n),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.config.storageKey&&n!==e&&t(i)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}};
package/index.mjs CHANGED
@@ -1 +1 @@
1
- import{DatabaseConnection as e,DatabaseError as t}from"@asaidimu/indexed";var r=Object.create,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,c=(e,t)=>function(){return t||(0,e[o(e)[0]])((t={exports:{}}).exports,t),t.exports},l=(e,t,c)=>(c=null!=e?r(s(e)):{},((e,t,r,s)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))a.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(s=i(t,c))||s.enumerable});return e})(e&&e.__esModule?c:n(c,"default",{value:e,enumerable:!0}),e)),u=c({"node_modules/@asaidimu/events/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))s.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],n=0,i=0;const o=new Map,s=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{n++,i+=t,o.set(e,(o.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const n=performance.now();try{(s.get(t)||[]).forEach((e=>e(r)))}catch(n){e.errorHandler({...n,eventName:t,payload:r})}c(t,performance.now()-n)}))},u=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(l,e.batchDelay)}})(),p=e=>{const r=t.get(e);r?s.set(e,Array.from(r)):s.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:r}=e.data;(s.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const n=t.get(e);return n.add(r),p(e),()=>{n.delete(r),0===n.size?(t.delete(e),s.delete(e)):p(e)}},emit:({name:t,payload:n})=>{if(e.async)return r.push({name:t,payload:n}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:n}));const i=performance.now();try{(s.get(t)||[]).forEach((e=>e(n))),a&&a.postMessage({name:t,payload:n})}catch(r){e.errorHandler({...r,eventName:t,payload:n})}c(t,performance.now()-i)},getMetrics:()=>({totalEvents:n,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:n>0?i/n:0}),clear:()=>{t.clear(),s.clear(),r=[],n=0,i=0,o.clear(),a&&(a.close(),a=null)}}}}}),p=c({"node_modules/@asaidimu/query/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>g,createMatcher:()=>u,createPaginator:()=>O,createProjector:()=>q,createSorter:()=>j}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!s.call(e,c)&&c!==r&&n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,r){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:r},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,r){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:r}),this}join(e,t,r){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:r,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function l(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?n(t,e):function(e){return"computed"===e?.type}(t)?n(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(i(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>i(e,t)))],["or",(e,t)=>t.some((t=>i(e,t)))],["not",(e,t)=>!t.every((t=>i(e,t)))],["nor",(e,t)=>!t.some((t=>i(e,t)))],["xor",(e,t)=>1===t.filter((t=>i(e,t))).length]]);function n(r,n){let i=r.arguments.map((e=>t(n,e)));if(e[r.function])return e[r.function](...i);throw new Error(`Function ${r.function} not found!`)}function i(n,i){if(function(e){return!!e&&void 0!==e.conditions}(i))return function(e,t){let{operator:n,conditions:i}=t,o=r.get(n);if(o)return o(e,i);throw new Error(`Unsupported logical operator: ${n}`)}(n,i);if(!i||!i.field)return!1;let{field:o,operator:s,value:a}=i,c=n[o],l=t(n,a),u=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),p=e[s]||u.get(s);if(p)return p(c,l);throw new Error(`Unsupported comparison operator: ${s}`)}return{resolve:t,evaluate:i}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function n(e,n){let i=r.get(e);i||(i=new Map,r.set(e,i));let o=JSON.stringify(n);if(i.has(o))return i.get(o);let s=t(e,n);return i.set(o,s),s}return{matcher:n,match:n}}var p=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},f=e=>e&&"field"in e&&"operator"in e&&"value"in e,h=(e,t)=>{if(e){if(f(e)&&e){let r=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:r}}if((e=>"operator"in e&&"conditions"in e)(e)){let r={...e};return e.conditions&&(r.conditions=e.conditions.map((e=>h(e,t)))),r}return e}},d=async(e,t,r,n)=>{try{if(((e,t)=>{if(!e.relation)throw new p("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new p(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new p("Join alias must be a string","INVALID_ALIAS")})(r,e),!Array.isArray(t))throw new p("Source data must be an array","INVALID_SOURCE_DATA");let i,o=e[r.relation];return r.query?.filters&&f(r.query.filters)&&(i=((e,t)=>{let r=new Map;return e.forEach((e=>{let n=e[t];r.has(n)||r.set(n,[]),r.get(n).push(e)})),r})(o,r.query.filters.field)),(await Promise.all(t.map((async e=>{let t,s=((e,t)=>{if(!e)return{};let r=h(e.filters,t);return{...e,filters:r}})(r.query,e);return t=s.filters&&f(s.filters)&&i?.has(s.filters.value)?i.get(s.filters.value)||[]:o.filter((e=>n.matcher(e,s.filters))),((e,t,r)=>{let n=r.alias||r.relation;return[{...e,[n]:t}]})(e,await[e=>s.sort?n.sorter(e,s.sort):e,e=>s.projection?n.projector(e,s.projection):e,async e=>s.pagination?await n.paginator(e,s.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),r)})))).flat()}catch(e){throw e instanceof p?e:new p(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},y=async(e,t,r,n)=>r.reduce((async(t,r)=>d(e,await t,r,n)),Promise.resolve(t));function g(){return{join:y}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},b=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function w(e,t,r){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===r?-1:1:"asc"===r?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===r?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===r?e-t:t-e;throw new m(e,t)}function v(e,t){let r=Array.from(e);return 0===t.length?r:r.sort(((e,r)=>{for(let n of t){let{field:t,direction:i}=n,o=e[t],s=r[t];try{if("asc"!==i&&"desc"!==i)throw new b(i);let e=w(o,s,i);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof b?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function j(){return{sort:v}}function q(e){let{resolve:t}=l(e);function r(e,n){let i={};return n.include?.length&&function(e,t,n){for(let i of t)if("string"!=typeof i){for(let[t,o]of Object.entries(i))if(Object.prototype.hasOwnProperty.call(e,t)){let i=r(e[t],o);n[t]=i}}else{let t=i;n[t]=e[t]}}(e,n.include,i),n.exclude?.length&&function(e,t,n){0===Object.keys(n).length&&Object.assign(n,e);for(let e of t)if("string"!=typeof e)for(let[t,i]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,t))continue;let e=n[t];e&&"object"==typeof e?n[t]=r(e,i):delete n[t]}else delete n[e]}(e,n.exclude,i),n.computed?.length&&function(e,r,n){for(let i of r)n[i.alias]=t(e,i)}(e,n.computed,i),i}return{project:r}}async function*N(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:n}=t,i=0,o=n,s=[];for await(let t of e)o<=0&&(yield s,s=[],o=n),i<r?i++:(s.push(t),o--);s.length>0&&(yield s)}(e,t):yield*async function*(e,t,r){let{cursor:n,limit:i,direction:o}=t,s=i,a=void 0===n,c=[];if("forward"===o)for await(let t of e)s<=0&&(yield c,c=[],s=i),a?(c.push(t),s--):a=r(t)===n;else{let t=[];for await(let r of e)t.push(r);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),s--,s<=0&&(yield c,c=[],s=i)):a=r(o)===n}}c.length>0&&(yield c)}(e,t,r)}function O(){return{paginate:N}}}}),f="https://github.com/asaidimu",h=l(u()),d=class{eventBus;storage;config;constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}initialize(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return;const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}initializeEventBus(){return(0,h.createEventBus)({async:!0,batchSize:5,batchDelay:16,errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e),crossTab:!0,channelName:`storage_${this.getStoreName()}`})}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const r={state:structuredClone(t),version:this.config.version,app:this.config.app},n=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),n),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.config.storageKey&&n!==e&&t(i)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},y=l(u()),g=l(p()),m=class r{static dbInstances=new Map;static collectionInstances=new Map;static eventBusMap=new Map;static defaultModelName="stores";static getDatabase(n){const{database:i,enableTelemetry:o=!1,collection:s=r.defaultModelName}=n;if(!r.dbInstances.has(i)){const n=e({name:i,enableTelemetry:o}).then((async e=>{try{await e.createCollection({name:s,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof t&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return e}));r.dbInstances.set(i,n)}return r.dbInstances.get(i)}static getEventBus(e,t){const n=`${e}_store_${t}`;return r.eventBusMap.has(n)||r.eventBusMap.set(n,(0,y.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:r=>console.error(`Event bus error for ${e}:${t}:`,r),crossTab:!0,channelName:n})),r.eventBusMap.get(n)}static getCollection(e){const{database:t,collection:n=r.defaultModelName}=e,i=`${t}:${n}`;if(!r.collectionInstances.has(i)){const t=r.getDatabase(e).then((e=>e.collection(n)));r.collectionInstances.set(i,t)}return r.collectionInstances.get(i)}static async closeDatabase(e){const t=r.dbInstances.get(e);if(t){(await t).close(),r.dbInstances.delete(e);const n=[];r.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&n.push(r)})),n.forEach((e=>r.collectionInstances.delete(e)));const i=[];r.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>r.eventBusMap.delete(e)))}}static async closeAll(){const e=Array.from(r.dbInstances.keys()).map((e=>r.closeDatabase(e)));await Promise.all(e)}static getActiveDatabases(){return Array.from(r.dbInstances.keys())}},b=class{collection=null;collectionPromise;config;eventBus;initialized=!1;initializationCallbacks=[];getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=m.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=m.getEventBus(this.config.database,this.getStoreName())}async initialize(){try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection?this.collection:this.collectionPromise}async set(e,t){try{const r=await this.getCollection(),n=(new g.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),i=await r.find(n.filters),o={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let s;return i?s=await i.update(o):(await r.create(o),s=!0),s&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),s}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _get(){try{const e=await this.getCollection(),t=(new g.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return r?r.read().then((()=>r)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.getStoreName()&&n!==e&&t(i)}))}async clear(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));try{const e=await this.collectionPromise,t=(new g.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return!r||await r.delete()}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){await m.closeDatabase(this.config.database)}};export{b as IndexedDBPersistence,d as WebStoragePersistence,f as author};
1
+ import{DatabaseConnection as e,DatabaseError as t}from"@asaidimu/indexed";var r=Object.create,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,c=(e,t)=>function(){return t||(0,e[o(e)[0]])((t={exports:{}}).exports,t),t.exports},l=(e,t,c)=>(c=null!=e?r(s(e)):{},((e,t,r,s)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))a.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(s=i(t,c))||s.enumerable});return e})(e&&e.__esModule?c:n(c,"default",{value:e,enumerable:!0}),e)),u=c({"node_modules/@asaidimu/events/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))s.call(e,c)||c===r||n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],n=0,i=0;const o=new Map,s=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{n++,i+=t,o.set(e,(o.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const n=performance.now();try{(s.get(t)||[]).forEach((e=>e(r)))}catch(n){e.errorHandler({...n,eventName:t,payload:r})}c(t,performance.now()-n)}))},u=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(l,e.batchDelay)}})(),h=e=>{const r=t.get(e);r?s.set(e,Array.from(r)):s.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:r}=e.data;(s.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const n=t.get(e);return n.add(r),h(e),()=>{n.delete(r),0===n.size?(t.delete(e),s.delete(e)):h(e)}},emit:({name:t,payload:n})=>{if(e.async)return r.push({name:t,payload:n}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:n}));const i=performance.now();try{(s.get(t)||[]).forEach((e=>e(n))),a&&a.postMessage({name:t,payload:n})}catch(r){e.errorHandler({...r,eventName:t,payload:n})}c(t,performance.now()-i)},getMetrics:()=>({totalEvents:n,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:n>0?i/n:0}),clear:()=>{t.clear(),s.clear(),r=[],n=0,i=0,o.clear(),a&&(a.close(),a=null)}}}}}),h=c({"node_modules/@asaidimu/query/index.js"(e,t){var r,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>g,createMatcher:()=>u,createPaginator:()=>E,createProjector:()=>q,createSorter:()=>j}),t.exports=(r=a,((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!s.call(e,c)&&c!==r&&n(e,c,{get:()=>t[c],enumerable:!(a=i(t,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),r));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,r){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:r},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,r){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:r}),this}join(e,t,r){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:r,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function l(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?n(t,e):function(e){return"computed"===e?.type}(t)?n(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(i(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>i(e,t)))],["or",(e,t)=>t.some((t=>i(e,t)))],["not",(e,t)=>!t.every((t=>i(e,t)))],["nor",(e,t)=>!t.some((t=>i(e,t)))],["xor",(e,t)=>1===t.filter((t=>i(e,t))).length]]);function n(r,n){let i=r.arguments.map((e=>t(n,e)));if(e[r.function])return e[r.function](...i);throw new Error(`Function ${r.function} not found!`)}function i(n,i){if(function(e){return!!e&&void 0!==e.conditions}(i))return function(e,t){let{operator:n,conditions:i}=t,o=r.get(n);if(o)return o(e,i);throw new Error(`Unsupported logical operator: ${n}`)}(n,i);if(!i||!i.field)return!1;let{field:o,operator:s,value:a}=i,c=n[o],l=t(n,a),u=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),h=e[s]||u.get(s);if(h)return h(c,l);throw new Error(`Unsupported comparison operator: ${s}`)}return{resolve:t,evaluate:i}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function n(e,n){let i=r.get(e);i||(i=new Map,r.set(e,i));let o=JSON.stringify(n);if(i.has(o))return i.get(o);let s=t(e,n);return i.set(o,s),s}return{matcher:n,match:n}}var h=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},p=e=>e&&"field"in e&&"operator"in e&&"value"in e,f=(e,t)=>{if(e){if(p(e)&&e){let r=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:r}}if((e=>"operator"in e&&"conditions"in e)(e)){let r={...e};return e.conditions&&(r.conditions=e.conditions.map((e=>f(e,t)))),r}return e}},d=async(e,t,r,n)=>{try{if(((e,t)=>{if(!e.relation)throw new h("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new h(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new h("Join alias must be a string","INVALID_ALIAS")})(r,e),!Array.isArray(t))throw new h("Source data must be an array","INVALID_SOURCE_DATA");let i,o=e[r.relation];return r.query?.filters&&p(r.query.filters)&&(i=((e,t)=>{let r=new Map;return e.forEach((e=>{let n=e[t];r.has(n)||r.set(n,[]),r.get(n).push(e)})),r})(o,r.query.filters.field)),(await Promise.all(t.map((async e=>{let t,s=((e,t)=>{if(!e)return{};let r=f(e.filters,t);return{...e,filters:r}})(r.query,e);return t=s.filters&&p(s.filters)&&i?.has(s.filters.value)?i.get(s.filters.value)||[]:o.filter((e=>n.matcher(e,s.filters))),((e,t,r)=>{let n=r.alias||r.relation;return[{...e,[n]:t}]})(e,await[e=>s.sort?n.sorter(e,s.sort):e,e=>s.projection?n.projector(e,s.projection):e,async e=>s.pagination?await n.paginator(e,s.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),r)})))).flat()}catch(e){throw e instanceof h?e:new h(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},y=async(e,t,r,n)=>r.reduce((async(t,r)=>d(e,await t,r,n)),Promise.resolve(t));function g(){return{join:y}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},b=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,r){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===r?-1:1:"asc"===r?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===r?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===r?e-t:t-e;throw new m(e,t)}function w(e,t){let r=Array.from(e);return 0===t.length?r:r.sort(((e,r)=>{for(let n of t){let{field:t,direction:i}=n,o=e[t],s=r[t];try{if("asc"!==i&&"desc"!==i)throw new b(i);let e=v(o,s,i);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof b?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function j(){return{sort:w}}function q(e){let{resolve:t}=l(e);function r(e,n){let i={};return n.include?.length&&function(e,t,n){for(let i of t)if("string"!=typeof i){for(let[t,o]of Object.entries(i))if(Object.prototype.hasOwnProperty.call(e,t)){let i=r(e[t],o);n[t]=i}}else{let t=i;n[t]=e[t]}}(e,n.include,i),n.exclude?.length&&function(e,t,n){0===Object.keys(n).length&&Object.assign(n,e);for(let e of t)if("string"!=typeof e)for(let[t,i]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,t))continue;let e=n[t];e&&"object"==typeof e?n[t]=r(e,i):delete n[t]}else delete n[e]}(e,n.exclude,i),n.computed?.length&&function(e,r,n){for(let i of r)n[i.alias]=t(e,i)}(e,n.computed,i),i}return{project:r}}async function*O(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:n}=t,i=0,o=n,s=[];for await(let t of e)o<=0&&(yield s,s=[],o=n),i<r?i++:(s.push(t),o--);s.length>0&&(yield s)}(e,t):yield*async function*(e,t,r){let{cursor:n,limit:i,direction:o}=t,s=i,a=void 0===n,c=[];if("forward"===o)for await(let t of e)s<=0&&(yield c,c=[],s=i),a?(c.push(t),s--):a=r(t)===n;else{let t=[];for await(let r of e)t.push(r);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),s--,s<=0&&(yield c,c=[],s=i)):a=r(o)===n}}c.length>0&&(yield c)}(e,t,r)}function E(){return{paginate:O}}}}),p=l(u()),f=class{eventBus;storage;config;constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}initialize(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return;const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}initializeEventBus(){return(0,p.createEventBus)({async:!0,batchSize:5,batchDelay:16,errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e),crossTab:!0,channelName:`storage_${this.getStoreName()}`})}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const r={state:structuredClone(t),version:this.config.version,app:this.config.app},n=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),n),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.config.storageKey&&n!==e&&t(i)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},d=l(u()),y=l(h()),g=class r{static dbInstances=new Map;static collectionInstances=new Map;static eventBusMap=new Map;static defaultModelName="stores";static getDatabase(n){const{database:i,enableTelemetry:o=!1,collection:s=r.defaultModelName}=n;if(!r.dbInstances.has(i)){const n=e({name:i,enableTelemetry:o}).then((async e=>{try{await e.createCollection({name:s,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof t&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return e}));r.dbInstances.set(i,n)}return r.dbInstances.get(i)}static getEventBus(e,t){const n=`${e}_store_${t}`;return r.eventBusMap.has(n)||r.eventBusMap.set(n,(0,d.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:r=>console.error(`Event bus error for ${e}:${t}:`,r),crossTab:!0,channelName:n})),r.eventBusMap.get(n)}static getCollection(e){const{database:t,collection:n=r.defaultModelName}=e,i=`${t}:${n}`;if(!r.collectionInstances.has(i)){const t=r.getDatabase(e).then((e=>e.collection(n)));r.collectionInstances.set(i,t)}return r.collectionInstances.get(i)}static async closeDatabase(e){const t=r.dbInstances.get(e);if(t){(await t).close(),r.dbInstances.delete(e);const n=[];r.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&n.push(r)})),n.forEach((e=>r.collectionInstances.delete(e)));const i=[];r.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>r.eventBusMap.delete(e)))}}static async closeAll(){const e=Array.from(r.dbInstances.keys()).map((e=>r.closeDatabase(e)));await Promise.all(e)}static getActiveDatabases(){return Array.from(r.dbInstances.keys())}},m=class{collection=null;collectionPromise;config;eventBus;initialized=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=g.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=g.getEventBus(this.config.database,this.getStoreName())}async initialize(){try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection?this.collection:this.collectionPromise}async set(e,t){try{const r=await this.getCollection(),n=await this._read(),i={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return n?o=await n.update(i):(this.doc=await r.create(i),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new y.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build(),r=await e.find(t.filters);return this.doc=r,this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:n,state:i})=>{r===this.getStoreName()&&n!==e&&t(i)}))}async clear(){this.initialized||await new Promise((e=>{this._onInitialized(e)}));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){await g.closeDatabase(this.config.database)}};export{m as IndexedDBPersistence,f as WebStoragePersistence};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-persistence",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "Persistence utilities.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",