@asaidimu/utils-persistence 2.2.2 → 3.0.0
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 +6 -6
- package/index.d.mts +7 -3
- package/index.d.ts +7 -3
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,7 +112,7 @@ export interface StoreConfig<T> {
|
|
|
112
112
|
*/
|
|
113
113
|
onUpgrade?: (
|
|
114
114
|
state: { data: T | null; version: string; app: string }
|
|
115
|
-
) => { state: T | null; version: string }
|
|
115
|
+
) => Promise<{ state: T | null; version: string }>;
|
|
116
116
|
}
|
|
117
117
|
```
|
|
118
118
|
|
|
@@ -336,7 +336,7 @@ document.body.innerHTML = `
|
|
|
336
336
|
const config: StoreConfig<MyAppState> = {
|
|
337
337
|
version: "1.0.0",
|
|
338
338
|
app: "my-first-app",
|
|
339
|
-
onUpgrade: ({ data, version, app }) => {
|
|
339
|
+
onUpgrade: async ({ data, version, app }) => {
|
|
340
340
|
console.log(`Migrating data for ${app} from version ${version} to 1.0.0. Current data:`, data);
|
|
341
341
|
// Simple example: if data was older, initialize count
|
|
342
342
|
return { state: data ? { ...data, count: data.count ?? 0 } : { data: 'migrated-default', count: 0, lastUpdated: Date.now() }, version: "1.0.0" };
|
|
@@ -538,7 +538,7 @@ const instanceId = uuidv4();
|
|
|
538
538
|
const commonConfig: StoreConfig<UserPreferences> = {
|
|
539
539
|
version: "1.0.0",
|
|
540
540
|
app: "user-dashboard",
|
|
541
|
-
onUpgrade: ({ data, version, app }) => {
|
|
541
|
+
async onUpgrade: ({ data, version, app }) => {
|
|
542
542
|
console.log(`[${app}] Migrating user preferences from version ${version} to 1.0.0.`);
|
|
543
543
|
// Example migration: ensure language is set to default if missing
|
|
544
544
|
if (data && !data.language) {
|
|
@@ -672,7 +672,7 @@ const indexedDBConfig: StoreConfig<Product[]> & IndexedDBPersistenceConfig = {
|
|
|
672
672
|
database: 'my-app-database', // Name of the IndexedDB database
|
|
673
673
|
collection: 'app-stores', // Name of the object store (table-like structure)
|
|
674
674
|
enableTelemetry: false, // Optional: enable telemetry for underlying IndexedDB lib
|
|
675
|
-
onUpgrade: ({ data, version, app }) => {
|
|
675
|
+
async onUpgrade: ({ data, version, app }) => {
|
|
676
676
|
console.log(`[${app}] Migrating product data from version ${version} to 2.0.0.`);
|
|
677
677
|
if (version === "1.0.0" && data) {
|
|
678
678
|
// Example migration from v1.0.0: Add 'lastUpdated' field if it doesn't exist
|
|
@@ -792,7 +792,7 @@ const ephemeralConfig: StoreConfig<SessionData> & { storageKey: string } = {
|
|
|
792
792
|
version: "1.0.0",
|
|
793
793
|
app: "multi-tab-session",
|
|
794
794
|
storageKey: "global-session-state",
|
|
795
|
-
onUpgrade: ({ data, version, app }) => {
|
|
795
|
+
async onUpgrade: ({ data, version, app }) => {
|
|
796
796
|
console.log(`[${app}] Initializing/Migrating ephemeral state from version ${version}.`);
|
|
797
797
|
// For EphemeralPersistence, onUpgrade is called with data: null initially
|
|
798
798
|
return { state: data || { activeUsers: 0, lastActivity: new Date().toISOString(), isPolling: false }, version: "1.0.0" };
|
|
@@ -1035,4 +1035,4 @@ This library leverages and builds upon the excellent work from:
|
|
|
1035
1035
|
|
|
1036
1036
|
* [`@asaidimu/events`](https://github.com/asaidimu/events): For robust cross-tab event communication and asynchronous event bus capabilities.
|
|
1037
1037
|
* [`@asaidimu/indexed`](https://github.com/asaidimu/indexed): For providing a simplified and promise-based interface for IndexedDB interactions.
|
|
1038
|
-
* [`@asaidimu/query`](https://github.com/asaidimu/query): For offering a declarative query builder used internally with IndexedDB operations.
|
|
1038
|
+
* [`@asaidimu/query`](https://github.com/asaidimu/query): For offering a declarative query builder used internally with IndexedDB operations.
|
package/index.d.mts
CHANGED
|
@@ -59,10 +59,10 @@ interface StoreConfig<T> {
|
|
|
59
59
|
data: T | null;
|
|
60
60
|
version: string;
|
|
61
61
|
app: string;
|
|
62
|
-
}) => {
|
|
62
|
+
}) => Promise<{
|
|
63
63
|
state: T | null;
|
|
64
64
|
version: string;
|
|
65
|
-
}
|
|
65
|
+
}>;
|
|
66
66
|
}
|
|
67
67
|
interface SimplePersistence<T> {
|
|
68
68
|
/**
|
|
@@ -144,13 +144,17 @@ declare class WebStoragePersistence<T> implements SimplePersistence<T> {
|
|
|
144
144
|
private readonly eventBus;
|
|
145
145
|
private readonly storage;
|
|
146
146
|
private readonly config;
|
|
147
|
+
private initialized;
|
|
148
|
+
private initializationCallbacks;
|
|
147
149
|
constructor(config: StoreConfig<T> & WebStoragePersistenceConfig);
|
|
148
150
|
private initialize;
|
|
151
|
+
private _onInitialized;
|
|
149
152
|
private initializeEventBus;
|
|
150
153
|
private getStoreName;
|
|
151
154
|
private setupStorageEventListener;
|
|
152
155
|
set(instanceId: string, state: T): boolean;
|
|
153
|
-
|
|
156
|
+
private _get;
|
|
157
|
+
get(): Promise<T | null>;
|
|
154
158
|
subscribe(instanceId: string, onStateChange: (state: T) => void): () => void;
|
|
155
159
|
clear(): boolean;
|
|
156
160
|
stats(): {
|
package/index.d.ts
CHANGED
|
@@ -59,10 +59,10 @@ interface StoreConfig<T> {
|
|
|
59
59
|
data: T | null;
|
|
60
60
|
version: string;
|
|
61
61
|
app: string;
|
|
62
|
-
}) => {
|
|
62
|
+
}) => Promise<{
|
|
63
63
|
state: T | null;
|
|
64
64
|
version: string;
|
|
65
|
-
}
|
|
65
|
+
}>;
|
|
66
66
|
}
|
|
67
67
|
interface SimplePersistence<T> {
|
|
68
68
|
/**
|
|
@@ -144,13 +144,17 @@ declare class WebStoragePersistence<T> implements SimplePersistence<T> {
|
|
|
144
144
|
private readonly eventBus;
|
|
145
145
|
private readonly storage;
|
|
146
146
|
private readonly config;
|
|
147
|
+
private initialized;
|
|
148
|
+
private initializationCallbacks;
|
|
147
149
|
constructor(config: StoreConfig<T> & WebStoragePersistenceConfig);
|
|
148
150
|
private initialize;
|
|
151
|
+
private _onInitialized;
|
|
149
152
|
private initializeEventBus;
|
|
150
153
|
private getStoreName;
|
|
151
154
|
private setupStorageEventListener;
|
|
152
155
|
set(instanceId: string, state: T): boolean;
|
|
153
|
-
|
|
156
|
+
private _get;
|
|
157
|
+
get(): Promise<T | null>;
|
|
154
158
|
subscribe(instanceId: string, onStateChange: (state: T) => void): () => void;
|
|
155
159
|
clear(): boolean;
|
|
156
160
|
stats(): {
|
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)}})(),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}}};
|
|
1
|
+
"use strict";var e=require("@asaidimu/indexed"),t=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,s=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,a=(e,t)=>function(){return t||(0,e[n(e)[0]])((t={exports:{}}).exports,t),t.exports},c=(e,a,c)=>(c=null!=e?t(s(e)):{},((e,t,s,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of n(t))o.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(a=i(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,i=Object.defineProperty,n=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)i(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 s(t))o.call(e,c)||c===r||i(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(i({},"__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=[],i=0,n=0;const s=new Map,o=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)=>{i++,n+=t,s.set(e,(s.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const i=performance.now();try{(o.get(t)||[]).forEach((e=>e(r)))}catch(i){e.errorHandler({...i,eventName:t,payload:r})}c(t,performance.now()-i)}))},u=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(l,e.batchDelay)}})(),h=e=>{const r=t.get(e);r?o.set(e,Array.from(r)):o.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:r}=e.data;(o.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const i=t.get(e);return i.add(r),h(e),()=>{i.delete(r),0===i.size?(t.delete(e),o.delete(e)):h(e)}},emit:({name:t,payload:i})=>{if(e.async)return r.push({name:t,payload:i}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:i}));const n=performance.now();try{(o.get(t)||[]).forEach((e=>e(i))),a&&a.postMessage({name:t,payload:i})}catch(r){e.errorHandler({...r,eventName:t,payload:i})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:i,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:s,averageEmitDuration:i>0?n/i:0}),clear:()=>{t.clear(),o.clear(),r=[],i=0,n=0,s.clear(),a&&(a.close(),a=null)}}}}}),u=a({"node_modules/@asaidimu/query/index.js"(e,t){var r,i=Object.defineProperty,n=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)i(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 s(t))!o.call(e,c)&&c!==r&&i(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(i({},"__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)?i(t,e):function(e){return"computed"===e?.type}(t)?i(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(n(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>n(e,t)))],["or",(e,t)=>t.some((t=>n(e,t)))],["not",(e,t)=>!t.every((t=>n(e,t)))],["nor",(e,t)=>!t.some((t=>n(e,t)))],["xor",(e,t)=>1===t.filter((t=>n(e,t))).length]]);function i(r,i){let n=r.arguments.map((e=>t(i,e)));if(e[r.function])return e[r.function](...n);throw new Error(`Function ${r.function} not found!`)}function n(i,n){if(function(e){return!!e&&void 0!==e.conditions}(n))return function(e,t){let{operator:i,conditions:n}=t,s=r.get(i);if(s)return s(e,n);throw new Error(`Unsupported logical operator: ${i}`)}(i,n);if(!n||!n.field)return!1;let{field:s,operator:o,value:a}=n,c=i[s],l=t(i,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[o]||u.get(o);if(h)return h(c,l);throw new Error(`Unsupported comparison operator: ${o}`)}return{resolve:t,evaluate:n}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function i(e,i){let n=r.get(e);n||(n=new Map,r.set(e,n));let s=JSON.stringify(i);if(n.has(s))return n.get(s);let o=t(e,i);return n.set(s,o),o}return{matcher:i,match:i}}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,i)=>{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 n,s=e[r.relation];return r.query?.filters&&p(r.query.filters)&&(n=((e,t)=>{let r=new Map;return e.forEach((e=>{let i=e[t];r.has(i)||r.set(i,[]),r.get(i).push(e)})),r})(s,r.query.filters.field)),(await Promise.all(t.map((async e=>{let t,o=((e,t)=>{if(!e)return{};let r=f(e.filters,t);return{...e,filters:r}})(r.query,e);return t=o.filters&&p(o.filters)&&n?.has(o.filters.value)?n.get(o.filters.value)||[]:s.filter((e=>i.matcher(e,o.filters))),((e,t,r)=>{let i=r.alias||r.relation;return[{...e,[i]:t}]})(e,await[e=>o.sort?i.sorter(e,o.sort):e,e=>o.projection?i.projector(e,o.projection):e,async e=>o.pagination?await i.paginator(e,o.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,i)=>r.reduce((async(t,r)=>d(e,await t,r,i)),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 i of t){let{field:t,direction:n}=i,s=e[t],o=r[t];try{if("asc"!==n&&"desc"!==n)throw new b(n);let e=w(s,o,n);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,i){let n={};return i.include?.length&&function(e,t,i){for(let n of t)if("string"!=typeof n){for(let[t,s]of Object.entries(n))if(Object.prototype.hasOwnProperty.call(e,t)){let n=r(e[t],s);i[t]=n}}else{let t=n;i[t]=e[t]}}(e,i.include,n),i.exclude?.length&&function(e,t,i){0===Object.keys(i).length&&Object.assign(i,e);for(let e of t)if("string"!=typeof e)for(let[t,n]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(i,t))continue;let e=i[t];e&&"object"==typeof e?i[t]=r(e,n):delete i[t]}else delete i[e]}(e,i.exclude,n),i.computed?.length&&function(e,r,i){for(let n of r)i[n.alias]=t(e,n)}(e,i.computed,n),n}return{project:r}}async function*E(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:i}=t,n=0,s=i,o=[];for await(let t of e)s<=0&&(yield o,o=[],s=i),n<r?n++:(o.push(t),s--);o.length>0&&(yield o)}(e,t):yield*async function*(e,t,r){let{cursor:i,limit:n,direction:s}=t,o=n,a=void 0===i,c=[];if("forward"===s)for await(let t of e)o<=0&&(yield c,c=[],o=n),a?(c.push(t),o--):a=r(t)===i;else{let t=[];for await(let r of e)t.push(r);for(let e=t.length-1;e>=0;e--){let s=t[e];a?(c.push(s),o--,o<=0&&(yield c,c=[],o=n)):a=r(s)===i}}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:i,enableTelemetry:n=!1,collection:s=t.defaultModelName}=r;if(!t.dbInstances.has(i)){const r=e.DatabaseConnection({name:i,enableTelemetry:n}).then((async t=>{try{await t.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(t){if(t instanceof e.DatabaseError&&"SCHEMA_ALREADY_EXISTS"!==t.type)throw t}return t}));t.dbInstances.set(i,r)}return t.dbInstances.get(i)}static getEventBus(e,r){const i=`${e}_store_${r}`;return t.eventBusMap.has(i)||t.eventBusMap.set(i,(0,p.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:t=>console.error(`Event bus error for ${e}:${r}:`,t),crossTab:!0,channelName:i})),t.eventBusMap.get(i)}static getCollection(e){const{database:r,collection:i=t.defaultModelName}=e,n=`${r}:${i}`;if(!t.collectionInstances.has(n)){const r=t.getDatabase(e).then((e=>e.collection(i)));t.collectionInstances.set(n,r)}return t.collectionInstances.get(n)}static async closeDatabase(e){const r=t.dbInstances.get(e);if(r){(await r).close(),t.dbInstances.delete(e);const i=[];t.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&i.push(r)})),i.forEach((e=>t.collectionInstances.delete(e)));const n=[];t.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),n.push(r))})),n.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}=await 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(),i=await this._read(),n={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let s;return i?s=await i.update(n):(this.doc=await r.create(n),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 _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:i,state:n})=>{r===this.getStoreName()&&i!==e&&t(n)}))}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;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async 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}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(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},i=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),i),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}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:i,state:n})=>{r===this.config.storageKey&&i!==e&&t(n)}))}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)}})(),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};
|
|
1
|
+
import{DatabaseConnection as e,DatabaseError as t}from"@asaidimu/indexed";var r=Object.create,i=Object.defineProperty,n=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||i(e,c,{get:()=>t[c],enumerable:!(s=n(t,c))||s.enumerable});return e})(e&&e.__esModule?c:i(c,"default",{value:e,enumerable:!0}),e)),u=c({"node_modules/@asaidimu/events/index.js"(e,t){var r,i=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)i(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||i(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(i({},"__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=[],i=0,n=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)=>{i++,n+=t,o.set(e,(o.get(e)||0)+1)},l=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const i=performance.now();try{(s.get(t)||[]).forEach((e=>e(r)))}catch(i){e.errorHandler({...i,eventName:t,payload:r})}c(t,performance.now()-i)}))},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 i=t.get(e);return i.add(r),h(e),()=>{i.delete(r),0===i.size?(t.delete(e),s.delete(e)):h(e)}},emit:({name:t,payload:i})=>{if(e.async)return r.push({name:t,payload:i}),r.length>=e.batchSize?l():u(),void(a&&a.postMessage({name:t,payload:i}));const n=performance.now();try{(s.get(t)||[]).forEach((e=>e(i))),a&&a.postMessage({name:t,payload:i})}catch(r){e.errorHandler({...r,eventName:t,payload:i})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:i,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:i>0?n/i:0}),clear:()=>{t.clear(),s.clear(),r=[],i=0,n=0,o.clear(),a&&(a.close(),a=null)}}}}}),h=c({"node_modules/@asaidimu/query/index.js"(e,t){var r,i=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var r in t)i(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&&i(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(i({},"__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)?i(t,e):function(e){return"computed"===e?.type}(t)?i(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let r of t.conditions)if(n(e,r.when))return r.then;return t.else}(e,t):t}let r=new Map([["and",(e,t)=>t.every((t=>n(e,t)))],["or",(e,t)=>t.some((t=>n(e,t)))],["not",(e,t)=>!t.every((t=>n(e,t)))],["nor",(e,t)=>!t.some((t=>n(e,t)))],["xor",(e,t)=>1===t.filter((t=>n(e,t))).length]]);function i(r,i){let n=r.arguments.map((e=>t(i,e)));if(e[r.function])return e[r.function](...n);throw new Error(`Function ${r.function} not found!`)}function n(i,n){if(function(e){return!!e&&void 0!==e.conditions}(n))return function(e,t){let{operator:i,conditions:n}=t,o=r.get(i);if(o)return o(e,n);throw new Error(`Unsupported logical operator: ${i}`)}(i,n);if(!n||!n.field)return!1;let{field:o,operator:s,value:a}=n,c=i[o],l=t(i,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:n}}function u(e){let{evaluate:t}=l(e),r=new WeakMap;function i(e,i){let n=r.get(e);n||(n=new Map,r.set(e,n));let o=JSON.stringify(i);if(n.has(o))return n.get(o);let s=t(e,i);return n.set(o,s),s}return{matcher:i,match:i}}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,i)=>{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 n,o=e[r.relation];return r.query?.filters&&p(r.query.filters)&&(n=((e,t)=>{let r=new Map;return e.forEach((e=>{let i=e[t];r.has(i)||r.set(i,[]),r.get(i).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)&&n?.has(s.filters.value)?n.get(s.filters.value)||[]:o.filter((e=>i.matcher(e,s.filters))),((e,t,r)=>{let i=r.alias||r.relation;return[{...e,[i]:t}]})(e,await[e=>s.sort?i.sorter(e,s.sort):e,e=>s.projection?i.projector(e,s.projection):e,async e=>s.pagination?await i.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,i)=>r.reduce((async(t,r)=>d(e,await t,r,i)),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 i of t){let{field:t,direction:n}=i,o=e[t],s=r[t];try{if("asc"!==n&&"desc"!==n)throw new b(n);let e=w(o,s,n);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,i){let n={};return i.include?.length&&function(e,t,i){for(let n of t)if("string"!=typeof n){for(let[t,o]of Object.entries(n))if(Object.prototype.hasOwnProperty.call(e,t)){let n=r(e[t],o);i[t]=n}}else{let t=n;i[t]=e[t]}}(e,i.include,n),i.exclude?.length&&function(e,t,i){0===Object.keys(i).length&&Object.assign(i,e);for(let e of t)if("string"!=typeof e)for(let[t,n]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(i,t))continue;let e=i[t];e&&"object"==typeof e?i[t]=r(e,n):delete i[t]}else delete i[e]}(e,i.exclude,n),i.computed?.length&&function(e,r,i){for(let n of r)i[n.alias]=t(e,n)}(e,i.computed,n),n}return{project:r}}async function*E(e,t,r=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:r,limit:i}=t,n=0,o=i,s=[];for await(let t of e)o<=0&&(yield s,s=[],o=i),n<r?n++:(s.push(t),o--);s.length>0&&(yield s)}(e,t):yield*async function*(e,t,r){let{cursor:i,limit:n,direction:o}=t,s=n,a=void 0===i,c=[];if("forward"===o)for await(let t of e)s<=0&&(yield c,c=[],s=n),a?(c.push(t),s--):a=r(t)===i;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=n)):a=r(o)===i}}c.length>0&&(yield c)}(e,t,r)}function O(){return{paginate:E}}}}),p=l(u()),f=class{eventBus;storage;config;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async 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}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(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},i=JSON.stringify(r);return this.storage.setItem(this.getStoreName(),i),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}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:r,instanceId:i,state:n})=>{r===this.config.storageKey&&i!==e&&t(n)}))}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(i){const{database:n,enableTelemetry:o=!1,collection:s=r.defaultModelName}=i;if(!r.dbInstances.has(n)){const i=e({name:n,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(n,i)}return r.dbInstances.get(n)}static getEventBus(e,t){const i=`${e}_store_${t}`;return r.eventBusMap.has(i)||r.eventBusMap.set(i,(0,d.createEventBus)({batchSize:5,async:!0,batchDelay:16,errorHandler:r=>console.error(`Event bus error for ${e}:${t}:`,r),crossTab:!0,channelName:i})),r.eventBusMap.get(i)}static getCollection(e){const{database:t,collection:i=r.defaultModelName}=e,n=`${t}:${i}`;if(!r.collectionInstances.has(n)){const t=r.getDatabase(e).then((e=>e.collection(i)));r.collectionInstances.set(n,t)}return r.collectionInstances.get(n)}static async closeDatabase(e){const t=r.dbInstances.get(e);if(t){(await t).close(),r.dbInstances.delete(e);const i=[];r.collectionInstances.forEach(((t,r)=>{r.startsWith(`${e}:`)&&i.push(r)})),i.forEach((e=>r.collectionInstances.delete(e)));const n=[];r.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),n.push(r))})),n.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}=await 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(),i=await this._read(),n={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return i?o=await i.update(n):(this.doc=await r.create(n),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:i,state:n})=>{r===this.getStoreName()&&i!==e&&t(n)}))}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};
|