@idb-orm/core 1.0.11 → 1.0.12
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 +185 -9
- package/dist/client/dump.d.ts +27 -0
- package/dist/client/index.d.ts +4 -4
- package/dist/client/restore.d.ts +14 -0
- package/dist/client/types/find.d.ts +5 -5
- package/dist/client/types/index.d.ts +3 -3
- package/dist/client/types/mutation.d.ts +3 -3
- package/dist/core.d.ts +1 -5
- package/dist/error.d.ts +16 -1
- package/dist/field/field-types.d.ts +4 -4
- package/dist/field/index.d.ts +1 -1
- package/dist/field/primary-key.d.ts +8 -1
- package/dist/field/property.d.ts +12 -27
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +2 -2
- package/dist/model/model-types.d.ts +7 -4
- package/dist/model/model.d.ts +1 -1
- package/dist/object-store.d.ts +5 -2
- package/dist/typing/index.d.ts +3 -0
- package/dist/typing/tag.d.ts +89 -0
- package/dist/typing/type.d.ts +37 -0
- package/dist/typing/utils.d.ts +24 -0
- package/dist/util-types.d.ts +4 -0
- package/dist/utils.d.ts +5 -0
- package/package.json +1 -1
- package/dist/dump/class.d.ts +0 -22
- package/dist/dump/json.d.ts +0 -9
- package/dist/field/type-wrapper.d.ts +0 -108
- package/dist/field/validators.d.ts +0 -13
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class e extends Error{code;constructor(e,t){super(`(${e}) ${t}`),this.code=e}}function t(t,r){return class extends e{static code;constructor(e=r){super(t,e)}static of(e){new this(e)}}}const r=t("INVALID_CONFIG","Configuration is invalid"),n=t("INVALID_TX","Transaction is invalid"),s=t("INVALID_ITEM","Item is invalid"),a=t("ASSERTION_FAILED","Assertion failed"),o=t("UNKNOWN","An unknown error occurred"),i=t("DELETE_FAILED","Item could not be deleted"),c=t("NOT_FOUND","Object Store Not Found"),l=t("NOT_FOUND","Document Not Found"),u=t("UPDATE_FAILED","Item could not be updated"),d=t("ADD_FAILED","Item could not be added"),h=t("OPEN_CURSOR","Cursor could not be opened"),y=t("GET_FAILED","Item could not be retrieved"),f=t("OVERWRITE_RELATION","Relation cannot be overwritten"),w=t("EXPORT","Export failed");function p(e,t){return new Promise(t=>{e.onsuccess=()=>{t(e.result)},e.onerror=()=>{}})}function m(e){return Object.keys(e)}function g(e){return Array.isArray(e)||(e=[e]),e}function b(){return crypto.randomUUID()}function S(){return new Date}function A(e){return e}function $(e,t){for(const r of t.keys())e.add(r);return e}class k{static String={tag:0};static Number={tag:1};static Boolean={tag:2};static BigInt={tag:6};static Symbol={tag:5};static File={tag:11};static Date={tag:4};static Unknown={tag:12};static Literal(e){return{tag:3,value:e}}static Array(e){return{tag:7,of:e}}static Set(e){return{tag:8,of:e}}static Union(e){return{tag:9,options:e}}static Optional(e){return{tag:10,of:e}}static Object(e){return{tag:14,props:e}}static Custom({isType:e,serialize:t,deserialize:r}){return{tag:15,isType:e,serialize:t,deserialize:r}}static async serialize(e,t){switch(e.tag){case 3:case 2:case 1:case 6:case 0:return t;case 5:return t.description;case 12:return JSON.stringify(t);case 4:return t.getTime();case 7:{const r=[];for(const n of t)r.push(await k.serialize(e.of,n));return r}case 8:{const r=new Set;for(const n of t)r.add(await k.serialize(e.of,n));return r}case 10:return void 0===t?null:await k.serialize(e.of,t);case 9:for(const r of e.options)if(k.is(r,t))return await k.serialize(r,t);throw new Error("Value union could not be serialized");case 11:if(!(t instanceof File))throw new Error("Value is not a valid file");return{data:new Promise((e,r)=>{const n=new FileReader;n.onload=()=>e(n.result),n.onerror=r,n.readAsDataURL(t)}),name:t.name};case 14:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const r={};for(const n in e.props){const s=e.props[n];if(!(n in t)&&10!==s.tag)throw new Error(`Required property '${n}' not found`);r[n]=await this.serialize(s,t[n])}return r}case 13:return this.serialize(e.of,t);case 15:return e.serialize?await e.serialize(t):JSON.stringify(t)}}static async deserialize(e,t){switch(e.tag){case 3:if(typeof t!=typeof e.value)throw new Error(`'${t}' is not equal to literal '${t}'`);return t;case 2:if("boolean"!=typeof t)throw new Error(`'${t}' is not a boolean`);return t;case 1:if("number"!=typeof t)throw new Error(`'${t}' is not a number`);return t;case 6:if("number"!=typeof t)throw new Error(`'${t}' is not a bigint`);return BigInt(t);case 0:if("string"!=typeof t)throw new Error(`'${t}' is not a string`);return t;case 5:if("string"!=typeof t)throw new Error(`'${t}' is not a symbol`);return Symbol.for(t);case 4:if(!(t instanceof Date))throw new Error(`'${t}' is not a date`);return t;case 7:if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);return t;case 8:if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);return new Set(t);case 10:return k.deserialize(e.of,t);case 12:return JSON.parse(t);case 9:{let r,n=!1;for(const s of e.options){try{r=k.deserialize(s,t),n=!0}catch{n=!1}if(n)break}if(!n)throw new Error("Value did not match the union");return r}case 11:{if(!t||"object"!=typeof t||!("data"in t)||!("name"in t)||"string"!=typeof t.data||"string"!=typeof t.name)throw new Error("Value is not a valid file schema");const e=await fetch(t.data);return new File([await e.blob()],t.name)}case 13:return this.deserialize(e.of,t);case 15:if(e.isType(t))return e.deserialize?await e.deserialize(t):JSON.parse(String(t));throw new Error("Value is not valid");case 14:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const r={};for(const n in e.props){const s=e.props[n];if(!(n in t)&&10!==s.tag)throw new Error(`Required property '${n}' not found`);r[n]=await this.deserialize(s,t[n])}return r}}}static is(e,t){switch(e.tag){case 3:return t===e.value;case 2:return"boolean"==typeof t;case 1:return"number"==typeof t;case 6:return"bigint"==typeof t;case 0:return"string"==typeof t;case 5:return"symbol"==typeof t;case 12:return!0;case 4:return t instanceof Date;case 7:return Array.isArray(t)&&t.every(t=>k.is(e.of,t));case 8:return t instanceof Set&&Array.from(t).every(t=>k.is(e.of,t));case 10:return void 0===t||this.is(e.of,t);case 9:return e.options.some(e=>k.is(e,t));case 11:return t instanceof File;case 14:return!(!t||"object"!=typeof t)&&Object.keys(e.props).every(r=>k.is(e.props[r],t[r]));case 13:return this.is(e.of,t);case 15:return e.isType(t)}}}const R=Object.freeze(Object.defineProperty({__proto__:null,Type:k},Symbol.toStringTag,{value:"Module"}));function v(e){return t=>typeof t===e?{success:!0,data:t}:{success:!1,error:"Value is not a string"}}const O={[k.String.tag]:v("string"),[k.Number.tag]:v("number"),[k.BigInt.tag]:v("bigint"),[k.Boolean.tag]:v("boolean"),[k.Symbol.tag]:v("symbol"),[k.Unknown.tag]:e=>({success:!0,data:e}),[k.Date.tag]:e=>e instanceof Date?isNaN(e.getTime())?{success:!1,error:"Value is not a valid date"}:{success:!0,data:e}:{success:!1,error:"Value is not a date"}},K=Symbol.for("primaryKey");class N{symbol=K;genFn;autoGenerate;type;constructor(e,t){if(e){if(e>k.Date)throw new r("Invalid Primary Key Type");this.type=e,t?(this.autoGenerate=!0,this.genFn=t):this.autoGenerate=!1}else this.autoGenerate=!1,this.type=k.Number}getType(){return this.type}generator(e){return this.genFn=e,this.autoGenerate=!0,this}autoIncrement(){if(this.type===k.Number)return this.genFn=void 0,this.autoGenerate=!0,this;throw new r("Primary key must be a number to use autoIncrement()")}uuid(){if(!window.isSecureContext)throw new Error("Window is not in a secure context");return new N(k.String,b)}date(){return new N(k.Date,S)}genKey(){if(this.genFn)return this.genFn();throw new Error("Generator function not defined")}getSchema(){return O[this.type.tag]}isAutoIncremented(){return this.autoGenerate&&!this.genFn}static is(e){return e?.symbol===K}}class M{constructor(e,t="",r=!1,n=!1,s){this.to=e,this.name=t,this.isOptional=r,this.isArray=n,this.relatedKey="",this.actions={onDelete:s||"Restrict"}}static SYMBOL=Symbol.for("baseRelation");BASE_SYMBOL=M.SYMBOL;actions;relatedKey;getActions(){return{...this.actions}}isNullable(){return this.isArray||this.isOptional}setRelatedKey(e){this.relatedKey=e}getRelatedKey(){return this.relatedKey}toString(){return`${this.isArray?"Array":this.isOptional?"Optional":"Standard"} relation from this model to model '${this.to}' on key '${this.relatedKey}'`}getBaseSymbol(){return this.BASE_SYMBOL}static is(e){return"getBaseSymbol"in e&&e.getBaseSymbol()===M.SYMBOL}}class D extends M{static R_SYMBOL=Symbol.for("relation");symbol=D.R_SYMBOL;constructor(e,t={}){super(e,t.name,!1,!1,t.onDelete)}array({onDelete:e}={}){return new I(this.to,this.name,e)}optional({onDelete:e}={}){return new j(this.to,this.name,e)}onDelete(e){return this.actions.onDelete=e,this}static is(e){return e?.symbol===this.R_SYMBOL}}class I extends M{static A_SYMBOL=Symbol.for("arrayRelation");symbol=I.A_SYMBOL;constructor(e,t,r="None"){super(e,t,!1,!0,r)}static is(e){return e?.symbol===this.A_SYMBOL}}class j extends M{static O_SYMBOL=Symbol.for("optionalRelation");symbol=j.O_SYMBOL;constructor(e,t,r="None"){super(e,t,!0,!1,r)}static is(e){return e?.symbol===this.O_SYMBOL}}var E=(e=>(e[e.Property=0]="Property",e[e.Relation=1]="Relation",e[e.PrimaryKey=2]="PrimaryKey",e[e.Invalid=3]="Invalid",e))(E||{});const x=Symbol.for("property");class T{constructor(e,t,r){this.parseFn=e,this.type=t,this.options={unique:r?.unique??!1}}symbol=x;hasDefault=!1;options;get parse(){return this.parseFn}getType(){return this.type}static array(...e){throw new Error("Method Not Implemented")}static boolean(...e){throw new Error("Method Not Implemented")}static custom(...e){throw new Error("Method Not Implemented")}static date(...e){throw new Error("Method Not Implemented")}static literal(e,...t){throw new Error("Method Not Implemented")}static number(...e){throw new Error("Method Not Implemented")}static union(...e){throw new Error("Method Not Implemented")}static set(...e){throw new Error("Method Not Implemented")}static string(...e){throw new Error("Method Not Implemented")}unique(){switch(this.type){case k.Boolean:case k.String:case k.Number:case k.Symbol:return this.options.unique=!0,this;default:throw new Error("A non-primitive cannot be a unique value")}}hasDefaultValue(){return this.hasDefault}static relation(e,t){return new D(e,t)}static primaryKey(e="number"){return new N(this.nameToType(e))}static nameToType(e){switch(e){case"boolean":return k.Boolean;case"bigint":return k.BigInt;case"number":case"string":return k.Number;case"symbol":return k.Symbol;default:return k.Unknown}}static is(e){return"object"==typeof e&&e?.symbol===x}}class F extends T{array(){return new F(F.generateArrayValidator(this.parseFn),k.Array(this.type),this.options)}default(e){return this.hasDefault=!0,new F(t=>null==t?{success:!0,data:"function"==typeof e?e():e}:this.parseFn(t),this.type,this.options)}optional(){return new F(e=>null==e?{success:!0,data:void 0}:this.parseFn(e),this.type,this.options)}static array(e,t){return new F(F.generateArrayValidator(e.parseFn),k.Array(e.type),t)}static boolean(e){return new F(e=>"boolean"==typeof e?{success:!0,data:e}:{success:!1,error:"Value is not a string"},k.Boolean,e)}static custom(e,t){return new F(e,k.Unknown,t)}static date(e){return new F(O[k.Date.tag],k.Date,e)}static literal(e,t){return new F(t=>t===e?{success:!0,data:e}:{success:!1,error:`${t} !== ${e}`},k.Literal(e),t)}static number(e){return new F(O[k.Number.tag],k.Number,e)}static string(e){return new F(O[k.String.tag],k.String,e)}static set(e,t){return new F(t=>{if(t instanceof Set){const r=new Set;for(const n of t){const t=e.parseFn(n);if(!t.success)return t;r.add(t.data)}return{success:!0,data:r}}return{success:!1,error:"Value is not an array"}},k.Set(e.type),t)}static union(e,t){const r=e.map(e=>e.parse);return new F(e=>{for(const t of r){const r=t(e);if(r.success)return r}return{success:!1,error:"Value did not match any of the items"}},k.Union(e.map(e=>e.getType())),t)}static generateArrayValidator(e){return t=>{if(Array.isArray(t)){const r=[];for(const n of t){const t=e(n);if(!t.success)return t;r.push(t.data)}return{success:!0,data:r}}return{success:!1,error:"Value is not an array"}}}}const P=Symbol.for("model");class _{constructor(t,r){this.name=t,this.fields=r,this.fieldKeys=m(r);for(const e of this.fieldKeys){const t=this.fields[e];M.is(t)&&t.to!==this.name&&this.relationLinks.add(t.to)}const n=this.fieldKeys.find(e=>N.is(this.fields[e]));if(!n)throw new e("INVALID_CONFIG",`Model ${this.name} has no primary key`);this.primaryKey=n}symbol=P;fieldKeys;relationLinks=new Set;cache={};primaryKey;get(e){return this.fields[e]}getPrimaryKey(){return this.fields[this.primaryKey]}getRelation(e){const t=this.fields[e];if(t&&M.is(t))return t}keyType(e){const t=this.fields[e];return t?T.is(t)?E.Property:M.is(t)?E.Relation:N.is(t)?E.PrimaryKey:E.Invalid:E.Invalid}links(){return this.relationLinks.keys()}*relations(){for(const e of this.fieldKeys)M.is(this.fields[e])&&(yield[e,this.fields[e]])}*entries(){for(const e of this.fieldKeys)yield[e,this.fields[e]]}keys(){return[...this.fieldKeys]}parseField(e,t){return T.is(this.fields[e])?this.fields[e].parse(t):null}getDeletedStores(e){if(this.cache.delete)return this.cache.delete;const t=new Set,r=[this.name];let n;for(;r.length>0;){const s=r.shift();if(t.has(s))continue;n=e.getModel(s);const a=n.cache.delete;if(a)$(t,a);else{t.add(s);for(const e of n.links())t.has(e)||r.push(e)}}return this.cache.delete=t,t}static is(e){return e?.symbol===P}}class L{constructor(e,t){this.tx=e,this.store=t}add(e){return this.handleRequest(this.store.add(e),()=>new d)}get(e){return this.handleRequest(this.store.get(e),()=>new y)}async assertGet(e){const t=await this.handleRequest(this.store.get(e),()=>new y);if(!t)throw this.tx.abort(new l);return t}put(e){return this.handleRequest(this.store.put(e),()=>new u)}delete(e){return this.handleRequest(this.store.delete(e),()=>new i)}async openCursor(t,r={}){const n=r.onError||(()=>new h),s=this.store.openCursor(r.query,r.direction);await new Promise((r,a)=>{s.onsuccess=async s=>{try{s.target||a(this.tx.abort(n()));const e=s.target.result;e&&await t(e,this.tx)||r()}catch(i){a(this.tx.abort(i instanceof e?i:new o(String(i))))}},s.onerror=()=>{a(this.tx.abort(n()))}})}handleRequest(e,t){return new Promise(r=>{e.onsuccess=()=>{r(e.result)},e.onerror=()=>{throw this.tx.abort(t())}})}}class B{internal;status;error=null;storeNames;inWrap=!1;onRejection=t=>{throw t instanceof e?this.abort(t):this.abort(new o(String(t)))};objectStores;constructor(e,t,r,n={}){e instanceof B?(this.internal=e.getInternal(),this.storeNames=e.storeNames,this.status=e.status,this.error=e.error,this.objectStores=e.getAllStores()):(this.internal=e.transaction(t,r),this.status=0,this.storeNames=Array.from(this.internal.objectStoreNames),this.objectStores=new Map(this.storeNames.map(e=>[e,this.getObjectstore(e)])),this.internal.onabort=this.registerHandler(1,n.onAbort),this.internal.onerror=this.registerHandler(3,n.onError),this.internal.oncomplete=this.registerHandler(2,n.onComplete))}static create(e,t,r,n){return n||new B(e,t,r)}abort(e){return 1!==this.status&&this.internal.abort(),this.status=1,this.error=e,this.error}commit(){this.internal.commit()}getInternal(){return this.internal}getStore(e){const t=this.objectStores.get(e);if(!t)throw this.abort(new n(`Store '${e}' is not a part of this transaction`));return t}getAllStores(){return this.objectStores}get mode(){return this.internal.mode}is(e){return this.status===e}contains(e){Array.isArray(e)||(e=[e]);for(const t of e)if(!this.internal.objectStoreNames.contains(t))return!1;return!0}assertIsArray(e,t="Value is not an array"){if(!Array.isArray(e))throw this.abort(new a(t))}getObjectstore(e){try{return new L(this,this.internal.objectStore(e))}catch{throw this.abort(new c(`No ObjectStore with the name '${e}' found`))}}registerHandler(e,t=()=>{}){return r=>{this.status=e,t(this,r)}}async wrap(t){if(this.inWrap)return await t(this);this.inWrap=!0;try{const e=await t(this);return this.inWrap=!1,e}catch(r){throw this.inWrap=!1,r instanceof e?this.abort(r):this.abort(new o(JSON.stringify(r)))}}}function V(e){if(!e)return[];const t=[];for(const r in e)if(Object.hasOwn(e,r))switch(typeof e[r]){case"function":t.push([r,!0,e[r]]);break;case"object":if(e[r]instanceof Date){const n=e[r];t.push([r,!0,e=>e instanceof Date&&e.getTime()===n.getTime()])}break;default:t.push([r,!1,e[r]])}return t}function C(e,t){if(!t||"object"!=typeof t)return!1;for(const r of e)if(r[1]){if(!r[2](t[r[0]]))return!1}else if(r[2]!==t[r[0]])return!1;return!0}function z(e,t,r={},n){const a=t.getModel(e);if(r.include&&r.select)throw new s("include and select cannot both be defined");const o=V(r.where),i=r.select?"select":r.include?"include":"";if(i){const e=r[i],n=!!r.select,s=[];for(const r in e)if(Object.hasOwn(e,r)&&e[r])switch(a.keyType(r)){case E.Relation:{const n=a.getRelation(r),o="object"==typeof e[r]?z(n.to,t,e[r]):A,i=n.getRelatedKey();if(n.isArray){const e=async(e,t)=>{const r=[],s=t.getStore(n.to);for(const n of e){const e=await o(await s.assertGet(n),t);e&&(delete e[i],r.push(e))}return r};s.push({key:r,getValue:e})}else{const e=async(e,t)=>await o(await t.getStore(n.to).assertGet(e),t);s.push({key:r,getValue:e})}break}case E.Property:case E.PrimaryKey:n&&s.push({key:r})}return n?async(e,t)=>{if(!C(o,e))return;const r={};for(const{key:n,getValue:a}of s)r[n]=a?await a(e[n],t):e[n];return r}:async(e,t)=>{if(C(o,e)){for(const{key:r,getValue:n}of s)e[r]=await n(e[r],t);return e}}}return e=>C(o,e)?e:void 0}function U(e,t,r,n){const s=new Set([e]);if(r){const a=m(t),o=n.getModel(e);for(const e of a){const a=o.getRelation(e),i=g(t[e]);if(a)for(const e of i)if(e&&"object"==typeof e)for(const t in e)if(Object.hasOwn(e,t))switch(t){case"$connect":case"$connectMany":case"$disconnect":case"$disconnectMany":case"$disconnectAll":s.add(a.to);break;case"$delete":case"$deleteMany":case"$deleteAll":$(s,o.getDeletedStores(n));break;case"$create":$(s,U(a.to,e[t],r,n));break;case"$createMany":e[t].forEach(e=>$(s,U(a.to,e,r,n)));break;case"$update":$(s,U(a.to,e[t].data,r,n));break;case"$updateMany":e[t].forEach(e=>$(s,U(a.to,e.data,r,n)))}}}else{const r=n.getModel(e);for(const e of m(t)){const a=r.getRelation(e);if(a)switch(typeof t[e]){case"object":$(s,U(a.to,q(t[e]),!1,n));break;case"boolean":s.add(a.to)}}}return s}function q(e){return e.select?e.select:e.include?e.include:{}}class G{constructor(e,t,r){this.client=e,this.name=t,this.accessedStores=Array.from(U(t,q(r),!1,this.client)),this.selectClause=z(t,this.client,r)}accessedStores;selectClause;async find(){return await this._find(!1)}async findFirst(){return(await this._find(!0))[0]}async _find(e){const t=this.client.createTransaction("readonly",this.accessedStores);return await t.wrap(async t=>{const r=[],n=t.getStore(this.name);return await n.openCursor(async n=>{const s=await this.selectClause(n.value,t);return s&&r.push(s),(!e||!r.length)&&(n.continue(),!0)}),r})}}function Y(e,t,n){return async s=>{if(!s)return!1;const a=s[e.primaryKey];for(const[o,c]of e.relations()){const{onDelete:l}=c.getActions(),u=s[o],d=t.getModel(c.to);switch(l){case"Cascade":if(c.isArray){n.assertIsArray(u);const e=new Set(u),r=Y(d,t,n),s=n.getStore(c.to);await s.openCursor(async t=>(e.has(t.value[d.primaryKey])&&await r(t.value),t.continue(),!0)).catch(n.onRejection)}else u&&await J(c.to,t,void 0,void 0,{tx:n,singleton:{id:u}});break;case"SetNull":{if(!u)break;const e=g(u),t=n.getStore(c.to),s=c.getRelatedKey(),o=d.getRelation(s);if(!o)throw new r(`Relation '${c.name}' has an invalid relation key '${c.getRelatedKey()}'`);if(!o.isNullable())throw new r(`Key '${s}' on model '${s}': Non-optional relation cannot have the 'SetNull' action`);for(const r of e){const e=await t.get(r);if(!e)continue;const i=e[s];if(o.isArray){n.assertIsArray(i);const e=i.indexOf(a);if(-1===e)continue;i.splice(e,1)}else e[s]=null;await t.put(e)}break}case"Restrict":if(Array.isArray(u)&&u.length>0||u)throw new i(`Key '${o}' on model '${e.name}' deletion is restricted while there is an active relation`)}}return!0}}async function J(e,t,r,n=!1,s={}){const{singleton:a,finalStep:o=!0}=s,i=t.getModel(e),c=s.tx?s.tx.storeNames:Array.from(i.getDeletedStores(t)),l=B.create(t.getDb(),c,"readwrite",s.tx);return await l.wrap(async s=>{const c=s.getStore(e);let l=0;const u=Y(i,t,s);if(a)await u(await c.assertGet(a.id))&&(await c.delete(a.id),l++);else{const e=V(r);let t;await c.openCursor(async r=>{const a=r.value;return C(e,a)&&await u(a)&&(t=p(r.delete()).catch(s.onRejection)),!(n&&l>0)&&(r.continue(),!0)}),t&&o&&await t}return l})}class W{constructor(e,t,r){this.name=e,this.content=t,this.extension=r}download(e=`${this.name}_dump.${this.extension}`,t){const r=URL.createObjectURL(this.toFile(e,t)),n=document.createElement("a");n.href=r,n.download=e,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}}class H extends W{constructor(e,t){super(e,t,"json")}getValue(){return this.content}toFile(e=`${this.name}_dump.json`,t={}){return new File([JSON.stringify(this.content,void 0,4)],e,t)}}class Q extends W{constructor(e,t){super(e,t,"csv")}getValue(){return this.content}toFile(e=`${this.name}_dump.csv`,t){return new File([this.content],e,t)}}function X(e){return"string"!=typeof e?`${e}`:e.replaceAll(/~/g,"~0").replaceAll(/\//g,"~1")}async function Z(e,t,r,n){n=B.create(e.getDb(),[t],"readonly",n);const s=V(r),o=e.getModel(t);return new H(t,await n.wrap(async e=>{const r={};return await e.getStore(t).openCursor(async e=>{if(C(s,e.value)){for(const[t,r]of o.entries())if(M.is(r))if(r.isArray){if(!Array.isArray(e.value[t]))throw new a("Expected array type");const n=[];for(const s of e.value[t])n.push(`/${r.to}/${X(s)}`);e.value[t]=n}else(r.isOptional&&e.value[t]||!r.isNullable())&&(e.value[t]=`/${r.to}/${X(e.value[t])}`);else{if(!F.is(r)&&!N.is(r))throw new w(`Unrecognized model field on key '${t}'`);e.value[t]=await k.serialize(r.getType(),e.value[t])}if(r[e.value[o.primaryKey]])throw new w("Duplicate primary key detected "+JSON.stringify(r));r[e.value[o.primaryKey]]=e.value}return e.continue(),!0}),r}))}class ee{constructor(e,t){this.db=e,this.models=t,this.name=this.db.name,this.version=this.db.version,this.stores={};for(const r of this.models.keys())this.stores[r]=this.createInterface(r)}name;version;stores;getDb(){return this.db}getStore(e){return this.stores[e]}getStoreNames(){return this.models.keys()}createTransaction(e,t,r){return new B(this.db,t,e,r)}async deleteDb(){await p(window.indexedDB.deleteDatabase(this.name))}async dump(e,t){return"json"===e?await async function(e,t){const r={};t=t||e.getStoreNames();const n=e.createTransaction("readonly",t);for(const s of t)r[s]=(await Z(e,s,void 0,n)).getValue();return new H(e.name,r)}(this,t):new Q("d","")}deleteAllStores(){for(const e of this.models.keys())this.db.deleteObjectStore(e)}deleteStore(e){Array.isArray(e)||(e=[e]);for(const t of e)this.db.deleteObjectStore(t)}getModel(e){return this.models.getModel(e)}getAccessedStores(e,t,r,n){return n?n.storeNames:Array.from(U(e,t,r,this))}createInterface(e){return{add:async(t,r)=>await this.add(e,t,{tx:r}),addMany:async(t,r)=>{if(!r){const n=new Set;for(const r of t)$(n,U(e,r,!0,this));r=this.createTransaction("readwrite",Array.from(n))}const n=[];for(const s of t)n.push(await this.add(e,s,{tx:r}));return n},findFirst:async(t,r)=>(await this.find(e,t,!0,{tx:r}))[0],find:async(t,r)=>await this.find(e,t,!1,{tx:r}),get:async t=>{const r=this.createTransaction("readonly",e);return await r.getStore(e).get(t)},update:async(t,r)=>(await this.update(e,{data:r},!0,{singleton:{id:t}}))[0],updateFirst:async(t,r)=>(await this.update(e,t,!0,{tx:r}))[0],updateMany:async(t,r)=>await this.update(e,t,!1,{tx:r}),compileQuery:t=>new G(this,e,t),delete:async t=>await J(e,this,void 0,void 0,{singleton:{id:t}})>0,deleteFirst:async t=>await J(e,this,t,!0)>0,deleteMany:async t=>await J(e,this,t,!1),dump:async(t,r)=>"json"===t?await Z(this,e,r):new Q("","")}}async add(e,t,r={}){let{tx:n}=r;const{relation:a}=r,i=this.getAccessedStores(e,t,!0,n);return n=B.create(this.db,i,"readwrite",n),await n.wrap(async r=>{const n=r.getStore(e),i=this.getModel(e),c=i.getPrimaryKey(),l=a?{[a.key]:i.getRelation(a.key)?.isArray?[a.id]:a.id}:{},u=c.isAutoIncremented()?{...l}:{...l,[i.primaryKey]:t[i.primaryKey]??c.genKey()},d=await n.add(u),h={},y=new Set;for(const a of m(t)){y.add(a);const n=t[a];switch(i.keyType(a)){case E.Invalid:throw new s(`Key '${a}' does ont exist on model '${e}'`);case E.Property:{const e=i.parseField(a,n);if(!e)throw new o;if(!e.success)throw new s(`Key '${a}' has the following validation error: ${e.error}`);h[a]=e.data;break}case E.Relation:{if(!n)continue;const e=g(n),t=i.getRelation(a);if(t.isArray&&(h[a]=[],"$createMany"in n||"$connectMany"in n)){const t=[];for(const e of n.$createMany??[])t.push({$create:e});for(const e of n.$connectMany??[])t.push({$connect:e});e.push(...t)}const o=this.getModel(t.to).getRelation(t.getRelatedKey()),c=new Set;for(const n of e){const e=m(n)[0];if(!e)throw new s(`Key '${a}' cannot be an empty connection object`);switch(e){case"$connect":{const i=n[e];if(c.has(i))throw new s(`Primary key '${i}' was already used for a connection`);if(c.add(i),!o)throw new s(`Could not find corresponding relation '${t.name}'`);await this.connectDocument(t,d,i,r),t.isArray?h[a].push(i):h[a]=i;break}case"$create":{const s=await this.add(t.to,n[e],{tx:r,relation:{id:d,key:t.getRelatedKey()}});t.isArray?h[a].push(s):h[a]=s;break}case"$connectMany":case"$createMany":break;default:throw new s(`Connection Object on key '${a}' has an unknown key '${e}'`)}if(!t.isArray)break}break}case E.PrimaryKey:}}const f=Array.from(new Set(i.keys()).difference(y));for(const e of f)switch(i.keyType(e)){case E.Property:{const t=i.parseField(e,void 0);if(!t)throw new o("A parsing error occurred");if(!t.success)throw new s(`Key '${e}' is missing`);h[e]=t.data;break}case E.Relation:{const t=i.getRelation(e),r=l[e];if(t.isArray)h[e]=r??[];else if(t.isOptional)h[e]=r??null;else{if(!r)throw new s(`Required relation '${e}' is not defined`);h[e]=r}break}case E.Invalid:case E.PrimaryKey:}return await n.put({[i.primaryKey]:d,...h})})}async clear(e,t){await J(e,this,void 0,!1,t)}async find(e,t,r,n={}){let{tx:s}=n;const a=this.getAccessedStores(e,q(t),!1,s);s=B.create(this.db,a,"readonly",s);const o=[];return await s.wrap(async n=>{const s=n.getStore(e),a=z(e,this,t);return await s.openCursor(async e=>{const t=await a(e.value,n);return t&&o.push(t),(!r||!o.length)&&(e.continue(),!0)}),o})}async update(e,t,r,n={}){const{singleton:a}=n,i=n.singleton?t:t.data,c=this.getAccessedStores(e,i,!0,n.tx),d=B.create(this.db,c,"readwrite",n.tx);return await d.wrap(async n=>{const c=n.getStore(e),d=this.getModel(e),h=[];for(const e of m(i))switch(d.keyType(e)){case E.Property:h.push({key:e,isRelation:!1,updateFn:"function"==typeof i[e]?i[e]:()=>i[e]});break;case E.Relation:{const t=g(i[e]);if(!t)continue;const r=[];for(const e of t)for(const t in e){switch(t){case"$createMany":case"$connectMany":case"$updateMany":case"$deleteMany":case"$disconnectMany":{const n=t.substring(0,t.length-4);for(const s of e[t])r.push([n,s]);break}default:r.push([t,e[t]])}break}h.push({actions:r,key:e,isRelation:!0,relation:d.getRelation(e)});break}case E.PrimaryKey:throw new u("Primary key field cannot be updated");case E.Invalid:default:throw new o(`Unknown key '${e}'`)}const y=[],f=async e=>{const t=e[d.primaryKey];for(const{key:r,...a}of h){const o=a.relation;if(a.isRelation)for(const[i,c]of a.actions)switch(i){case"$connect":e[r]&&!o.isArray&&await this.disconnectDocument(o,t,e[r],n).catch(n.onRejection),await this.connectDocument(o,t,c,n).catch(n.onRejection),o.isArray?e[r].push(c):e[r]=c;break;case"$create":{const s=await this.add(o.to,c,{tx:n,relation:{id:t,key:o.getRelatedKey()}});o.isArray?e[r].push(s):e[r]=s;break}case"$delete":if(!o.isNullable())throw new s("Item cannot be deleted, relation is required");e[r]=o.isArray&&Array.isArray(e[r])?e[r].filter(e=>e!==c):null,await J(o.to,this,{},!0,{tx:n,singleton:{id:c}});break;case"$disconnect":{if(!o.isNullable())throw new s("Item cannot be disconnected, relation is required");if(!e[r]||0===e[r]?.lenth)break;const a=this.getModel(o.to).getRelation(o.getRelatedKey());await this.disconnectDocument(o,t,a.isArray?c:e[r],n).catch(n.onRejection),e[r]=o.isArray&&Array.isArray(e[r])?e[r].filter(e=>e!==c):null;break}case"$update":o.isArray?await this.update(o.to,c,!1,{tx:n}):null!=e[r]&&await this.update(o.to,c,!1,{tx:n,singleton:{id:t}});break;case"$deleteAll":if(c&&o.isArray&&Array.isArray(e[r])){const t=this.getModel(o.to),s=new Set(e[r]);await J(o.to,this,{[t.primaryKey]:e=>s.has(e)},!1,{tx:n}),e[r]=[]}break;case"$disconnectAll":if(c&&o.isArray&&Array.isArray(e[r])){for(const s of e[r])await this.disconnectDocument(o,t,s,n);e[r]=[]}}else e[r]=a.updateFn(e[r])}return e};if(a){const e=await c.get(a.id);if(!e)throw new l(`${d.name} with priamry key '${a.id}' not found`);const t=await f(e).catch(n.onRejection);return await c.put(t),[t]}{const e=V(t.where);return await c.openCursor(async t=>{const s=t.value;if(C(e,s)){const e=await f(s).catch(n.onRejection);if(await p(t.update(e)).then(()=>y.push(e)).catch(n.onRejection),r)return!1}return t.continue(),!0}),y}})}async connectDocument(e,t,r,n){const s=n.getStore(e.to),a=await s.get(r);if(!a)throw new l(`Document with Primary Key '${r}' could not be found in model '${e.to}'`);const o=e.getRelatedKey(),i=this.getModel(e.to).getRelation(o),c=a[o];if(i.isArray&&Array.isArray(c))c.includes(t)||c.push(t);else{if(c)throw new f;a[o]=t}return await s.put(a).catch(n.onRejection),r}async disconnectDocument(e,t,r,n){const s=n.getStore(e.to),a=await s.get(r);if(!a)throw new l(`Document with Primary Key '${r}' could not be found in model '${e.to}'`);const o=this.getModel(e.to).getRelation(e.getRelatedKey());if(o.isArray)a[e.getRelatedKey()].filter(e=>e!==t);else{if(!o.isOptional)throw new f;a[e.getRelatedKey()]=null}return await s.put(a).catch(n.onRejection),r}}class te{constructor(e,t){this.name=e,this.models=t,this.modelKeys=m(this.models),this.schemas={};for(const n of this.modelKeys){const e=this.models[n],t={};for(const s of e.keys()){const a=e.get(s);if(T.is(a))t[s]=a.parse;else if(M.is(a)){const{onDelete:o}=a.getActions(),i=this.models[a.to],c=i.getPrimaryKey();t[s]=O[c.type.tag],a.isOptional?t[s]=new F(t[s],c.type).optional().parse:a.isArray&&(t[s]=t[s]=new F(t[s],c.type).array().parse);let l=!!a.getRelatedKey();if(!l)for(const[t,n]of i.relations())if(s!==t&&n.to===e.name&&n.name===a.name){if(l=!0,a.setRelatedKey(t),n.setRelatedKey(s),"SetNull"===o&&!n.isNullable())throw new r(`Key '${t}' on model '${i.name}': Non-optional relation cannot have the 'SetNull' action`);break}if(!l)throw new r(`Relation '${a.name}' of model ${n} does not have an equivalent relation on model '${a.to}'`)}else{if(!N.is(a))throw new r(`Unknown field value detected: ${JSON.stringify(a)}`);t[s]=O[a.type.tag]}}this.schemas[n]=t}}schemas;modelKeys;getModel(e){return this.models[e]}async createClient(e=1){const t=window.indexedDB.open(this.name,e);t.onupgradeneeded=e=>{const t=e.target.result;for(const r of this.modelKeys){const e=this.models[r];t.objectStoreNames.contains(e.name)||t.createObjectStore(e.name,{autoIncrement:e.getPrimaryKey().isAutoIncremented(),keyPath:e.primaryKey})}};const r=await p(t);return new ee(r,this)}keys(){return[...this.modelKeys]}}const re=Object.freeze(Object.defineProperty({__proto__:null,AbstractProperty:T,ArrayRelation:I,BaseRelation:M,DbClient:ee,FieldTypes:E,Model:_,OptionalRelation:j,PrimaryKey:N,Property:F,Relation:D,Type:k,Typing:R,VALIDATORS:O},Symbol.toStringTag,{value:"Module"}));exports.Builder=class{constructor(e,t){this.name=e,this.names=t,this.models={}}models;defineModel(e,t){if("object"==typeof e&&_.is(e))return this.models[e.name]=e,e;{if(!t)throw new Error("Model Fields must be defined");const r=new _(e,t);return this.models[e]=r,r}}compile(e){return new te(this.name,e)}},exports.CompiledQuery=G,exports.Model=_,exports.Property=F,exports.StoreError=e,exports.core=re;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class e extends Error{code;constructor(e,t){super(`(${e}) ${t}`),this.code=e}}function t(t,n){return class extends e{static code;constructor(e=n){super(t,e)}static of(e){new this(e)}}}const n=t("INVALID_CONFIG","Configuration is invalid"),r=t("INVALID_TX","Transaction is invalid"),s=t("INVALID_ITEM","Item is invalid"),o=t("ASSERTION_FAILED","Assertion failed"),a=t("UNKNOWN","An unknown error occurred"),i=t("DELETE_FAILED","Item could not be deleted"),c=t("NOT_FOUND","Object Store Not Found"),u=t("NOT_FOUND","Document Not Found"),l=t("UPDATE_FAILED","Item could not be updated"),d=t("ADD_FAILED","Item could not be added"),y=t("OPEN_CURSOR","Cursor could not be opened"),f=t("GET_FAILED","Item could not be retrieved"),h=t("OVERWRITE_RELATION","Relation cannot be overwritten"),w=t("EXPORT","Export failed");function p(e,t){return new Promise(t=>{e.onsuccess=()=>{t(e.result)},e.onerror=()=>{}})}function m(e){return Object.keys(e)}function g(e){return Array.isArray(e)||(e=[e]),e}function b(){return crypto.randomUUID()}function S(){return new Date}function A(e){return e}function v(e,t){for(const n of t.keys())e.add(n);return e}var $=(e=>(e[e.string=0]="string",e[e.number=1]="number",e[e.date=2]="date",e[e.boolean=3]="boolean",e[e.symbol=4]="symbol",e[e.bigint=5]="bigint",e[e.file=6]="file",e[e.void=7]="void",e[e.unknown=8]="unknown",e[e.literal=9]="literal",e[e.array=10]="array",e[e.set=11]="set",e[e.union=12]="union",e[e.optional=13]="optional",e[e.default=14]="default",e[e.object=15]="object",e[e.custom=16]="custom",e))($||{});const k={};function R(e){const t=k[e];return t||(k[e]={tag:e})}function O(){return R($.string)}function j(){return R($.number)}function K(){return R($.boolean)}function N(){return R($.bigint)}function M(){return R($.symbol)}function D(){return R($.file)}function T(){return R($.date)}function x(){return R($.unknown)}function E(e){return{tag:$.literal,value:e}}function I(e){return{tag:$.array,of:e}}function P(e,t){return{tag:$.default,of:e,value:t}}function _(e){return{tag:$.set,of:e}}function F(e){return{tag:$.union,options:e}}function L(e){return{tag:$.optional,of:e}}function C(e){return{tag:$.custom,...e}}const B=Object.freeze(Object.defineProperty({__proto__:null,Array:I,BigInt:N,Boolean:K,Custom:C,Date:T,Default:P,File:D,Literal:E,Number:j,Object:function(e){return{tag:$.object,props:e}},Optional:L,Set:_,String:O,Symbol:M,Union:F,Unknown:x,Void:function(){return R($.void)},getType:R},Symbol.toStringTag,{value:"Module"}));function V(e){switch(e.tag){case $.void:return"void";case $.literal:return String(e.value);case $.boolean:return"boolean";case $.number:return"number";case $.bigint:return"bigint";case $.string:return"string";case $.symbol:return"symbol";case $.unknown:return"unknown";case $.date:return"Date";case $.array:return`Array<${V(e.of)}>`;case $.set:return`Set<${V(e.of)}>`;case $.default:case $.optional:return`${V(e.of)} | undefined`;case $.union:return`Union<${e.options.map(e=>V(e)).join(", ")}>`;case $.file:return"File";case $.object:return`{${Object.keys(e.props).map(t=>`${t}: ${V(e.props[t])}`).join(",\n")}}`;case $.custom:return"custom"}}async function q(e,t){if(!G(e,t))throw new Error(`Value not of the proper type, expected type '${V(e)}', received '${JSON.stringify(t)}'`);switch(e.tag){case $.literal:case $.boolean:case $.number:case $.string:return t;case $.void:return;case $.bigint:return Number(t);case $.symbol:return t.description;case $.unknown:return JSON.stringify(t);case $.date:return t.getTime();case $.array:{const n=[];for(const r of t)n.push(q(e.of,r));return await Promise.all(n)}case $.set:{const n=[];for(const r of t.keys())n.push(q(e.of,r));return await Promise.all(n)}case $.optional:if(void 0===t)return;return await q(e.of,t);case $.union:for(const n of e.options)try{return await q(n,t)}catch{}throw new Error("Value union could not be serialized");case $.file:if(!(t instanceof File))throw new Error("Value is not a valid file");return{data:new Promise((e,n)=>{const r=new FileReader;r.onload=()=>e(r.result),r.onerror=n,r.readAsDataURL(t)}),name:t.name,type:t.type};case $.object:{const n={};for(const r in e.props){const s=e.props[r];if(!(r in t)&&s.tag!==$.optional&&s.tag!==$.default&&s.tag!==$.void)throw new Error(`Required property '${r}' not found`);n[r]=await q(s,t[r])}return n}case $.default:return await q(e.of,void 0===t?"function"==typeof e.value?e.value():e.value:t);case $.custom:return e.serialize?await e.serialize(t):JSON.stringify(t)}}async function U(e,t){switch(e.tag){case $.void:return;case $.literal:if(t!==e.value)throw new Error(`'${t}' is not equal to literal '${t}'`);return t;case $.boolean:if("boolean"!=typeof t)throw new Error(`'${t}' is not a boolean`);return t;case $.number:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a number`);return t;case $.bigint:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a bigint`);return BigInt(t);case $.string:if("string"!=typeof t)throw new Error(`'${t}' is not a string`);return t;case $.symbol:if("string"!=typeof t)throw new Error(`'${t}' is not a symbol`);return Symbol.for(t);case $.date:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a date timestamp`);return new Date(t);case $.array:{if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);const n=[];for(const r of t)n.push(U(e.of,r));return await Promise.all(n)}case $.set:{if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);const n=[];for(const r of t)n.push(U(e.of,r));return new Set(await Promise.all(n))}case $.optional:if(void 0===t)return;return U(e.of,t);case $.unknown:return"string"!=typeof t?t:JSON.parse(t);case $.union:for(const n of e.options)try{return await U(n,t)}catch{}throw new Error("Value did not match the union");case $.file:{if(!(t&&"object"==typeof t&&"data"in t&&"name"in t&&"type"in t&&"string"==typeof t.data&&"string"==typeof t.name&&"string"==typeof t.type))throw new Error("Value is not a valid file schema");const e=Buffer.from(t.data.replace(/^data:.+;base64,/,""),"base64");return new File([e],t.name,{type:t.type})}case $.default:return void 0===t?e.value:U(e.of,t);case $.custom:if(e.isType(t))return e.deserialize?await e.deserialize(t):JSON.parse(String(t));throw new Error("Value is not valid");case $.object:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const n={};for(const r in e.props){const s=e.props[r];if(!(r in t)&&s.tag!==$.optional)throw new Error(`Required property '${r}' not found`);n[r]=await U(s,t[r])}return n}}}function z(e,t){switch(e.tag){case $.literal:return t.tag===$.literal&&t.value===e.value;case $.boolean:case $.number:case $.symbol:case $.string:case $.bigint:return t.tag===e.tag||t.tag===$.literal&&typeof t.value===V(e);case $.unknown:return!0;case $.date:case $.file:case $.void:return t.tag===e.tag;case $.optional:case $.default:case $.set:case $.array:return t.tag===e.tag&&z(e.of,t.of);case $.union:if(t.tag===$.union){for(const n of t.options)if(!z(e,n))return!1;return!0}return e.options.some(e=>z(e,t));case $.object:if(t.tag!==$.object)return!1;for(const n in t.props){if(!e.props[n])return!1;if(!z(e.props[n],t.props[n]))return!1}return!0;case $.custom:return e===t}}function G(e,t){switch(e.tag){case $.void:return void 0===t;case $.literal:return t===e.value;case $.boolean:return"boolean"==typeof t;case $.number:return"number"==typeof t;case $.bigint:return"bigint"==typeof t;case $.string:return"string"==typeof t;case $.symbol:return"symbol"==typeof t;case $.unknown:return!0;case $.date:return t instanceof Date&&!isNaN(t.getTime());case $.array:return Array.isArray(t)&&t.every(t=>G(e.of,t));case $.set:return t instanceof Set&&Array.from(t).every(t=>G(e.of,t));case $.optional:case $.default:return void 0===t||G(e.of,t);case $.union:return e.options.some(e=>G(e,t));case $.file:return t instanceof File;case $.object:return!(!t||"object"!=typeof t)&&Object.keys(e.props).every(n=>G(e.props[n],t[n]));case $.custom:return e.isType(t)}}function Y(e,t){if(G(e,t)){switch(e.tag){case $.custom:if(e.parse)try{return{success:!0,data:e.parse(t)}}catch(n){return{success:!1,error:String(n)}}break;case $.default:return void 0===t?{success:!0,data:e.value}:{success:!0,data:t}}return{success:!0,data:t}}return{success:!1,error:`Value is not a valid '${V(e)}'`}}const J=Object.freeze(Object.defineProperty({__proto__:null,Tag:$,Type:B,deserializeType:U,isSubtype:z,isType:G,parseType:Y,serializeType:q,typeToString:V},Symbol.toStringTag,{value:"Module"})),W=Symbol.for("primaryKey");class H{symbol=W;genFn;autoGenerate;type;constructor(e,t){if(e){if(e.tag>$.date)throw new n("Invalid Primary Key Type");this.type=e,t?(this.autoGenerate=!0,this.genFn=t):this.autoGenerate=!1}else this.autoGenerate=!1,this.type=j()}getType(){return this.type}generator(e){return this.genFn=e,this.autoGenerate=!0,this}autoIncrement(){if(this.type.tag===$.number)return this.genFn=void 0,this.autoGenerate=!0,this;throw new n("Primary key must be a number to use autoIncrement()")}uuid(){if(!window.isSecureContext)throw new Error("Window is not in a secure context");return new H(O(),b)}date(){return new H(T(),S)}genKey(){if(this.genFn)return this.genFn();throw new Error("Generator function not defined")}isAutoIncremented(){return this.autoGenerate&&!this.genFn}static is(e){return e?.symbol===W}static compareKeyValue(e,t){if(typeof e!=typeof t)return!1;switch(typeof e){case"string":case"number":return e===t;case"object":return e.getTime()===t.getTime();default:return!1}}static validKeyTag=F([O(),j(),T()])}class Q{constructor(e,t="",n=!1,r=!1,s){this.to=e,this.name=t,this.isOptional=n,this.isArray=r,this.relatedKey="",this.actions={onDelete:s||"Restrict"}}static SYMBOL=Symbol.for("baseRelation");BASE_SYMBOL=Q.SYMBOL;actions;relatedKey;getActions(){return{...this.actions}}isNullable(){return this.isArray||this.isOptional}setRelatedKey(e){this.relatedKey=e}getRelatedKey(){return this.relatedKey}toString(){return`${this.isArray?"Array":this.isOptional?"Optional":"Standard"} relation from this model to model '${this.to}' on key '${this.relatedKey}'`}getBaseSymbol(){return this.BASE_SYMBOL}static is(e){return"getBaseSymbol"in e&&e.getBaseSymbol()===Q.SYMBOL}}class X extends Q{static R_SYMBOL=Symbol.for("relation");symbol=X.R_SYMBOL;constructor(e,t={}){super(e,t.name,!1,!1,t.onDelete)}array({onDelete:e}={}){return new Z(this.to,this.name,e)}optional({onDelete:e}={}){return new ee(this.to,this.name,e)}onDelete(e){return this.actions.onDelete=e,this}static is(e){return e?.symbol===this.R_SYMBOL}}class Z extends Q{static A_SYMBOL=Symbol.for("arrayRelation");symbol=Z.A_SYMBOL;constructor(e,t,n="None"){super(e,t,!1,!0,n)}static is(e){return e?.symbol===this.A_SYMBOL}}class ee extends Q{static O_SYMBOL=Symbol.for("optionalRelation");symbol=ee.O_SYMBOL;constructor(e,t,n="None"){super(e,t,!0,!1,n)}static is(e){return e?.symbol===this.O_SYMBOL}}var te=(e=>(e[e.Property=0]="Property",e[e.Relation=1]="Relation",e[e.PrimaryKey=2]="PrimaryKey",e[e.Invalid=3]="Invalid",e))(te||{});const ne=Symbol.for("property");class re{constructor(e,t){this.type=e,this.options={unique:t?.unique??!1}}symbol=ne;hasDefault=!1;options;unique(){switch(this.type.tag){case $.boolean:case $.string:case $.number:case $.symbol:return this.options.unique=!0,this;default:throw new Error("A non-primitive cannot be a unique value")}}hasDefaultValue(){return this.hasDefault}static relation(e,t){return new X(e,t)}static primaryKey(e="number"){return new H(this.nameToType(e))}static nameToType(e){switch(e){case"boolean":return K();case"bigint":return N();case"number":return j();case"string":return O();case"symbol":return M();default:return x()}}static is(e){return"object"==typeof e&&e?.symbol===ne}array(){return new re(I(this.type),this.options)}default(e){return this.hasDefault=!0,new re(P(this.type,e),this.options)}optional(){return new re(L(this.type),this.options)}static array(e,t){return new re(I(e.type),t)}static boolean(e){return new re(K(),e)}static custom(e,t){return new re(C({isType:t=>e(t).success,serialize:t?.serialize,deserialize:t?.deserialize}),t)}static date(e){return new re(T(),e)}static file(e){return new re(D(),e)}static literal(e,t){return new re(E(e),t)}static number(e){return new re(j(),e)}static string(e){return new re(O(),e)}static set(e,t){return new re(_(e.type),t)}static union(e,t){return new re(F(e.map(e=>e.type)),t)}static generateArrayValidator(e){return t=>{if(Array.isArray(t)){const n=[];for(const r of t){const t=e(r);if(!t.success)return t;n.push(t.data)}return{success:!0,data:n}}return{success:!1,error:"Value is not an array"}}}}const se=Symbol.for("model");class oe{constructor(t,n){this.name=t,this.fields=n,this.fieldKeys=m(n);for(const e of this.fieldKeys){const t=this.fields[e];Q.is(t)&&t.to!==this.name&&this.relationLinks.add(t.to)}const r=this.fieldKeys.find(e=>H.is(this.fields[e]));if(!r)throw new e("INVALID_CONFIG",`Model ${this.name} has no primary key`);this.primaryKey=r}symbol=se;fieldKeys;relationLinks=new Set;cache={};primaryKey;get(e){return this.fields[e]}getPrimaryKey(){return this.fields[this.primaryKey]}getRelation(e){const t=this.fields[e];if(t&&Q.is(t))return t}keyType(e){const t=this.fields[e];return t?re.is(t)?te.Property:Q.is(t)?te.Relation:H.is(t)?te.PrimaryKey:te.Invalid:te.Invalid}links(){return this.relationLinks.keys()}*relations(){for(const e of this.fieldKeys)Q.is(this.fields[e])&&(yield[e,this.fields[e]])}*entries(){for(const e of this.fieldKeys)yield[e,this.fields[e]]}keys(){return this.fieldKeys}parseField(e,t){return re.is(this.fields[e])?Y(this.fields[e].type,t):null}getDeletedStores(e){if(this.cache.delete)return this.cache.delete;const t=new Set,n=[this.name];let r;for(;n.length>0;){const s=n.shift();if(t.has(s))continue;r=e.getModel(s);const o=r.cache.delete;if(o)v(t,o);else{t.add(s);for(const e of r.links())t.has(e)||n.push(e)}}return this.cache.delete=t,t}static is(e){return e?.symbol===se}}class ae{constructor(e,t){this.tx=e,this.internal=t}add(e){return this.handleRequest(this.internal.add(e),()=>new d)}get(e){return this.handleRequest(this.internal.get(e),()=>new f)}async assertGet(e){const t=await this.handleRequest(this.internal.get(e),()=>new f);if(!t)throw this.tx.abort(new u);return t}put(e){return this.handleRequest(this.internal.put(e),()=>new l)}delete(e){return this.handleRequest(this.internal.delete(e),()=>new i)}async openCursor(t,n={}){const r=n.onError||(()=>new y),s=this.internal.openCursor(n.query,n.direction);await new Promise((n,o)=>{s.onsuccess=async s=>{try{s.target||o(this.tx.abort(r()));const e=s.target.result;e&&await t(e,this.tx)||n()}catch(i){o(this.tx.abort(i instanceof e?i:new a(String(i))))}},s.onerror=()=>{o(this.tx.abort(r()))}})}handleRequest(e,t){return new Promise(n=>{e.onsuccess=()=>{n(e.result)},e.onerror=()=>{throw this.tx.abort(t())}})}}class ie{internal;status;error=null;storeNames;inWrap=!1;onRejection=t=>{throw t instanceof e?this.abort(t):this.abort(new a(String(t)))};objectStores;constructor(e,t,n,r={}){e instanceof ie?(this.internal=e.getInternal(),this.storeNames=e.storeNames,this.status=e.status,this.error=e.error,this.objectStores=e.getAllStores()):(this.internal=e.transaction(t,n),this.status=0,this.storeNames=Array.from(this.internal.objectStoreNames),this.objectStores=new Map(this.storeNames.map(e=>[e,this.getObjectstore(e)])),this.internal.onabort=this.registerHandler(1,r.onAbort),this.internal.onerror=this.registerHandler(3,r.onError),this.internal.oncomplete=this.registerHandler(2,r.onComplete))}static create(e,t,n,r){return r||new ie(e,t,n)}abort(e){return 1!==this.status&&this.internal.abort(),this.status=1,this.error=e,this.error}commit(){this.internal.commit()}getInternal(){return this.internal}getStore(e){const t=this.objectStores.get(e);if(!t)throw this.abort(new r(`Store '${e}' is not a part of this transaction`));return t}getAllStores(){return this.objectStores}get mode(){return this.internal.mode}is(e){return this.status===e}contains(e){Array.isArray(e)||(e=[e]);for(const t of e)if(!this.internal.objectStoreNames.contains(t))return!1;return!0}assertIsArray(e,t="Value is not an array"){if(!Array.isArray(e))throw this.abort(new o(t))}getObjectstore(e){try{return new ae(this,this.internal.objectStore(e))}catch{throw this.abort(new c(`No ObjectStore with the name '${e}' found`))}}registerHandler(e,t=()=>{}){return n=>{this.status=e,t(this,n)}}async wrap(t){if(this.inWrap)return await t(this);this.inWrap=!0;try{const e=await t(this);return this.inWrap=!1,e}catch(n){throw this.inWrap=!1,n instanceof e?this.abort(n):this.abort(new a(JSON.stringify(n)))}}}function ce(e){if(!e)return[];const t=[];for(const n in e)if(Object.hasOwn(e,n))switch(typeof e[n]){case"function":t.push([n,!0,e[n]]);break;case"object":if(e[n]instanceof Date){const r=e[n];t.push([n,!0,e=>e instanceof Date&&e.getTime()===r.getTime()])}break;default:t.push([n,!1,e[n]])}return t}function ue(e,t){if(!t||"object"!=typeof t)return!1;for(const n of e)if(n[1]){if(!n[2](t[n[0]]))return!1}else if(n[2]!==t[n[0]])return!1;return!0}function le(e,t,n={},r){const o=t.getModel(e);if(n.include&&n.select)throw new s("include and select cannot both be defined");const a=ce(n.where),i=n.select?"select":n.include?"include":"";if(i){const e=n[i],r=!!n.select,s=[];for(const n in e)if(Object.hasOwn(e,n)&&e[n])switch(o.keyType(n)){case te.Relation:{const r=o.getRelation(n),a="object"==typeof e[n]?le(r.to,t,e[n]):A,i=r.getRelatedKey();if(r.isArray){const e=async(e,t)=>{const n=[],s=t.getStore(r.to);for(const r of e){const e=await a(await s.assertGet(r),t);e&&(delete e[i],n.push(e))}return n};s.push({key:n,getValue:e})}else{const e=async(e,t)=>await a(await t.getStore(r.to).assertGet(e),t);s.push({key:n,getValue:e})}break}case te.Property:case te.PrimaryKey:r&&s.push({key:n})}return r?async(e,t)=>{if(!ue(a,e))return;const n={};for(const{key:r,getValue:o}of s)n[r]=o?await o(e[r],t):e[r];return n}:async(e,t)=>{if(ue(a,e)){for(const{key:n,getValue:r}of s)e[n]=await r(e[n],t);return e}}}return e=>ue(a,e)?e:void 0}function de(e,t,n,r){const s=new Set([e]);if(n){const o=r.getModel(e);for(const e in t){const a=o.getRelation(e),i=g(t[e]);if(a)for(const e of i)if(e&&"object"==typeof e)for(const t in e)if(Object.hasOwn(e,t))switch(t){case"$connect":case"$connectMany":case"$disconnect":case"$disconnectMany":case"$disconnectAll":s.add(a.to);break;case"$delete":case"$deleteMany":case"$deleteAll":v(s,o.getDeletedStores(r));break;case"$create":v(s,de(a.to,e[t],n,r));break;case"$createMany":e[t].forEach(e=>v(s,de(a.to,e,n,r)));break;case"$update":v(s,de(a.to,e[t].data,n,r));break;case"$updateMany":e[t].forEach(e=>v(s,de(a.to,e.data,n,r)))}}}else{const n=r.getModel(e);for(const e in t){const o=n.getRelation(e);if(o)switch(typeof t[e]){case"object":v(s,de(o.to,ye(t[e]),!1,r));break;case"boolean":s.add(o.to)}}}return s}function ye(e){return e.select?e.select:e.include?e.include:{}}class fe{constructor(e,t,n){this.client=e,this.name=t,this.accessedStores=Array.from(de(t,ye(n),!1,this.client)),this.selectClause=le(t,this.client,n)}accessedStores;selectClause;async find(){return await this._find(!1)}async findFirst(){return(await this._find(!0))[0]}async _find(e){const t=this.client.createTransaction("readonly",this.accessedStores);return await t.wrap(async t=>{const n=[],r=t.getStore(this.name);return await r.openCursor(async r=>{const s=await this.selectClause(r.value,t);return s&&n.push(s),(!e||!n.length)&&(r.continue(),!0)}),n})}}function he(e,t,r){return async s=>{if(!s)return!1;const o=s[e.primaryKey];for(const[a,c]of e.relations()){const{onDelete:u}=c.getActions(),l=s[a],d=t.getModel(c.to);switch(u){case"Cascade":if(c.isArray){r.assertIsArray(l);const e=new Set(l),n=he(d,t,r),s=r.getStore(c.to);await s.openCursor(async t=>(e.has(t.value[d.primaryKey])&&await n(t.value),t.continue(),!0)).catch(r.onRejection)}else l&&await we(c.to,t,void 0,void 0,{tx:r,singleton:{id:l}});break;case"SetNull":{if(!l)break;const e=g(l),t=r.getStore(c.to),s=c.getRelatedKey(),a=d.getRelation(s);if(!a)throw new n(`Relation '${c.name}' has an invalid relation key '${c.getRelatedKey()}'`);if(!a.isNullable())throw new n(`Key '${s}' on model '${s}': Non-optional relation cannot have the 'SetNull' action`);for(const n of e){const e=await t.get(n);if(!e)continue;const i=e[s];if(a.isArray){r.assertIsArray(i);const e=i.indexOf(o);if(-1===e)continue;i.splice(e,1)}else e[s]=null;await t.put(e)}break}case"Restrict":if(Array.isArray(l)&&l.length>0||l)throw new i(`Key '${a}' on model '${e.name}' deletion is restricted while there is an active relation`)}}return!0}}async function we(e,t,n,r=!1,s={}){const{singleton:o,finalStep:a=!0}=s,i=t.getModel(e),c=s.tx?s.tx.storeNames:Array.from(i.getDeletedStores(t)),u=ie.create(t.getDb(),c,"readwrite",s.tx);return await u.wrap(async s=>{const c=s.getStore(e);let u=0;const l=he(i,t,s);if(o)await l(await c.assertGet(o.id))&&(await c.delete(o.id),u++);else{const e=ce(n);let t;await c.openCursor(async n=>{const o=n.value;return ue(e,o)&&await l(o)&&(t=p(n.delete()).catch(s.onRejection)),!(r&&u>0)&&(n.continue(),!0)}),t&&a&&await t}return u})}function pe(e){return"string"!=typeof e?String(e):e.replaceAll(/~|\//g,e=>"~"===e?"~0":"~1")}async function me(e,t,n,r){r=ie.create(e.getDb(),[t],"readonly",r);const s=ce(n),a=e.getModel(t);return await r.wrap(async e=>{const n={};return await e.getStore(t).openCursor(async e=>{if(ue(s,e.value)){for(const[t,n]of a.entries())if(Q.is(n))if(n.isArray){if(!Array.isArray(e.value[t]))throw new o("Expected array type");const r=[];for(const s of e.value[t])r.push(`/${n.to}/${pe(s)}`);e.value[t]=r}else(n.isOptional&&e.value[t]||!n.isNullable())&&(e.value[t]=`/${n.to}/${pe(e.value[t])}`);else{if(!re.is(n)&&!H.is(n))throw new w(`Unrecognized model field on key '${t}'`);e.value[t]=await q(n.type,e.value[t])}if(n[e.value[a.primaryKey]])throw new w("Duplicate primary key detected "+JSON.stringify(n));n[e.value[a.primaryKey]]=e.value}return e.continue(),!0}),n})}function ge(e,t){const n=[`## ${e.name}`],r=[];for(const[s,o]of e.entries())H.is(o)?r.unshift(s):r.push(s);n.push(r.join(","));for(const s of Object.values(t)){const e=[];for(const t of r)switch(typeof s[t]){case"object":e.push(JSON.stringify(s[t]));break;case"undefined":e.push("");break;default:e.push(String(s[t]))}n.push(e.join(","))}return n.join("\n")}class be{constructor(e,t,n){this.name=e,this.content=t,this.extension=n}toFile(e=`${this.name}_dump.${this.extension}`,t){return new File([this.content],e,t)}download(e=`${this.name}_dump.${this.extension}`,t){const n=URL.createObjectURL(this.toFile(e,t)),r=document.createElement("a");r.href=n,r.download=e,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}static toJson(e,t,n){return new this(e,JSON.stringify(t,void 0,n?.pretty??1?4:void 0),"json")}static toCsvStore(e,t){return new this(e.name,ge(e,t),"csv")}static toCsvDb(e,t,n){const r=[`# ${e.name}`];for(const s of t)r.push(ge(e.getModel(s),n[s]));return new this(e.name,r.join("\n"),"csv")}}class Se{constructor(e,t){this.db=e,this.models=t,this.name=this.db.name,this.version=this.db.version,this.stores={};for(const n of this.models.keys())this.stores[n]=this.createInterface(n)}name;version;stores;getDb(){return this.db}getStore(e){return this.stores[e]}getStoreNames(){return this.models.keys()}createTransaction(e,t,n){return new ie(this.db,t,e,n)}async drop(){await p(window.indexedDB.deleteDatabase(this.name))}async dump(e,t,n){const r=await async function(e,t){const n={};t=t||e.getStoreNames();const r=e.createTransaction("readonly",t);for(const s of t)n[s]=await me(e,s,void 0,r);return n}(this,t);switch(e){case"json":return be.toJson(this.name,r,n);case"csv":return be.toCsvDb(this,t||this.getStoreNames(),r)}}deleteAllStores(){for(const e of this.models.keys())this.db.deleteObjectStore(e)}deleteStore(e){Array.isArray(e)||(e=[e]);for(const t of e)this.db.deleteObjectStore(t)}getModel(e){const t=this.models.getModel(e);if(!t)throw new c(`Model with name '${e}' not found`);return t}getAccessedStores(e,t,n,r){return r?r.storeNames:Array.from(de(e,t,n,this))}createInterface(e){return{add:async(t,n)=>await this.add(e,t,{tx:n}),addMany:async(t,n)=>{if(!n){const r=new Set;for(const n of t)v(r,de(e,n,!0,this));n=this.createTransaction("readwrite",Array.from(r))}const r=[];for(const s of t)r.push(await this.add(e,s,{tx:n}));return r},findFirst:async(t,n)=>(await this.find(e,t,!0,{tx:n}))[0],find:async(t,n)=>await this.find(e,t,!1,{tx:n}),get:async t=>{const n=this.createTransaction("readonly",e);return await n.getStore(e).get(t)},update:async(t,n)=>(await this.update(e,{data:n},!0,{singleton:{id:t}}))[0],updateFirst:async(t,n)=>(await this.update(e,t,!0,{tx:n}))[0],updateMany:async(t,n)=>await this.update(e,t,!1,{tx:n}),compileQuery:t=>new fe(this,e,t),delete:async t=>await we(e,this,void 0,void 0,{singleton:{id:t}})>0,deleteFirst:async t=>await we(e,this,t,!0)>0,deleteMany:async t=>await we(e,this,t,!1),dump:async(t,n,r)=>{const s=await me(this,e,n);switch(t){case"json":return be.toJson(e,s,r);case"csv":return be.toCsvStore(this.getModel(e),s)}}}}async add(e,t,n={}){let{tx:r}=n;const{relation:o}=n,i=this.getAccessedStores(e,t,!0,r);return r=ie.create(this.db,i,"readwrite",r),await r.wrap(async n=>{const r=n.getStore(e),i=this.getModel(e),c=i.getPrimaryKey(),u=o?{[o.key]:i.getRelation(o.key)?.isArray?[o.id]:o.id}:{},l=c.isAutoIncremented()?{...u}:{...u,[i.primaryKey]:t[i.primaryKey]??c.genKey()},d=await r.add(l),y={},f=new Set;for(const o in t){f.add(o);const r=t[o];switch(i.keyType(o)){case te.Invalid:throw new s(`Key '${o}' does ont exist on model '${e}'`);case te.Property:{const e=i.parseField(o,r);if(!e)throw new a;if(!e.success)throw new s(`Key '${o}' has the following validation error: ${e.error}`);y[o]=e.data;break}case te.Relation:{if(!r)continue;const e=g(r),t=i.getRelation(o);if(t.isArray&&(y[o]=[],"$createMany"in r||"$connectMany"in r)){const t=[];for(const e of r.$createMany??[])t.push({$create:e});for(const e of r.$connectMany??[])t.push({$connect:e});e.push(...t)}const a=this.getModel(t.to).getRelation(t.getRelatedKey()),c=new Set;for(const r of e){const e=m(r)[0];if(!e)throw new s(`Key '${o}' cannot be an empty connection object`);switch(e){case"$connect":{const i=r[e];if(c.has(i))throw new s(`Primary key '${i}' was already used for a connection`);if(c.add(i),!a)throw new s(`Could not find corresponding relation '${t.name}'`);await this.connectDocument(t,d,i,n),t.isArray?y[o].push(i):y[o]=i;break}case"$create":{const s=await this.add(t.to,r[e],{tx:n,relation:{id:d,key:t.getRelatedKey()}});t.isArray?y[o].push(s):y[o]=s;break}case"$connectMany":case"$createMany":break;default:throw new s(`Connection Object on key '${o}' has an unknown key '${e}'`)}if(!t.isArray)break}break}case te.PrimaryKey:}}const h=Array.from(new Set(i.keys()).difference(f));for(const e of h)switch(i.keyType(e)){case te.Property:{const t=i.parseField(e,void 0);if(!t)throw new a("A parsing error occurred");if(!t.success)throw new s(`Key '${e}' is missing`);y[e]=t.data;break}case te.Relation:{const t=i.getRelation(e),n=u[e];if(t.isArray)y[e]=n??[];else if(t.isOptional)y[e]=n??null;else{if(!n)throw new s(`Required relation '${e}' is not defined`);y[e]=n}break}case te.Invalid:case te.PrimaryKey:}return await r.put({[i.primaryKey]:d,...y})})}async clear(e,t){await we(e,this,void 0,!1,t)}async find(e,t,n,r={}){let{tx:s}=r;const o=this.getAccessedStores(e,ye(t),!1,s);s=ie.create(this.db,o,"readonly",s);const a=[];return await s.wrap(async r=>{const s=r.getStore(e),o=le(e,this,t);return await s.openCursor(async e=>{const t=await o(e.value,r);return t&&a.push(t),(!n||!a.length)&&(e.continue(),!0)}),a})}async update(e,t,n,r={}){const{singleton:o}=r,i=r.singleton?t:t.data,c=this.getAccessedStores(e,i,!0,r.tx),d=ie.create(this.db,c,"readwrite",r.tx);return await d.wrap(async r=>{const c=r.getStore(e),d=this.getModel(e),y=[];for(const e of m(i))switch(d.keyType(e)){case te.Property:y.push({key:e,isRelation:!1,updateFn:"function"==typeof i[e]?i[e]:()=>i[e]});break;case te.Relation:{const t=g(i[e]);if(!t)continue;const n=[];for(const e of t)for(const t in e){switch(t){case"$createMany":case"$connectMany":case"$updateMany":case"$deleteMany":case"$disconnectMany":{const r=t.substring(0,t.length-4);for(const s of e[t])n.push([r,s]);break}default:n.push([t,e[t]])}break}y.push({actions:n,key:e,isRelation:!0,relation:d.getRelation(e)});break}case te.PrimaryKey:throw new l("Primary key field cannot be updated");case te.Invalid:default:throw new a(`Unknown key '${e}'`)}const f=[],h=async e=>{const t=e[d.primaryKey];for(const{key:n,...o}of y){const a=o.relation;if(o.isRelation)for(const[i,c]of o.actions)switch(i){case"$connect":e[n]&&!a.isArray&&await this.disconnectDocument(a,t,e[n],r).catch(r.onRejection),await this.connectDocument(a,t,c,r).catch(r.onRejection),a.isArray?e[n].push(c):e[n]=c;break;case"$create":{const s=await this.add(a.to,c,{tx:r,relation:{id:t,key:a.getRelatedKey()}});a.isArray?e[n].push(s):e[n]=s;break}case"$delete":if(!a.isNullable())throw new s("Item cannot be deleted, relation is required");e[n]=a.isArray&&Array.isArray(e[n])?e[n].filter(e=>e!==c):null,await we(a.to,this,{},!0,{tx:r,singleton:{id:c}});break;case"$disconnect":{if(!a.isNullable())throw new s("Item cannot be disconnected, relation is required");if(!e[n]||0===e[n]?.lenth)break;const o=this.getModel(a.to).getRelation(a.getRelatedKey());await this.disconnectDocument(a,t,o.isArray?c:e[n],r).catch(r.onRejection),e[n]=a.isArray&&Array.isArray(e[n])?e[n].filter(e=>e!==c):null;break}case"$update":a.isArray?await this.update(a.to,c,!1,{tx:r}):null!=e[n]&&await this.update(a.to,c,!1,{tx:r,singleton:{id:t}});break;case"$deleteAll":if(c&&a.isArray&&Array.isArray(e[n])){const t=this.getModel(a.to),s=new Set(e[n]);await we(a.to,this,{[t.primaryKey]:e=>s.has(e)},!1,{tx:r}),e[n]=[]}break;case"$disconnectAll":if(c&&a.isArray&&Array.isArray(e[n])){for(const s of e[n])await this.disconnectDocument(a,t,s,r);e[n]=[]}}else e[n]=o.updateFn(e[n])}return e};if(o){const e=await c.get(o.id);if(!e)throw new u(`${d.name} with priamry key '${o.id}' not found`);const t=await h(e).catch(r.onRejection);return await c.put(t),[t]}{const e=ce(t.where);return await c.openCursor(async t=>{const s=t.value;if(ue(e,s)){const e=await h(s).catch(r.onRejection);if(await p(t.update(e)).then(()=>f.push(e)).catch(r.onRejection),n)return!1}return t.continue(),!0}),f}})}async connectDocument(e,t,n,r){const s=r.getStore(e.to),o=await s.get(n);if(!o)throw new u(`Document with Primary Key '${n}' could not be found in model '${e.to}'`);const a=e.getRelatedKey(),i=this.getModel(e.to).getRelation(a),c=o[a];if(i.isArray&&Array.isArray(c))c.includes(t)||c.push(t);else{if(c)throw new h;o[a]=t}return await s.put(o).catch(r.onRejection),n}async disconnectDocument(e,t,n,r){const s=r.getStore(e.to),o=await s.get(n);if(!o)throw new u(`Document with Primary Key '${n}' could not be found in model '${e.to}'`);const a=this.getModel(e.to).getRelation(e.getRelatedKey());if(a.isArray)o[e.getRelatedKey()].filter(e=>e!==t);else{if(!a.isOptional)throw new h;o[e.getRelatedKey()]=null}return await s.put(o).catch(r.onRejection),n}}class Ae{constructor(e,t){this.name=e,this.models=t,this.modelKeys=m(this.models),this.schemas={};for(const r of this.modelKeys){const e=this.models[r],t={};for(const[s,o]of e.entries())if(re.is(o))t[s]=o.type;else if(Q.is(o)){const{onDelete:a}=o.getActions(),i=this.models[o.to],c=i.getPrimaryKey();t[s]=c.type,o.isOptional?t[s]=L(t[s]):o.isArray&&(t[s]=I(t[s]));let u=!!o.getRelatedKey();if(!u)for(const[t,r]of i.relations())if(s!==t&&r.to===e.name&&r.name===o.name){if(u=!0,o.setRelatedKey(t),r.setRelatedKey(s),"SetNull"===a&&!r.isNullable())throw new n(`Key '${t}' on model '${i.name}': Non-optional relation cannot have the 'SetNull' action`);break}if(!u)throw new n(`Relation '${o.name}' of model ${r} does not have an equivalent relation on model '${o.to}'`)}else{if(!H.is(o))throw new n(`Unknown field value detected: ${JSON.stringify(o)}`);t[s]=o.type}this.schemas[r]=t}}schemas;modelKeys;getModel(e){return this.models[e]}async createClient(e=1){const t=window.indexedDB.open(this.name,e);t.onupgradeneeded=e=>{const t=e.target.result;for(const n of this.modelKeys){const e=this.models[n];t.objectStoreNames.contains(e.name)||t.createObjectStore(e.name,{autoIncrement:e.getPrimaryKey().isAutoIncremented(),keyPath:e.primaryKey})}};const n=await p(t);return new Se(n,this)}keys(){return[...this.modelKeys]}}const ve=Object.freeze(Object.defineProperty({__proto__:null,ArrayRelation:Z,BaseRelation:Q,DbClient:Se,FieldTypes:te,Model:oe,OptionalRelation:ee,PrimaryKey:H,Property:re,Relation:X,Tag:$,Type:B,Typing:J,deserializeType:U,isSubtype:z,isType:G,parseType:Y,serializeType:q,typeToString:V},Symbol.toStringTag,{value:"Module"}));exports.Builder=class{constructor(e,t){this.name=e,this.names=t,this.models={}}models;defineModel(e,t){if("object"==typeof e&&oe.is(e))return this.models[e.name]=e,e;{if(!t)throw new Error("Model Fields must be defined");const n=new oe(e,t);return this.models[e]=n,n}}compile(e){return new Ae(this.name,e)}},exports.CompiledQuery=fe,exports.Model=oe,exports.Property=re,exports.StoreError=e,exports.core=ve;
|
package/dist/index.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class e extends Error{code;constructor(e,t){super(`(${e}) ${t}`),this.code=e}}function t(t,
|
|
2
|
-
return new Date}function A(e){return e}function $(e,t){for(const r of t.keys())e.add(r);return e}class k{static String={tag:0};static Number={tag:1};static Boolean={tag:2};static BigInt={tag:6};static Symbol={tag:5};static File={tag:11};static Date={tag:4};static Unknown={tag:12};static Literal(e){return{tag:3,value:e}}static Array(e){return{tag:7,of:e}}static Set(e){return{tag:8,of:e}}static Union(e){return{tag:9,options:e}}static Optional(e){return{tag:10,of:e}}static Object(e){return{tag:14,props:e}}static Custom({isType:e,serialize:t,deserialize:r}){return{tag:15,isType:e,serialize:t,deserialize:r}}static async serialize(e,t){switch(e.tag){case 3:case 2:case 1:case 6:case 0:return t;case 5:return t.description;case 12:return JSON.stringify(t);case 4:return t.getTime();case 7:{const r=[];for(const n of t)r.push(await k.serialize(e.of,n));return r}case 8:{const r=/* @__PURE__ */new Set;for(const n of t)r.add(await k.serialize(e.of,n));return r}case 10:return void 0===t?null:await k.serialize(e.of,t);case 9:for(const r of e.options)if(k.is(r,t))return await k.serialize(r,t);throw new Error("Value union could not be serialized");case 11:if(!(t instanceof File))throw new Error("Value is not a valid file");return{data:new Promise((e,r)=>{const n=new FileReader;n.onload=()=>e(n.result),n.onerror=r,n.readAsDataURL(t)}),name:t.name};case 14:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const r={};for(const n in e.props){const s=e.props[n];if(!(n in t)&&10!==s.tag)throw new Error(`Required property '${n}' not found`);r[n]=await this.serialize(s,t[n])}return r}case 13:return this.serialize(e.of,t);case 15:return e.serialize?await e.serialize(t):JSON.stringify(t)}}static async deserialize(e,t){switch(e.tag){case 3:if(typeof t!=typeof e.value)throw new Error(`'${t}' is not equal to literal '${t}'`);return t;case 2:if("boolean"!=typeof t)throw new Error(`'${t}' is not a boolean`);return t;case 1:if("number"!=typeof t)throw new Error(`'${t}' is not a number`);return t;case 6:if("number"!=typeof t)throw new Error(`'${t}' is not a bigint`);return BigInt(t);case 0:if("string"!=typeof t)throw new Error(`'${t}' is not a string`);return t;case 5:if("string"!=typeof t)throw new Error(`'${t}' is not a symbol`);return Symbol.for(t);case 4:if(!(t instanceof Date))throw new Error(`'${t}' is not a date`);return t;case 7:if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);return t;case 8:if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);return new Set(t);case 10:return k.deserialize(e.of,t);case 12:return JSON.parse(t);case 9:{let r,n=!1;for(const s of e.options){try{r=k.deserialize(s,t),n=!0}catch{n=!1}if(n)break}if(!n)throw new Error("Value did not match the union");return r}case 11:{if(!t||"object"!=typeof t||!("data"in t)||!("name"in t)||"string"!=typeof t.data||"string"!=typeof t.name)throw new Error("Value is not a valid file schema");const e=await fetch(t.data);return new File([await e.blob()],t.name)}case 13:return this.deserialize(e.of,t);case 15:if(e.isType(t))return e.deserialize?await e.deserialize(t):JSON.parse(String(t));throw new Error("Value is not valid");case 14:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const r={};for(const n in e.props){const s=e.props[n];if(!(n in t)&&10!==s.tag)throw new Error(`Required property '${n}' not found`);r[n]=await this.deserialize(s,t[n])}return r}}}static is(e,t){switch(e.tag){case 3:return t===e.value;case 2:return"boolean"==typeof t;case 1:return"number"==typeof t;case 6:return"bigint"==typeof t;case 0:return"string"==typeof t;case 5:return"symbol"==typeof t;case 12:return!0;case 4:return t instanceof Date;case 7:return Array.isArray(t)&&t.every(t=>k.is(e.of,t));case 8:return t instanceof Set&&Array.from(t).every(t=>k.is(e.of,t));case 10:return void 0===t||this.is(e.of,t);case 9:return e.options.some(e=>k.is(e,t));case 11:return t instanceof File;case 14:return!(!t||"object"!=typeof t)&&Object.keys(e.props).every(r=>k.is(e.props[r],t[r]));case 13:return this.is(e.of,t);case 15:return e.isType(t)}}}const R=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Type:k},Symbol.toStringTag,{value:"Module"}));function v(e){return t=>typeof t===e?{success:!0,data:t}:{success:!1,error:"Value is not a string"}}const K={[k.String.tag]:v("string"),[k.Number.tag]:v("number"),[k.BigInt.tag]:v("bigint"),[k.Boolean.tag]:v("boolean"),[k.Symbol.tag]:v("symbol"),[k.Unknown.tag]:e=>({success:!0,data:e}),[k.Date.tag]:e=>e instanceof Date?isNaN(e.getTime())?{success:!1,error:"Value is not a valid date"}:{success:!0,data:e}:{success:!1,error:"Value is not a date"}},O=Symbol.for("primaryKey");class N{symbol=O;genFn;autoGenerate;type;constructor(e,t){if(e){if(e>k.Date)throw new r("Invalid Primary Key Type");this.type=e,t?(this.autoGenerate=!0,this.genFn=t):this.autoGenerate=!1}else this.autoGenerate=!1,this.type=k.Number}getType(){return this.type}generator(e){return this.genFn=e,this.autoGenerate=!0,this}autoIncrement(){if(this.type===k.Number)return this.genFn=void 0,this.autoGenerate=!0,this;throw new r("Primary key must be a number to use autoIncrement()")}uuid(){if(!window.isSecureContext)throw new Error("Window is not in a secure context");return new N(k.String,b)}date(){return new N(k.Date,S)}genKey(){if(this.genFn)return this.genFn();throw new Error("Generator function not defined")}getSchema(){return K[this.type.tag]}isAutoIncremented(){return this.autoGenerate&&!this.genFn}static is(e){return e?.symbol===O}}class M{constructor(e,t="",r=!1,n=!1,s){this.to=e,this.name=t,this.isOptional=r,this.isArray=n,this.relatedKey="",this.actions={onDelete:s||"Restrict"}}static SYMBOL=Symbol.for("baseRelation");BASE_SYMBOL=M.SYMBOL;actions;relatedKey;getActions(){return{...this.actions}}isNullable(){return this.isArray||this.isOptional}setRelatedKey(e){this.relatedKey=e}getRelatedKey(){return this.relatedKey}toString(){return`${this.isArray?"Array":this.isOptional?"Optional":"Standard"} relation from this model to model '${this.to}' on key '${this.relatedKey}'`}getBaseSymbol(){return this.BASE_SYMBOL}static is(e){return"getBaseSymbol"in e&&e.getBaseSymbol()===M.SYMBOL}}class D extends M{static R_SYMBOL=Symbol.for("relation");symbol=D.R_SYMBOL;constructor(e,t={}){super(e,t.name,!1,!1,t.onDelete)}array({onDelete:e}={}){return new I(this.to,this.name,e)}optional({onDelete:e}={}){return new j(this.to,this.name,e)}onDelete(e){return this.actions.onDelete=e,this}static is(e){return e?.symbol===this.R_SYMBOL}}class I extends M{static A_SYMBOL=Symbol.for("arrayRelation");symbol=I.A_SYMBOL;constructor(e,t,r="None"){super(e,t,!1,!0,r)}static is(e){return e?.symbol===this.A_SYMBOL}}class j extends M{static O_SYMBOL=Symbol.for("optionalRelation");symbol=j.O_SYMBOL;constructor(e,t,r="None"){super(e,t,!0,!1,r)}static is(e){return e?.symbol===this.O_SYMBOL}}var E=/* @__PURE__ */(e=>(e[e.Property=0]="Property",e[e.Relation=1]="Relation",e[e.PrimaryKey=2]="PrimaryKey",e[e.Invalid=3]="Invalid",e))(E||{});const x=Symbol.for("property");class F{constructor(e,t,r){this.parseFn=e,this.type=t,this.options={unique:r?.unique??!1}}symbol=x;hasDefault=!1;options;get parse(){return this.parseFn}getType(){return this.type}static array(...e){throw new Error("Method Not Implemented")}static boolean(...e){throw new Error("Method Not Implemented")}static custom(...e){throw new Error("Method Not Implemented")}static date(...e){throw new Error("Method Not Implemented")}static literal(e,...t){throw new Error("Method Not Implemented")}static number(...e){throw new Error("Method Not Implemented")}static union(...e){throw new Error("Method Not Implemented")}static set(...e){throw new Error("Method Not Implemented")}static string(...e){throw new Error("Method Not Implemented")}unique(){switch(this.type){case k.Boolean:case k.String:case k.Number:case k.Symbol:return this.options.unique=!0,this;default:throw new Error("A non-primitive cannot be a unique value")}}hasDefaultValue(){return this.hasDefault}static relation(e,t){return new D(e,t)}static primaryKey(e="number"){return new N(this.nameToType(e))}static nameToType(e){switch(e){case"boolean":return k.Boolean;case"bigint":return k.BigInt;case"number":case"string":return k.Number;case"symbol":return k.Symbol;default:return k.Unknown}}static is(e){return"object"==typeof e&&e?.symbol===x}}class T extends F{array(){return new T(T.generateArrayValidator(this.parseFn),k.Array(this.type),this.options)}default(e){return this.hasDefault=!0,new T(t=>null==t?{success:!0,data:"function"==typeof e?e():e}:this.parseFn(t),this.type,this.options)}optional(){return new T(e=>null==e?{success:!0,data:void 0}:this.parseFn(e),this.type,this.options)}static array(e,t){return new T(T.generateArrayValidator(e.parseFn),k.Array(e.type),t)}static boolean(e){return new T(e=>"boolean"==typeof e?{success:!0,data:e}:{success:!1,error:"Value is not a string"},k.Boolean,e)}static custom(e,t){return new T(e,k.Unknown,t)}static date(e){return new T(K[k.Date.tag],k.Date,e)}static literal(e,t){return new T(t=>t===e?{success:!0,data:e}:{success:!1,error:`${t} !== ${e}`},k.Literal(e),t)}static number(e){return new T(K[k.Number.tag],k.Number,e)}static string(e){return new T(K[k.String.tag],k.String,e)}static set(e,t){return new T(t=>{if(t instanceof Set){const r=/* @__PURE__ */new Set;for(const n of t){const t=e.parseFn(n);if(!t.success)return t;r.add(t.data)}return{success:!0,data:r}}return{success:!1,error:"Value is not an array"}},k.Set(e.type),t)}static union(e,t){const r=e.map(e=>e.parse);return new T(e=>{for(const t of r){const r=t(e);if(r.success)return r}return{success:!1,error:"Value did not match any of the items"}},k.Union(e.map(e=>e.getType())),t)}static generateArrayValidator(e){return t=>{if(Array.isArray(t)){const r=[];for(const n of t){const t=e(n);if(!t.success)return t;r.push(t.data)}return{success:!0,data:r}}return{success:!1,error:"Value is not an array"}}}}const _=Symbol.for("model");class P{constructor(t,r){this.name=t,this.fields=r,this.fieldKeys=m(r);for(const e of this.fieldKeys){const t=this.fields[e];M.is(t)&&t.to!==this.name&&this.relationLinks.add(t.to)}const n=this.fieldKeys.find(e=>N.is(this.fields[e]));if(!n)throw new e("INVALID_CONFIG",`Model ${this.name} has no primary key`);this.primaryKey=n}symbol=_;fieldKeys;relationLinks=/* @__PURE__ */new Set;cache={};primaryKey;get(e){return this.fields[e]}getPrimaryKey(){return this.fields[this.primaryKey]}getRelation(e){const t=this.fields[e];if(t&&M.is(t))return t}keyType(e){const t=this.fields[e];return t?F.is(t)?E.Property:M.is(t)?E.Relation:N.is(t)?E.PrimaryKey:E.Invalid:E.Invalid}links(){return this.relationLinks.keys()}*relations(){for(const e of this.fieldKeys)M.is(this.fields[e])&&(yield[e,this.fields[e]])}*entries(){for(const e of this.fieldKeys)yield[e,this.fields[e]]}keys(){return[...this.fieldKeys]}parseField(e,t){return F.is(this.fields[e])?this.fields[e].parse(t):null}getDeletedStores(e){if(this.cache.delete)return this.cache.delete;const t=/* @__PURE__ */new Set,r=[this.name];let n;for(;r.length>0;){const s=r.shift();if(t.has(s))continue;n=e.getModel(s);const a=n.cache.delete;if(a)$(t,a);else{t.add(s);for(const e of n.links())t.has(e)||r.push(e)}}return this.cache.delete=t,t}static is(e){return e?.symbol===_}}class L{constructor(e,t){this.tx=e,this.store=t}add(e){return this.handleRequest(this.store.add(e),()=>new d)}get(e){return this.handleRequest(this.store.get(e),()=>new y)}async assertGet(e){const t=await this.handleRequest(this.store.get(e),()=>new y);if(!t)throw this.tx.abort(new l);return t}put(e){return this.handleRequest(this.store.put(e),()=>new u)}delete(e){return this.handleRequest(this.store.delete(e),()=>new i)}async openCursor(t,r={}){const n=r.onError||(()=>new h),s=this.store.openCursor(r.query,r.direction);await new Promise((r,a)=>{s.onsuccess=async s=>{try{s.target||a(this.tx.abort(n()));const e=s.target.result;e&&await t(e,this.tx)||r()}catch(i){a(this.tx.abort(i instanceof e?i:new o(String(i))))}},s.onerror=()=>{a(this.tx.abort(n()))}})}handleRequest(e,t){return new Promise(r=>{e.onsuccess=()=>{r(e.result)},e.onerror=()=>{throw this.tx.abort(t())}})}}class V{internal;status;error=null;storeNames;inWrap=!1;onRejection=t=>{throw t instanceof e?this.abort(t):this.abort(new o(String(t)))};objectStores;constructor(e,t,r,n={}){e instanceof V?(this.internal=e.getInternal(),this.storeNames=e.storeNames,this.status=e.status,this.error=e.error,this.objectStores=e.getAllStores()):(this.internal=e.transaction(t,r),this.status=0,this.storeNames=Array.from(this.internal.objectStoreNames),this.objectStores=new Map(this.storeNames.map(e=>[e,this.getObjectstore(e)])),this.internal.onabort=this.registerHandler(1,n.onAbort),this.internal.onerror=this.registerHandler(3,n.onError),this.internal.oncomplete=this.registerHandler(2,n.onComplete))}static create(e,t,r,n){return n||new V(e,t,r)}abort(e){return 1!==this.status&&this.internal.abort(),this.status=1,this.error=e,this.error}commit(){this.internal.commit()}getInternal(){return this.internal}getStore(e){const t=this.objectStores.get(e);if(!t)throw this.abort(new n(`Store '${e}' is not a part of this transaction`));return t}getAllStores(){return this.objectStores}get mode(){return this.internal.mode}is(e){return this.status===e}contains(e){Array.isArray(e)||(e=[e]);for(const t of e)if(!this.internal.objectStoreNames.contains(t))return!1;return!0}assertIsArray(e,t="Value is not an array"){if(!Array.isArray(e))throw this.abort(new a(t))}getObjectstore(e){try{return new L(this,this.internal.objectStore(e))}catch{throw this.abort(new c(`No ObjectStore with the name '${e}' found`))}}registerHandler(e,t=()=>{}){return r=>{this.status=e,t(this,r)}}async wrap(t){if(this.inWrap)return await t(this);this.inWrap=!0;try{const e=await t(this);return this.inWrap=!1,e}catch(r){throw this.inWrap=!1,r instanceof e?this.abort(r):this.abort(new o(JSON.stringify(r)))}}}function B(e){if(!e)return[];const t=[];for(const r in e)if(Object.hasOwn(e,r))switch(typeof e[r]){case"function":t.push([r,!0,e[r]]);break;case"object":if(e[r]instanceof Date){const n=e[r];t.push([r,!0,e=>e instanceof Date&&e.getTime()===n.getTime()])}break;default:t.push([r,!1,e[r]])}return t}function C(e,t){if(!t||"object"!=typeof t)return!1;for(const r of e)if(r[1]){if(!r[2](t[r[0]]))return!1}else if(r[2]!==t[r[0]])return!1;return!0}function z(e,t,r={},n){const a=t.getModel(e);if(r.include&&r.select)throw new s("include and select cannot both be defined");const o=B(r.where),i=r.select?"select":r.include?"include":"";if(i){const e=r[i],n=!!r.select,s=[];for(const r in e)if(Object.hasOwn(e,r)&&e[r])switch(a.keyType(r)){case E.Relation:{const n=a.getRelation(r),o="object"==typeof e[r]?z(n.to,t,e[r]):A,i=n.getRelatedKey();if(n.isArray){const e=async(e,t)=>{const r=[],s=t.getStore(n.to);for(const n of e){const e=await o(await s.assertGet(n),t);e&&(delete e[i],r.push(e))}return r};s.push({key:r,getValue:e})}else{const e=async(e,t)=>await o(await t.getStore(n.to).assertGet(e),t);s.push({key:r,getValue:e})}break}case E.Property:case E.PrimaryKey:n&&s.push({key:r})}return n?async(e,t)=>{if(!C(o,e))return;const r={};for(const{key:n,getValue:a}of s)r[n]=a?await a(e[n],t):e[n];return r}:async(e,t)=>{if(C(o,e)){for(const{key:r,getValue:n}of s)e[r]=await n(e[r],t);return e}}}return e=>C(o,e)?e:void 0}function U(e,t,r,n){const s=/* @__PURE__ */new Set([e]);if(r){const a=m(t),o=n.getModel(e);for(const e of a){const a=o.getRelation(e),i=g(t[e]);if(a)for(const e of i)if(e&&"object"==typeof e)for(const t in e)if(Object.hasOwn(e,t))switch(t){case"$connect":case"$connectMany":case"$disconnect":case"$disconnectMany":case"$disconnectAll":s.add(a.to);break;case"$delete":case"$deleteMany":case"$deleteAll":$(s,o.getDeletedStores(n));break;case"$create":$(s,U(a.to,e[t],r,n));break;case"$createMany":e[t].forEach(e=>$(s,U(a.to,e,r,n)));break;case"$update":$(s,U(a.to,e[t].data,r,n));break;case"$updateMany":e[t].forEach(e=>$(s,U(a.to,e.data,r,n)))}}}else{const r=n.getModel(e);for(const e of m(t)){const a=r.getRelation(e);if(a)switch(typeof t[e]){case"object":$(s,U(a.to,q(t[e]),!1,n));break;case"boolean":s.add(a.to)}}}return s}function q(e){return e.select?e.select:e.include?e.include:{}}class G{constructor(e,t,r){this.client=e,this.name=t,this.accessedStores=Array.from(U(t,q(r),!1,this.client)),this.selectClause=z(t,this.client,r)}accessedStores;selectClause;async find(){return await this._find(!1)}async findFirst(){return(await this._find(!0))[0]}async _find(e){const t=this.client.createTransaction("readonly",this.accessedStores);return await t.wrap(async t=>{const r=[],n=t.getStore(this.name);return await n.openCursor(async n=>{const s=await this.selectClause(n.value,t);return s&&r.push(s),(!e||!r.length)&&(n.continue(),!0)}),r})}}function Y(e,t,n){return async s=>{if(!s)return!1;const a=s[e.primaryKey];for(const[o,c]of e.relations()){const{onDelete:l}=c.getActions(),u=s[o],d=t.getModel(c.to);switch(l){case"Cascade":if(c.isArray){n.assertIsArray(u);const e=new Set(u),r=Y(d,t,n),s=n.getStore(c.to);await s.openCursor(async t=>(e.has(t.value[d.primaryKey])&&await r(t.value),t.continue(),!0)).catch(n.onRejection)}else u&&await J(c.to,t,void 0,void 0,{tx:n,singleton:{id:u}});break;case"SetNull":{if(!u)break;const e=g(u),t=n.getStore(c.to),s=c.getRelatedKey(),o=d.getRelation(s);if(!o)throw new r(`Relation '${c.name}' has an invalid relation key '${c.getRelatedKey()}'`);if(!o.isNullable())throw new r(`Key '${s}' on model '${s}': Non-optional relation cannot have the 'SetNull' action`);for(const r of e){const e=await t.get(r);if(!e)continue;const i=e[s];if(o.isArray){n.assertIsArray(i);const e=i.indexOf(a);if(-1===e)continue;i.splice(e,1)}else e[s]=null;await t.put(e)}break}case"Restrict":if(Array.isArray(u)&&u.length>0||u)throw new i(`Key '${o}' on model '${e.name}' deletion is restricted while there is an active relation`)}}return!0}}async function J(e,t,r,n=!1,s={}){const{singleton:a,finalStep:o=!0}=s,i=t.getModel(e),c=s.tx?s.tx.storeNames:Array.from(i.getDeletedStores(t)),l=V.create(t.getDb(),c,"readwrite",s.tx);return await l.wrap(async s=>{const c=s.getStore(e);let l=0;const u=Y(i,t,s);if(a)await u(await c.assertGet(a.id))&&(await c.delete(a.id),l++);else{const e=B(r);let t;await c.openCursor(async r=>{const a=r.value;return C(e,a)&&await u(a)&&(t=p(r.delete()).catch(s.onRejection)),!(n&&l>0)&&(r.continue(),!0)}),t&&o&&await t}return l})}class W{constructor(e,t,r){this.name=e,this.content=t,this.extension=r}download(e=`${this.name}_dump.${this.extension}`,t){const r=URL.createObjectURL(this.toFile(e,t)),n=document.createElement("a");n.href=r,n.download=e,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}}class H extends W{constructor(e,t){super(e,t,"json")}getValue(){return this.content}toFile(e=`${this.name}_dump.json`,t={}){return new File([JSON.stringify(this.content,void 0,4)],e,t)}}class X extends W{constructor(e,t){super(e,t,"csv")}getValue(){return this.content}toFile(e=`${this.name}_dump.csv`,t){return new File([this.content],e,t)}}function Q(e){return"string"!=typeof e?`${e}`:e.replaceAll(/~/g,"~0").replaceAll(/\//g,"~1")}async function Z(e,t,r,n){n=V.create(e.getDb(),[t],"readonly",n);const s=B(r),o=e.getModel(t);return new H(t,await n.wrap(async e=>{const r={};return await e.getStore(t).openCursor(async e=>{if(C(s,e.value)){for(const[t,r]of o.entries())if(M.is(r))if(r.isArray){if(!Array.isArray(e.value[t]))throw new a("Expected array type");const n=[];for(const s of e.value[t])n.push(`/${r.to}/${Q(s)}`);e.value[t]=n}else(r.isOptional&&e.value[t]||!r.isNullable())&&(e.value[t]=`/${r.to}/${Q(e.value[t])}`);else{if(!T.is(r)&&!N.is(r))throw new w(`Unrecognized model field on key '${t}'`);e.value[t]=await k.serialize(r.getType(),e.value[t])}if(r[e.value[o.primaryKey]])throw new w("Duplicate primary key detected "+JSON.stringify(r));r[e.value[o.primaryKey]]=e.value}return e.continue(),!0}),r}))}class ee{constructor(e,t){this.db=e,this.models=t,this.name=this.db.name,this.version=this.db.version,this.stores={};for(const r of this.models.keys())this.stores[r]=this.createInterface(r)}name;version;stores;getDb(){return this.db}getStore(e){return this.stores[e]}getStoreNames(){return this.models.keys()}createTransaction(e,t,r){return new V(this.db,t,e,r)}async deleteDb(){await p(window.indexedDB.deleteDatabase(this.name))}async dump(e,t){return"json"===e?await async function(e,t){const r={};t=t||e.getStoreNames();const n=e.createTransaction("readonly",t);for(const s of t)r[s]=(await Z(e,s,void 0,n)).getValue();return new H(e.name,r)}(this,t):new X("d","")}deleteAllStores(){for(const e of this.models.keys())this.db.deleteObjectStore(e)}deleteStore(e){Array.isArray(e)||(e=[e]);for(const t of e)this.db.deleteObjectStore(t)}getModel(e){return this.models.getModel(e)}getAccessedStores(e,t,r,n){return n?n.storeNames:Array.from(U(e,t,r,this))}createInterface(e){return{add:async(t,r)=>await this.add(e,t,{tx:r}),addMany:async(t,r)=>{if(!r){const n=/* @__PURE__ */new Set;for(const r of t)$(n,U(e,r,!0,this));r=this.createTransaction("readwrite",Array.from(n))}const n=[];for(const s of t)n.push(await this.add(e,s,{tx:r}));return n},findFirst:async(t,r)=>(await this.find(e,t,!0,{tx:r}))[0],find:async(t,r)=>await this.find(e,t,!1,{tx:r}),get:async t=>{const r=this.createTransaction("readonly",e);return await r.getStore(e).get(t)},update:async(t,r)=>(await this.update(e,{data:r},!0,{singleton:{id:t}}))[0],updateFirst:async(t,r)=>(await this.update(e,t,!0,{tx:r}))[0],updateMany:async(t,r)=>await this.update(e,t,!1,{tx:r}),compileQuery:t=>new G(this,e,t),delete:async t=>await J(e,this,void 0,void 0,{singleton:{id:t}})>0,deleteFirst:async t=>await J(e,this,t,!0)>0,deleteMany:async t=>await J(e,this,t,!1),dump:async(t,r)=>"json"===t?await Z(this,e,r):new X("","")}}async add(e,t,r={}){let{tx:n}=r;const{relation:a}=r,i=this.getAccessedStores(e,t,!0,n);return n=V.create(this.db,i,"readwrite",n),await n.wrap(async r=>{const n=r.getStore(e),i=this.getModel(e),c=i.getPrimaryKey(),l=a?{[a.key]:i.getRelation(a.key)?.isArray?[a.id]:a.id}:{},u=c.isAutoIncremented()?{...l}:{...l,[i.primaryKey]:t[i.primaryKey]??c.genKey()},d=await n.add(u),h={},y=/* @__PURE__ */new Set;for(const a of m(t)){y.add(a);const n=t[a];switch(i.keyType(a)){case E.Invalid:throw new s(`Key '${a}' does ont exist on model '${e}'`);case E.Property:{const e=i.parseField(a,n);if(!e)throw new o;if(!e.success)throw new s(`Key '${a}' has the following validation error: ${e.error}`);h[a]=e.data;break}case E.Relation:{if(!n)continue;const e=g(n),t=i.getRelation(a);if(t.isArray&&(h[a]=[],"$createMany"in n||"$connectMany"in n)){const t=[];for(const e of n.$createMany??[])t.push({$create:e});for(const e of n.$connectMany??[])t.push({$connect:e});e.push(...t)}const o=this.getModel(t.to).getRelation(t.getRelatedKey()),c=/* @__PURE__ */new Set;for(const n of e){const e=m(n)[0];if(!e)throw new s(`Key '${a}' cannot be an empty connection object`);switch(e){case"$connect":{const i=n[e];if(c.has(i))throw new s(`Primary key '${i}' was already used for a connection`);if(c.add(i),!o)throw new s(`Could not find corresponding relation '${t.name}'`);await this.connectDocument(t,d,i,r),t.isArray?h[a].push(i):h[a]=i;break}case"$create":{const s=await this.add(t.to,n[e],{tx:r,relation:{id:d,key:t.getRelatedKey()}});t.isArray?h[a].push(s):h[a]=s;break}case"$connectMany":case"$createMany":break;default:throw new s(`Connection Object on key '${a}' has an unknown key '${e}'`)}if(!t.isArray)break}break}case E.PrimaryKey:}}const f=Array.from(new Set(i.keys()).difference(y));for(const e of f)switch(i.keyType(e)){case E.Property:{const t=i.parseField(e,void 0);if(!t)throw new o("A parsing error occurred");if(!t.success)throw new s(`Key '${e}' is missing`);h[e]=t.data;break}case E.Relation:{const t=i.getRelation(e),r=l[e];if(t.isArray)h[e]=r??[];else if(t.isOptional)h[e]=r??null;else{if(!r)throw new s(`Required relation '${e}' is not defined`);h[e]=r}break}case E.Invalid:case E.PrimaryKey:}return await n.put({[i.primaryKey]:d,...h})})}async clear(e,t){await J(e,this,void 0,!1,t)}async find(e,t,r,n={}){let{tx:s}=n;const a=this.getAccessedStores(e,q(t),!1,s);s=V.create(this.db,a,"readonly",s);const o=[];return await s.wrap(async n=>{const s=n.getStore(e),a=z(e,this,t);return await s.openCursor(async e=>{const t=await a(e.value,n);return t&&o.push(t),(!r||!o.length)&&(e.continue(),!0)}),o})}async update(e,t,r,n={}){const{singleton:a}=n,i=n.singleton?t:t.data,c=this.getAccessedStores(e,i,!0,n.tx),d=V.create(this.db,c,"readwrite",n.tx);return await d.wrap(async n=>{const c=n.getStore(e),d=this.getModel(e),h=[];for(const e of m(i))switch(d.keyType(e)){case E.Property:h.push({key:e,isRelation:!1,updateFn:"function"==typeof i[e]?i[e]:()=>i[e]});break;case E.Relation:{const t=g(i[e]);if(!t)continue;const r=[];for(const e of t)for(const t in e){switch(t){case"$createMany":case"$connectMany":case"$updateMany":case"$deleteMany":case"$disconnectMany":{const n=t.substring(0,t.length-4);for(const s of e[t])r.push([n,s]);break}default:r.push([t,e[t]])}break}h.push({actions:r,key:e,isRelation:!0,relation:d.getRelation(e)});break}case E.PrimaryKey:throw new u("Primary key field cannot be updated");case E.Invalid:default:throw new o(`Unknown key '${e}'`)}const y=[],f=async e=>{const t=e[d.primaryKey];for(const{key:r,...a}of h){const o=a.relation;if(a.isRelation)for(const[i,c]of a.actions)switch(i){case"$connect":e[r]&&!o.isArray&&await this.disconnectDocument(o,t,e[r],n).catch(n.onRejection),await this.connectDocument(o,t,c,n).catch(n.onRejection),o.isArray?e[r].push(c):e[r]=c;break;case"$create":{const s=await this.add(o.to,c,{tx:n,relation:{id:t,key:o.getRelatedKey()}});o.isArray?e[r].push(s):e[r]=s;break}case"$delete":if(!o.isNullable())throw new s("Item cannot be deleted, relation is required");e[r]=o.isArray&&Array.isArray(e[r])?e[r].filter(e=>e!==c):null,await J(o.to,this,{},!0,{tx:n,singleton:{id:c}});break;case"$disconnect":{if(!o.isNullable())throw new s("Item cannot be disconnected, relation is required");if(!e[r]||0===e[r]?.lenth)break;const a=this.getModel(o.to).getRelation(o.getRelatedKey());await this.disconnectDocument(o,t,a.isArray?c:e[r],n).catch(n.onRejection),e[r]=o.isArray&&Array.isArray(e[r])?e[r].filter(e=>e!==c):null;break}case"$update":o.isArray?await this.update(o.to,c,!1,{tx:n}):null!=e[r]&&await this.update(o.to,c,!1,{tx:n,singleton:{id:t}});break;case"$deleteAll":if(c&&o.isArray&&Array.isArray(e[r])){const t=this.getModel(o.to),s=new Set(e[r]);await J(o.to,this,{[t.primaryKey]:e=>s.has(e)},!1,{tx:n}),e[r]=[]}break;case"$disconnectAll":if(c&&o.isArray&&Array.isArray(e[r])){for(const s of e[r])await this.disconnectDocument(o,t,s,n);e[r]=[]}}else e[r]=a.updateFn(e[r])}return e};if(a){const e=await c.get(a.id);if(!e)throw new l(`${d.name} with priamry key '${a.id}' not found`);const t=await f(e).catch(n.onRejection);return await c.put(t),[t]}{const e=B(t.where);return await c.openCursor(async t=>{const s=t.value;if(C(e,s)){const e=await f(s).catch(n.onRejection);if(await p(t.update(e)).then(()=>y.push(e)).catch(n.onRejection),r)return!1}return t.continue(),!0}),y}})}async connectDocument(e,t,r,n){const s=n.getStore(e.to),a=await s.get(r);if(!a)throw new l(`Document with Primary Key '${r}' could not be found in model '${e.to}'`);const o=e.getRelatedKey(),i=this.getModel(e.to).getRelation(o),c=a[o];if(i.isArray&&Array.isArray(c))c.includes(t)||c.push(t);else{if(c)throw new f;a[o]=t}return await s.put(a).catch(n.onRejection),r}async disconnectDocument(e,t,r,n){const s=n.getStore(e.to),a=await s.get(r);if(!a)throw new l(`Document with Primary Key '${r}' could not be found in model '${e.to}'`);const o=this.getModel(e.to).getRelation(e.getRelatedKey());if(o.isArray)a[e.getRelatedKey()].filter(e=>e!==t);else{if(!o.isOptional)throw new f;a[e.getRelatedKey()]=null}return await s.put(a).catch(n.onRejection),r}}class te{constructor(e,t){this.name=e,this.names=t,this.models={}}models;defineModel(e,t){if("object"==typeof e&&P.is(e))return this.models[e.name]=e,e;{if(!t)throw new Error("Model Fields must be defined");const r=new P(e,t);return this.models[e]=r,r}}compile(e){return new re(this.name,e)}}class re{constructor(e,t){this.name=e,this.models=t,this.modelKeys=m(this.models),this.schemas={};for(const n of this.modelKeys){const e=this.models[n],t={};for(const s of e.keys()){const a=e.get(s);if(F.is(a))t[s]=a.parse;else if(M.is(a)){const{onDelete:o}=a.getActions(),i=this.models[a.to],c=i.getPrimaryKey();t[s]=K[c.type.tag],a.isOptional?t[s]=new T(t[s],c.type).optional().parse:a.isArray&&(t[s]=t[s]=new T(t[s],c.type).array().parse);let l=!!a.getRelatedKey();if(!l)for(const[t,n]of i.relations())if(s!==t&&n.to===e.name&&n.name===a.name){if(l=!0,a.setRelatedKey(t),n.setRelatedKey(s),"SetNull"===o&&!n.isNullable())throw new r(`Key '${t}' on model '${i.name}': Non-optional relation cannot have the 'SetNull' action`);break}if(!l)throw new r(`Relation '${a.name}' of model ${n} does not have an equivalent relation on model '${a.to}'`)}else{if(!N.is(a))throw new r(`Unknown field value detected: ${JSON.stringify(a)}`);t[s]=K[a.type.tag]}}this.schemas[n]=t}}schemas;modelKeys;getModel(e){return this.models[e]}async createClient(e=1){const t=window.indexedDB.open(this.name,e);t.onupgradeneeded=e=>{const t=e.target.result;for(const r of this.modelKeys){const e=this.models[r];t.objectStoreNames.contains(e.name)||t.createObjectStore(e.name,{autoIncrement:e.getPrimaryKey().isAutoIncremented(),keyPath:e.primaryKey})}};const r=await p(t);return new ee(r,this)}keys(){return[...this.modelKeys]}}const ne=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,AbstractProperty:F,ArrayRelation:I,BaseRelation:M,DbClient:ee,FieldTypes:E,Model:P,OptionalRelation:j,PrimaryKey:N,Property:T,Relation:D,Type:k,Typing:R,VALIDATORS:K},Symbol.toStringTag,{value:"Module"}));export{te as Builder,G as CompiledQuery,P as Model,T as Property,e as StoreError,ne as core};
|
|
1
|
+
class e extends Error{code;constructor(e,t){super(`(${e}) ${t}`),this.code=e}}function t(t,n){return class extends e{static code;constructor(e=n){super(t,e)}static of(e){new this(e)}}}const n=t("INVALID_CONFIG","Configuration is invalid"),r=t("INVALID_TX","Transaction is invalid"),s=t("INVALID_ITEM","Item is invalid"),o=t("ASSERTION_FAILED","Assertion failed"),a=t("UNKNOWN","An unknown error occurred"),i=t("DELETE_FAILED","Item could not be deleted"),c=t("NOT_FOUND","Object Store Not Found"),u=t("NOT_FOUND","Document Not Found"),l=t("UPDATE_FAILED","Item could not be updated"),d=t("ADD_FAILED","Item could not be added"),y=t("OPEN_CURSOR","Cursor could not be opened"),f=t("GET_FAILED","Item could not be retrieved"),h=t("OVERWRITE_RELATION","Relation cannot be overwritten"),w=t("EXPORT","Export failed");function p(e,t){return new Promise(t=>{e.onsuccess=()=>{t(e.result)},e.onerror=()=>{}})}function m(e){return Object.keys(e)}function g(e){return Array.isArray(e)||(e=[e]),e}function b(){return crypto.randomUUID()}function S(){/* @__PURE__ */
|
|
2
|
+
return new Date}function A(e){return e}function v(e,t){for(const n of t.keys())e.add(n);return e}var $=/* @__PURE__ */(e=>(e[e.string=0]="string",e[e.number=1]="number",e[e.date=2]="date",e[e.boolean=3]="boolean",e[e.symbol=4]="symbol",e[e.bigint=5]="bigint",e[e.file=6]="file",e[e.void=7]="void",e[e.unknown=8]="unknown",e[e.literal=9]="literal",e[e.array=10]="array",e[e.set=11]="set",e[e.union=12]="union",e[e.optional=13]="optional",e[e.default=14]="default",e[e.object=15]="object",e[e.custom=16]="custom",e))($||{});const k={};function R(e){const t=k[e];return t||(k[e]={tag:e})}function O(){return R($.string)}function j(){return R($.number)}function K(){return R($.boolean)}function N(){return R($.bigint)}function M(){return R($.symbol)}function D(){return R($.file)}function T(){return R($.date)}function I(){return R($.unknown)}function E(e){return{tag:$.literal,value:e}}function x(e){return{tag:$.array,of:e}}function P(e,t){return{tag:$.default,of:e,value:t}}function _(e){return{tag:$.set,of:e}}function F(e){return{tag:$.union,options:e}}function L(e){return{tag:$.optional,of:e}}function C(e){return{tag:$.custom,...e}}const B=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Array:x,BigInt:N,Boolean:K,Custom:C,Date:T,Default:P,File:D,Literal:E,Number:j,Object:function(e){return{tag:$.object,props:e}},Optional:L,Set:_,String:O,Symbol:M,Union:F,Unknown:I,Void:function(){return R($.void)},getType:R},Symbol.toStringTag,{value:"Module"}));function V(e){switch(e.tag){case $.void:return"void";case $.literal:return String(e.value);case $.boolean:return"boolean";case $.number:return"number";case $.bigint:return"bigint";case $.string:return"string";case $.symbol:return"symbol";case $.unknown:return"unknown";case $.date:return"Date";case $.array:return`Array<${V(e.of)}>`;case $.set:return`Set<${V(e.of)}>`;case $.default:case $.optional:return`${V(e.of)} | undefined`;case $.union:return`Union<${e.options.map(e=>V(e)).join(", ")}>`;case $.file:return"File";case $.object:return`{${Object.keys(e.props).map(t=>`${t}: ${V(e.props[t])}`).join(",\n")}}`;case $.custom:return"custom"}}async function q(e,t){if(!G(e,t))throw new Error(`Value not of the proper type, expected type '${V(e)}', received '${JSON.stringify(t)}'`);switch(e.tag){case $.literal:case $.boolean:case $.number:case $.string:return t;case $.void:return;case $.bigint:return Number(t);case $.symbol:return t.description;case $.unknown:return JSON.stringify(t);case $.date:return t.getTime();case $.array:{const n=[];for(const r of t)n.push(q(e.of,r));return await Promise.all(n)}case $.set:{const n=[];for(const r of t.keys())n.push(q(e.of,r));return await Promise.all(n)}case $.optional:if(void 0===t)return;return await q(e.of,t);case $.union:for(const n of e.options)try{return await q(n,t)}catch{}throw new Error("Value union could not be serialized");case $.file:if(!(t instanceof File))throw new Error("Value is not a valid file");return{data:new Promise((e,n)=>{const r=new FileReader;r.onload=()=>e(r.result),r.onerror=n,r.readAsDataURL(t)}),name:t.name,type:t.type};case $.object:{const n={};for(const r in e.props){const s=e.props[r];if(!(r in t)&&s.tag!==$.optional&&s.tag!==$.default&&s.tag!==$.void)throw new Error(`Required property '${r}' not found`);n[r]=await q(s,t[r])}return n}case $.default:return await q(e.of,void 0===t?"function"==typeof e.value?e.value():e.value:t);case $.custom:return e.serialize?await e.serialize(t):JSON.stringify(t)}}async function U(e,t){switch(e.tag){case $.void:return;case $.literal:if(t!==e.value)throw new Error(`'${t}' is not equal to literal '${t}'`);return t;case $.boolean:if("boolean"!=typeof t)throw new Error(`'${t}' is not a boolean`);return t;case $.number:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a number`);return t;case $.bigint:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a bigint`);return BigInt(t);case $.string:if("string"!=typeof t)throw new Error(`'${t}' is not a string`);return t;case $.symbol:if("string"!=typeof t)throw new Error(`'${t}' is not a symbol`);return Symbol.for(t);case $.date:if("number"!=typeof t||isNaN(t))throw new Error(`'${t}' is not a date timestamp`);return new Date(t);case $.array:{if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);const n=[];for(const r of t)n.push(U(e.of,r));return await Promise.all(n)}case $.set:{if(!Array.isArray(t))throw new Error(`'${t}' is not an array`);const n=[];for(const r of t)n.push(U(e.of,r));return new Set(await Promise.all(n))}case $.optional:if(void 0===t)return;return U(e.of,t);case $.unknown:return"string"!=typeof t?t:JSON.parse(t);case $.union:for(const n of e.options)try{return await U(n,t)}catch{}throw new Error("Value did not match the union");case $.file:{if(!(t&&"object"==typeof t&&"data"in t&&"name"in t&&"type"in t&&"string"==typeof t.data&&"string"==typeof t.name&&"string"==typeof t.type))throw new Error("Value is not a valid file schema");const e=Buffer.from(t.data.replace(/^data:.+;base64,/,""),"base64");return new File([e],t.name,{type:t.type})}case $.default:return void 0===t?e.value:U(e.of,t);case $.custom:if(e.isType(t))return e.deserialize?await e.deserialize(t):JSON.parse(String(t));throw new Error("Value is not valid");case $.object:{if(!t||"object"!=typeof t)throw new Error("Value is not an object");const n={};for(const r in e.props){const s=e.props[r];if(!(r in t)&&s.tag!==$.optional)throw new Error(`Required property '${r}' not found`);n[r]=await U(s,t[r])}return n}}}function z(e,t){switch(e.tag){case $.literal:return t.tag===$.literal&&t.value===e.value;case $.boolean:case $.number:case $.symbol:case $.string:case $.bigint:return t.tag===e.tag||t.tag===$.literal&&typeof t.value===V(e);case $.unknown:return!0;case $.date:case $.file:case $.void:return t.tag===e.tag;case $.optional:case $.default:case $.set:case $.array:return t.tag===e.tag&&z(e.of,t.of);case $.union:if(t.tag===$.union){for(const n of t.options)if(!z(e,n))return!1;return!0}return e.options.some(e=>z(e,t));case $.object:if(t.tag!==$.object)return!1;for(const n in t.props){if(!e.props[n])return!1;if(!z(e.props[n],t.props[n]))return!1}return!0;case $.custom:return e===t}}function G(e,t){switch(e.tag){case $.void:return void 0===t;case $.literal:return t===e.value;case $.boolean:return"boolean"==typeof t;case $.number:return"number"==typeof t;case $.bigint:return"bigint"==typeof t;case $.string:return"string"==typeof t;case $.symbol:return"symbol"==typeof t;case $.unknown:return!0;case $.date:return t instanceof Date&&!isNaN(t.getTime());case $.array:return Array.isArray(t)&&t.every(t=>G(e.of,t));case $.set:return t instanceof Set&&Array.from(t).every(t=>G(e.of,t));case $.optional:case $.default:return void 0===t||G(e.of,t);case $.union:return e.options.some(e=>G(e,t));case $.file:return t instanceof File;case $.object:return!(!t||"object"!=typeof t)&&Object.keys(e.props).every(n=>G(e.props[n],t[n]));case $.custom:return e.isType(t)}}function Y(e,t){if(G(e,t)){switch(e.tag){case $.custom:if(e.parse)try{return{success:!0,data:e.parse(t)}}catch(n){return{success:!1,error:String(n)}}break;case $.default:return void 0===t?{success:!0,data:e.value}:{success:!0,data:t}}return{success:!0,data:t}}return{success:!1,error:`Value is not a valid '${V(e)}'`}}const J=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,Tag:$,Type:B,deserializeType:U,isSubtype:z,isType:G,parseType:Y,serializeType:q,typeToString:V},Symbol.toStringTag,{value:"Module"})),W=Symbol.for("primaryKey");class H{symbol=W;genFn;autoGenerate;type;constructor(e,t){if(e){if(e.tag>$.date)throw new n("Invalid Primary Key Type");this.type=e,t?(this.autoGenerate=!0,this.genFn=t):this.autoGenerate=!1}else this.autoGenerate=!1,this.type=j()}getType(){return this.type}generator(e){return this.genFn=e,this.autoGenerate=!0,this}autoIncrement(){if(this.type.tag===$.number)return this.genFn=void 0,this.autoGenerate=!0,this;throw new n("Primary key must be a number to use autoIncrement()")}uuid(){if(!window.isSecureContext)throw new Error("Window is not in a secure context");return new H(O(),b)}date(){return new H(T(),S)}genKey(){if(this.genFn)return this.genFn();throw new Error("Generator function not defined")}isAutoIncremented(){return this.autoGenerate&&!this.genFn}static is(e){return e?.symbol===W}static compareKeyValue(e,t){if(typeof e!=typeof t)return!1;switch(typeof e){case"string":case"number":return e===t;case"object":return e.getTime()===t.getTime();default:return!1}}static validKeyTag=F([O(),j(),T()])}class X{constructor(e,t="",n=!1,r=!1,s){this.to=e,this.name=t,this.isOptional=n,this.isArray=r,this.relatedKey="",this.actions={onDelete:s||"Restrict"}}static SYMBOL=Symbol.for("baseRelation");BASE_SYMBOL=X.SYMBOL;actions;relatedKey;getActions(){return{...this.actions}}isNullable(){return this.isArray||this.isOptional}setRelatedKey(e){this.relatedKey=e}getRelatedKey(){return this.relatedKey}toString(){return`${this.isArray?"Array":this.isOptional?"Optional":"Standard"} relation from this model to model '${this.to}' on key '${this.relatedKey}'`}getBaseSymbol(){return this.BASE_SYMBOL}static is(e){return"getBaseSymbol"in e&&e.getBaseSymbol()===X.SYMBOL}}class Q extends X{static R_SYMBOL=Symbol.for("relation");symbol=Q.R_SYMBOL;constructor(e,t={}){super(e,t.name,!1,!1,t.onDelete)}array({onDelete:e}={}){return new Z(this.to,this.name,e)}optional({onDelete:e}={}){return new ee(this.to,this.name,e)}onDelete(e){return this.actions.onDelete=e,this}static is(e){return e?.symbol===this.R_SYMBOL}}class Z extends X{static A_SYMBOL=Symbol.for("arrayRelation");symbol=Z.A_SYMBOL;constructor(e,t,n="None"){super(e,t,!1,!0,n)}static is(e){return e?.symbol===this.A_SYMBOL}}class ee extends X{static O_SYMBOL=Symbol.for("optionalRelation");symbol=ee.O_SYMBOL;constructor(e,t,n="None"){super(e,t,!0,!1,n)}static is(e){return e?.symbol===this.O_SYMBOL}}var te=/* @__PURE__ */(e=>(e[e.Property=0]="Property",e[e.Relation=1]="Relation",e[e.PrimaryKey=2]="PrimaryKey",e[e.Invalid=3]="Invalid",e))(te||{});const ne=Symbol.for("property");class re{constructor(e,t){this.type=e,this.options={unique:t?.unique??!1}}symbol=ne;hasDefault=!1;options;unique(){switch(this.type.tag){case $.boolean:case $.string:case $.number:case $.symbol:return this.options.unique=!0,this;default:throw new Error("A non-primitive cannot be a unique value")}}hasDefaultValue(){return this.hasDefault}static relation(e,t){return new Q(e,t)}static primaryKey(e="number"){return new H(this.nameToType(e))}static nameToType(e){switch(e){case"boolean":return K();case"bigint":return N();case"number":return j();case"string":return O();case"symbol":return M();default:return I()}}static is(e){return"object"==typeof e&&e?.symbol===ne}array(){return new re(x(this.type),this.options)}default(e){return this.hasDefault=!0,new re(P(this.type,e),this.options)}optional(){return new re(L(this.type),this.options)}static array(e,t){return new re(x(e.type),t)}static boolean(e){return new re(K(),e)}static custom(e,t){return new re(C({isType:t=>e(t).success,serialize:t?.serialize,deserialize:t?.deserialize}),t)}static date(e){return new re(T(),e)}static file(e){return new re(D(),e)}static literal(e,t){return new re(E(e),t)}static number(e){return new re(j(),e)}static string(e){return new re(O(),e)}static set(e,t){return new re(_(e.type),t)}static union(e,t){return new re(F(e.map(e=>e.type)),t)}static generateArrayValidator(e){return t=>{if(Array.isArray(t)){const n=[];for(const r of t){const t=e(r);if(!t.success)return t;n.push(t.data)}return{success:!0,data:n}}return{success:!1,error:"Value is not an array"}}}}const se=Symbol.for("model");class oe{constructor(t,n){this.name=t,this.fields=n,this.fieldKeys=m(n);for(const e of this.fieldKeys){const t=this.fields[e];X.is(t)&&t.to!==this.name&&this.relationLinks.add(t.to)}const r=this.fieldKeys.find(e=>H.is(this.fields[e]));if(!r)throw new e("INVALID_CONFIG",`Model ${this.name} has no primary key`);this.primaryKey=r}symbol=se;fieldKeys;relationLinks=/* @__PURE__ */new Set;cache={};primaryKey;get(e){return this.fields[e]}getPrimaryKey(){return this.fields[this.primaryKey]}getRelation(e){const t=this.fields[e];if(t&&X.is(t))return t}keyType(e){const t=this.fields[e];return t?re.is(t)?te.Property:X.is(t)?te.Relation:H.is(t)?te.PrimaryKey:te.Invalid:te.Invalid}links(){return this.relationLinks.keys()}*relations(){for(const e of this.fieldKeys)X.is(this.fields[e])&&(yield[e,this.fields[e]])}*entries(){for(const e of this.fieldKeys)yield[e,this.fields[e]]}keys(){return this.fieldKeys}parseField(e,t){return re.is(this.fields[e])?Y(this.fields[e].type,t):null}getDeletedStores(e){if(this.cache.delete)return this.cache.delete;const t=/* @__PURE__ */new Set,n=[this.name];let r;for(;n.length>0;){const s=n.shift();if(t.has(s))continue;r=e.getModel(s);const o=r.cache.delete;if(o)v(t,o);else{t.add(s);for(const e of r.links())t.has(e)||n.push(e)}}return this.cache.delete=t,t}static is(e){return e?.symbol===se}}class ae{constructor(e,t){this.tx=e,this.internal=t}add(e){return this.handleRequest(this.internal.add(e),()=>new d)}get(e){return this.handleRequest(this.internal.get(e),()=>new f)}async assertGet(e){const t=await this.handleRequest(this.internal.get(e),()=>new f);if(!t)throw this.tx.abort(new u);return t}put(e){return this.handleRequest(this.internal.put(e),()=>new l)}delete(e){return this.handleRequest(this.internal.delete(e),()=>new i)}async openCursor(t,n={}){const r=n.onError||(()=>new y),s=this.internal.openCursor(n.query,n.direction);await new Promise((n,o)=>{s.onsuccess=async s=>{try{s.target||o(this.tx.abort(r()));const e=s.target.result;e&&await t(e,this.tx)||n()}catch(i){o(this.tx.abort(i instanceof e?i:new a(String(i))))}},s.onerror=()=>{o(this.tx.abort(r()))}})}handleRequest(e,t){return new Promise(n=>{e.onsuccess=()=>{n(e.result)},e.onerror=()=>{throw this.tx.abort(t())}})}}class ie{internal;status;error=null;storeNames;inWrap=!1;onRejection=t=>{throw t instanceof e?this.abort(t):this.abort(new a(String(t)))};objectStores;constructor(e,t,n,r={}){e instanceof ie?(this.internal=e.getInternal(),this.storeNames=e.storeNames,this.status=e.status,this.error=e.error,this.objectStores=e.getAllStores()):(this.internal=e.transaction(t,n),this.status=0,this.storeNames=Array.from(this.internal.objectStoreNames),this.objectStores=new Map(this.storeNames.map(e=>[e,this.getObjectstore(e)])),this.internal.onabort=this.registerHandler(1,r.onAbort),this.internal.onerror=this.registerHandler(3,r.onError),this.internal.oncomplete=this.registerHandler(2,r.onComplete))}static create(e,t,n,r){return r||new ie(e,t,n)}abort(e){return 1!==this.status&&this.internal.abort(),this.status=1,this.error=e,this.error}commit(){this.internal.commit()}getInternal(){return this.internal}getStore(e){const t=this.objectStores.get(e);if(!t)throw this.abort(new r(`Store '${e}' is not a part of this transaction`));return t}getAllStores(){return this.objectStores}get mode(){return this.internal.mode}is(e){return this.status===e}contains(e){Array.isArray(e)||(e=[e]);for(const t of e)if(!this.internal.objectStoreNames.contains(t))return!1;return!0}assertIsArray(e,t="Value is not an array"){if(!Array.isArray(e))throw this.abort(new o(t))}getObjectstore(e){try{return new ae(this,this.internal.objectStore(e))}catch{throw this.abort(new c(`No ObjectStore with the name '${e}' found`))}}registerHandler(e,t=()=>{}){return n=>{this.status=e,t(this,n)}}async wrap(t){if(this.inWrap)return await t(this);this.inWrap=!0;try{const e=await t(this);return this.inWrap=!1,e}catch(n){throw this.inWrap=!1,n instanceof e?this.abort(n):this.abort(new a(JSON.stringify(n)))}}}function ce(e){if(!e)return[];const t=[];for(const n in e)if(Object.hasOwn(e,n))switch(typeof e[n]){case"function":t.push([n,!0,e[n]]);break;case"object":if(e[n]instanceof Date){const r=e[n];t.push([n,!0,e=>e instanceof Date&&e.getTime()===r.getTime()])}break;default:t.push([n,!1,e[n]])}return t}function ue(e,t){if(!t||"object"!=typeof t)return!1;for(const n of e)if(n[1]){if(!n[2](t[n[0]]))return!1}else if(n[2]!==t[n[0]])return!1;return!0}function le(e,t,n={},r){const o=t.getModel(e);if(n.include&&n.select)throw new s("include and select cannot both be defined");const a=ce(n.where),i=n.select?"select":n.include?"include":"";if(i){const e=n[i],r=!!n.select,s=[];for(const n in e)if(Object.hasOwn(e,n)&&e[n])switch(o.keyType(n)){case te.Relation:{const r=o.getRelation(n),a="object"==typeof e[n]?le(r.to,t,e[n]):A,i=r.getRelatedKey();if(r.isArray){const e=async(e,t)=>{const n=[],s=t.getStore(r.to);for(const r of e){const e=await a(await s.assertGet(r),t);e&&(delete e[i],n.push(e))}return n};s.push({key:n,getValue:e})}else{const e=async(e,t)=>await a(await t.getStore(r.to).assertGet(e),t);s.push({key:n,getValue:e})}break}case te.Property:case te.PrimaryKey:r&&s.push({key:n})}return r?async(e,t)=>{if(!ue(a,e))return;const n={};for(const{key:r,getValue:o}of s)n[r]=o?await o(e[r],t):e[r];return n}:async(e,t)=>{if(ue(a,e)){for(const{key:n,getValue:r}of s)e[n]=await r(e[n],t);return e}}}return e=>ue(a,e)?e:void 0}function de(e,t,n,r){const s=/* @__PURE__ */new Set([e]);if(n){const o=r.getModel(e);for(const e in t){const a=o.getRelation(e),i=g(t[e]);if(a)for(const e of i)if(e&&"object"==typeof e)for(const t in e)if(Object.hasOwn(e,t))switch(t){case"$connect":case"$connectMany":case"$disconnect":case"$disconnectMany":case"$disconnectAll":s.add(a.to);break;case"$delete":case"$deleteMany":case"$deleteAll":v(s,o.getDeletedStores(r));break;case"$create":v(s,de(a.to,e[t],n,r));break;case"$createMany":e[t].forEach(e=>v(s,de(a.to,e,n,r)));break;case"$update":v(s,de(a.to,e[t].data,n,r));break;case"$updateMany":e[t].forEach(e=>v(s,de(a.to,e.data,n,r)))}}}else{const n=r.getModel(e);for(const e in t){const o=n.getRelation(e);if(o)switch(typeof t[e]){case"object":v(s,de(o.to,ye(t[e]),!1,r));break;case"boolean":s.add(o.to)}}}return s}function ye(e){return e.select?e.select:e.include?e.include:{}}class fe{constructor(e,t,n){this.client=e,this.name=t,this.accessedStores=Array.from(de(t,ye(n),!1,this.client)),this.selectClause=le(t,this.client,n)}accessedStores;selectClause;async find(){return await this._find(!1)}async findFirst(){return(await this._find(!0))[0]}async _find(e){const t=this.client.createTransaction("readonly",this.accessedStores);return await t.wrap(async t=>{const n=[],r=t.getStore(this.name);return await r.openCursor(async r=>{const s=await this.selectClause(r.value,t);return s&&n.push(s),(!e||!n.length)&&(r.continue(),!0)}),n})}}function he(e,t,r){return async s=>{if(!s)return!1;const o=s[e.primaryKey];for(const[a,c]of e.relations()){const{onDelete:u}=c.getActions(),l=s[a],d=t.getModel(c.to);switch(u){case"Cascade":if(c.isArray){r.assertIsArray(l);const e=new Set(l),n=he(d,t,r),s=r.getStore(c.to);await s.openCursor(async t=>(e.has(t.value[d.primaryKey])&&await n(t.value),t.continue(),!0)).catch(r.onRejection)}else l&&await we(c.to,t,void 0,void 0,{tx:r,singleton:{id:l}});break;case"SetNull":{if(!l)break;const e=g(l),t=r.getStore(c.to),s=c.getRelatedKey(),a=d.getRelation(s);if(!a)throw new n(`Relation '${c.name}' has an invalid relation key '${c.getRelatedKey()}'`);if(!a.isNullable())throw new n(`Key '${s}' on model '${s}': Non-optional relation cannot have the 'SetNull' action`);for(const n of e){const e=await t.get(n);if(!e)continue;const i=e[s];if(a.isArray){r.assertIsArray(i);const e=i.indexOf(o);if(-1===e)continue;i.splice(e,1)}else e[s]=null;await t.put(e)}break}case"Restrict":if(Array.isArray(l)&&l.length>0||l)throw new i(`Key '${a}' on model '${e.name}' deletion is restricted while there is an active relation`)}}return!0}}async function we(e,t,n,r=!1,s={}){const{singleton:o,finalStep:a=!0}=s,i=t.getModel(e),c=s.tx?s.tx.storeNames:Array.from(i.getDeletedStores(t)),u=ie.create(t.getDb(),c,"readwrite",s.tx);return await u.wrap(async s=>{const c=s.getStore(e);let u=0;const l=he(i,t,s);if(o)await l(await c.assertGet(o.id))&&(await c.delete(o.id),u++);else{const e=ce(n);let t;await c.openCursor(async n=>{const o=n.value;return ue(e,o)&&await l(o)&&(t=p(n.delete()).catch(s.onRejection)),!(r&&u>0)&&(n.continue(),!0)}),t&&a&&await t}return u})}function pe(e){return"string"!=typeof e?String(e):e.replaceAll(/~|\//g,e=>"~"===e?"~0":"~1")}async function me(e,t,n,r){r=ie.create(e.getDb(),[t],"readonly",r);const s=ce(n),a=e.getModel(t);return await r.wrap(async e=>{const n={};return await e.getStore(t).openCursor(async e=>{if(ue(s,e.value)){for(const[t,n]of a.entries())if(X.is(n))if(n.isArray){if(!Array.isArray(e.value[t]))throw new o("Expected array type");const r=[];for(const s of e.value[t])r.push(`/${n.to}/${pe(s)}`);e.value[t]=r}else(n.isOptional&&e.value[t]||!n.isNullable())&&(e.value[t]=`/${n.to}/${pe(e.value[t])}`);else{if(!re.is(n)&&!H.is(n))throw new w(`Unrecognized model field on key '${t}'`);e.value[t]=await q(n.type,e.value[t])}if(n[e.value[a.primaryKey]])throw new w("Duplicate primary key detected "+JSON.stringify(n));n[e.value[a.primaryKey]]=e.value}return e.continue(),!0}),n})}function ge(e,t){const n=[`## ${e.name}`],r=[];for(const[s,o]of e.entries())H.is(o)?r.unshift(s):r.push(s);n.push(r.join(","));for(const s of Object.values(t)){const e=[];for(const t of r)switch(typeof s[t]){case"object":e.push(JSON.stringify(s[t]));break;case"undefined":e.push("");break;default:e.push(String(s[t]))}n.push(e.join(","))}return n.join("\n")}class be{constructor(e,t,n){this.name=e,this.content=t,this.extension=n}toFile(e=`${this.name}_dump.${this.extension}`,t){return new File([this.content],e,t)}download(e=`${this.name}_dump.${this.extension}`,t){const n=URL.createObjectURL(this.toFile(e,t)),r=document.createElement("a");r.href=n,r.download=e,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}static toJson(e,t,n){return new this(e,JSON.stringify(t,void 0,n?.pretty??1?4:void 0),"json")}static toCsvStore(e,t){return new this(e.name,ge(e,t),"csv")}static toCsvDb(e,t,n){const r=[`# ${e.name}`];for(const s of t)r.push(ge(e.getModel(s),n[s]));return new this(e.name,r.join("\n"),"csv")}}class Se{constructor(e,t){this.db=e,this.models=t,this.name=this.db.name,this.version=this.db.version,this.stores={};for(const n of this.models.keys())this.stores[n]=this.createInterface(n)}name;version;stores;getDb(){return this.db}getStore(e){return this.stores[e]}getStoreNames(){return this.models.keys()}createTransaction(e,t,n){return new ie(this.db,t,e,n)}async drop(){await p(window.indexedDB.deleteDatabase(this.name))}async dump(e,t,n){const r=await async function(e,t){const n={};t=t||e.getStoreNames();const r=e.createTransaction("readonly",t);for(const s of t)n[s]=await me(e,s,void 0,r);return n}(this,t);switch(e){case"json":return be.toJson(this.name,r,n);case"csv":return be.toCsvDb(this,t||this.getStoreNames(),r)}}deleteAllStores(){for(const e of this.models.keys())this.db.deleteObjectStore(e)}deleteStore(e){Array.isArray(e)||(e=[e]);for(const t of e)this.db.deleteObjectStore(t)}getModel(e){const t=this.models.getModel(e);if(!t)throw new c(`Model with name '${e}' not found`);return t}getAccessedStores(e,t,n,r){return r?r.storeNames:Array.from(de(e,t,n,this))}createInterface(e){return{add:async(t,n)=>await this.add(e,t,{tx:n}),addMany:async(t,n)=>{if(!n){const r=/* @__PURE__ */new Set;for(const n of t)v(r,de(e,n,!0,this));n=this.createTransaction("readwrite",Array.from(r))}const r=[];for(const s of t)r.push(await this.add(e,s,{tx:n}));return r},findFirst:async(t,n)=>(await this.find(e,t,!0,{tx:n}))[0],find:async(t,n)=>await this.find(e,t,!1,{tx:n}),get:async t=>{const n=this.createTransaction("readonly",e);return await n.getStore(e).get(t)},update:async(t,n)=>(await this.update(e,{data:n},!0,{singleton:{id:t}}))[0],updateFirst:async(t,n)=>(await this.update(e,t,!0,{tx:n}))[0],updateMany:async(t,n)=>await this.update(e,t,!1,{tx:n}),compileQuery:t=>new fe(this,e,t),delete:async t=>await we(e,this,void 0,void 0,{singleton:{id:t}})>0,deleteFirst:async t=>await we(e,this,t,!0)>0,deleteMany:async t=>await we(e,this,t,!1),dump:async(t,n,r)=>{const s=await me(this,e,n);switch(t){case"json":return be.toJson(e,s,r);case"csv":return be.toCsvStore(this.getModel(e),s)}}}}async add(e,t,n={}){let{tx:r}=n;const{relation:o}=n,i=this.getAccessedStores(e,t,!0,r);return r=ie.create(this.db,i,"readwrite",r),await r.wrap(async n=>{const r=n.getStore(e),i=this.getModel(e),c=i.getPrimaryKey(),u=o?{[o.key]:i.getRelation(o.key)?.isArray?[o.id]:o.id}:{},l=c.isAutoIncremented()?{...u}:{...u,[i.primaryKey]:t[i.primaryKey]??c.genKey()},d=await r.add(l),y={},f=/* @__PURE__ */new Set;for(const o in t){f.add(o);const r=t[o];switch(i.keyType(o)){case te.Invalid:throw new s(`Key '${o}' does ont exist on model '${e}'`);case te.Property:{const e=i.parseField(o,r);if(!e)throw new a;if(!e.success)throw new s(`Key '${o}' has the following validation error: ${e.error}`);y[o]=e.data;break}case te.Relation:{if(!r)continue;const e=g(r),t=i.getRelation(o);if(t.isArray&&(y[o]=[],"$createMany"in r||"$connectMany"in r)){const t=[];for(const e of r.$createMany??[])t.push({$create:e});for(const e of r.$connectMany??[])t.push({$connect:e});e.push(...t)}const a=this.getModel(t.to).getRelation(t.getRelatedKey()),c=/* @__PURE__ */new Set;for(const r of e){const e=m(r)[0];if(!e)throw new s(`Key '${o}' cannot be an empty connection object`);switch(e){case"$connect":{const i=r[e];if(c.has(i))throw new s(`Primary key '${i}' was already used for a connection`);if(c.add(i),!a)throw new s(`Could not find corresponding relation '${t.name}'`);await this.connectDocument(t,d,i,n),t.isArray?y[o].push(i):y[o]=i;break}case"$create":{const s=await this.add(t.to,r[e],{tx:n,relation:{id:d,key:t.getRelatedKey()}});t.isArray?y[o].push(s):y[o]=s;break}case"$connectMany":case"$createMany":break;default:throw new s(`Connection Object on key '${o}' has an unknown key '${e}'`)}if(!t.isArray)break}break}case te.PrimaryKey:}}const h=Array.from(new Set(i.keys()).difference(f));for(const e of h)switch(i.keyType(e)){case te.Property:{const t=i.parseField(e,void 0);if(!t)throw new a("A parsing error occurred");if(!t.success)throw new s(`Key '${e}' is missing`);y[e]=t.data;break}case te.Relation:{const t=i.getRelation(e),n=u[e];if(t.isArray)y[e]=n??[];else if(t.isOptional)y[e]=n??null;else{if(!n)throw new s(`Required relation '${e}' is not defined`);y[e]=n}break}case te.Invalid:case te.PrimaryKey:}return await r.put({[i.primaryKey]:d,...y})})}async clear(e,t){await we(e,this,void 0,!1,t)}async find(e,t,n,r={}){let{tx:s}=r;const o=this.getAccessedStores(e,ye(t),!1,s);s=ie.create(this.db,o,"readonly",s);const a=[];return await s.wrap(async r=>{const s=r.getStore(e),o=le(e,this,t);return await s.openCursor(async e=>{const t=await o(e.value,r);return t&&a.push(t),(!n||!a.length)&&(e.continue(),!0)}),a})}async update(e,t,n,r={}){const{singleton:o}=r,i=r.singleton?t:t.data,c=this.getAccessedStores(e,i,!0,r.tx),d=ie.create(this.db,c,"readwrite",r.tx);return await d.wrap(async r=>{const c=r.getStore(e),d=this.getModel(e),y=[];for(const e of m(i))switch(d.keyType(e)){case te.Property:y.push({key:e,isRelation:!1,updateFn:"function"==typeof i[e]?i[e]:()=>i[e]});break;case te.Relation:{const t=g(i[e]);if(!t)continue;const n=[];for(const e of t)for(const t in e){switch(t){case"$createMany":case"$connectMany":case"$updateMany":case"$deleteMany":case"$disconnectMany":{const r=t.substring(0,t.length-4);for(const s of e[t])n.push([r,s]);break}default:n.push([t,e[t]])}break}y.push({actions:n,key:e,isRelation:!0,relation:d.getRelation(e)});break}case te.PrimaryKey:throw new l("Primary key field cannot be updated");case te.Invalid:default:throw new a(`Unknown key '${e}'`)}const f=[],h=async e=>{const t=e[d.primaryKey];for(const{key:n,...o}of y){const a=o.relation;if(o.isRelation)for(const[i,c]of o.actions)switch(i){case"$connect":e[n]&&!a.isArray&&await this.disconnectDocument(a,t,e[n],r).catch(r.onRejection),await this.connectDocument(a,t,c,r).catch(r.onRejection),a.isArray?e[n].push(c):e[n]=c;break;case"$create":{const s=await this.add(a.to,c,{tx:r,relation:{id:t,key:a.getRelatedKey()}});a.isArray?e[n].push(s):e[n]=s;break}case"$delete":if(!a.isNullable())throw new s("Item cannot be deleted, relation is required");e[n]=a.isArray&&Array.isArray(e[n])?e[n].filter(e=>e!==c):null,await we(a.to,this,{},!0,{tx:r,singleton:{id:c}});break;case"$disconnect":{if(!a.isNullable())throw new s("Item cannot be disconnected, relation is required");if(!e[n]||0===e[n]?.lenth)break;const o=this.getModel(a.to).getRelation(a.getRelatedKey());await this.disconnectDocument(a,t,o.isArray?c:e[n],r).catch(r.onRejection),e[n]=a.isArray&&Array.isArray(e[n])?e[n].filter(e=>e!==c):null;break}case"$update":a.isArray?await this.update(a.to,c,!1,{tx:r}):null!=e[n]&&await this.update(a.to,c,!1,{tx:r,singleton:{id:t}});break;case"$deleteAll":if(c&&a.isArray&&Array.isArray(e[n])){const t=this.getModel(a.to),s=new Set(e[n]);await we(a.to,this,{[t.primaryKey]:e=>s.has(e)},!1,{tx:r}),e[n]=[]}break;case"$disconnectAll":if(c&&a.isArray&&Array.isArray(e[n])){for(const s of e[n])await this.disconnectDocument(a,t,s,r);e[n]=[]}}else e[n]=o.updateFn(e[n])}return e};if(o){const e=await c.get(o.id);if(!e)throw new u(`${d.name} with priamry key '${o.id}' not found`);const t=await h(e).catch(r.onRejection);return await c.put(t),[t]}{const e=ce(t.where);return await c.openCursor(async t=>{const s=t.value;if(ue(e,s)){const e=await h(s).catch(r.onRejection);if(await p(t.update(e)).then(()=>f.push(e)).catch(r.onRejection),n)return!1}return t.continue(),!0}),f}})}async connectDocument(e,t,n,r){const s=r.getStore(e.to),o=await s.get(n);if(!o)throw new u(`Document with Primary Key '${n}' could not be found in model '${e.to}'`);const a=e.getRelatedKey(),i=this.getModel(e.to).getRelation(a),c=o[a];if(i.isArray&&Array.isArray(c))c.includes(t)||c.push(t);else{if(c)throw new h;o[a]=t}return await s.put(o).catch(r.onRejection),n}async disconnectDocument(e,t,n,r){const s=r.getStore(e.to),o=await s.get(n);if(!o)throw new u(`Document with Primary Key '${n}' could not be found in model '${e.to}'`);const a=this.getModel(e.to).getRelation(e.getRelatedKey());if(a.isArray)o[e.getRelatedKey()].filter(e=>e!==t);else{if(!a.isOptional)throw new h;o[e.getRelatedKey()]=null}return await s.put(o).catch(r.onRejection),n}}class Ae{constructor(e,t){this.name=e,this.names=t,this.models={}}models;defineModel(e,t){if("object"==typeof e&&oe.is(e))return this.models[e.name]=e,e;{if(!t)throw new Error("Model Fields must be defined");const n=new oe(e,t);return this.models[e]=n,n}}compile(e){return new ve(this.name,e)}}class ve{constructor(e,t){this.name=e,this.models=t,this.modelKeys=m(this.models),this.schemas={};for(const r of this.modelKeys){const e=this.models[r],t={};for(const[s,o]of e.entries())if(re.is(o))t[s]=o.type;else if(X.is(o)){const{onDelete:a}=o.getActions(),i=this.models[o.to],c=i.getPrimaryKey();t[s]=c.type,o.isOptional?t[s]=L(t[s]):o.isArray&&(t[s]=x(t[s]));let u=!!o.getRelatedKey();if(!u)for(const[t,r]of i.relations())if(s!==t&&r.to===e.name&&r.name===o.name){if(u=!0,o.setRelatedKey(t),r.setRelatedKey(s),"SetNull"===a&&!r.isNullable())throw new n(`Key '${t}' on model '${i.name}': Non-optional relation cannot have the 'SetNull' action`);break}if(!u)throw new n(`Relation '${o.name}' of model ${r} does not have an equivalent relation on model '${o.to}'`)}else{if(!H.is(o))throw new n(`Unknown field value detected: ${JSON.stringify(o)}`);t[s]=o.type}this.schemas[r]=t}}schemas;modelKeys;getModel(e){return this.models[e]}async createClient(e=1){const t=window.indexedDB.open(this.name,e);t.onupgradeneeded=e=>{const t=e.target.result;for(const n of this.modelKeys){const e=this.models[n];t.objectStoreNames.contains(e.name)||t.createObjectStore(e.name,{autoIncrement:e.getPrimaryKey().isAutoIncremented(),keyPath:e.primaryKey})}};const n=await p(t);return new Se(n,this)}keys(){return[...this.modelKeys]}}const $e=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,ArrayRelation:Z,BaseRelation:X,DbClient:Se,FieldTypes:te,Model:oe,OptionalRelation:ee,PrimaryKey:H,Property:re,Relation:Q,Tag:$,Type:B,Typing:J,deserializeType:U,isSubtype:z,isType:G,parseType:Y,serializeType:q,typeToString:V},Symbol.toStringTag,{value:"Module"}));export{Ae as Builder,fe as CompiledQuery,oe as Model,re as Property,e as StoreError,$e as core};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CompiledDb } from '../builder.js';
|
|
2
|
-
import { ValidValue, BaseRelation, OptionalRelation, ArrayRelation, RelationOutput, Relation,
|
|
2
|
+
import { ValidValue, BaseRelation, OptionalRelation, ArrayRelation, RelationOutput, Relation, Property, PrimaryKey, TypeTag } from '../field';
|
|
3
3
|
import { Dict, Keyof } from '../util-types.js';
|
|
4
4
|
import { default as Model } from './model.js';
|
|
5
5
|
export type FindPrimaryKey<F extends Record<string, ValidValue>> = Extract<{
|
|
@@ -20,7 +20,7 @@ export type RelationValue<Name extends string, C> = Name extends keyof C ? C[Nam
|
|
|
20
20
|
*/
|
|
21
21
|
export type GetRelationField<F, C> = F extends Relation<infer To, any> ? RelationValue<To, C> : F extends OptionalRelation<infer To, any> ? RelationValue<To, C> | null : F extends ArrayRelation<infer To, any> ? RelationValue<To, C>[] : never;
|
|
22
22
|
export type ModelStructure<F extends Dict<ValidValue>, C> = {
|
|
23
|
-
[K in keyof F]: F[K] extends
|
|
23
|
+
[K in keyof F]: F[K] extends Property<infer Output, any> ? Output : F[K] extends PrimaryKey<any, infer Type> ? Type : GetRelationField<F[K], C>;
|
|
24
24
|
};
|
|
25
25
|
export type ModelType<M extends Model<any, any, any>, C extends CompiledDb<any, any, any>> = M extends Model<any, infer Fields, any> ? C extends CompiledDb<any, any, infer Collection> ? ModelStructure<Fields, Collection> : never : never;
|
|
26
26
|
export type ExtractFields<M extends Model<any, any, any>> = M extends Model<any, infer Fields, any> ? Fields : never;
|
|
@@ -28,10 +28,13 @@ export type AllRelationKeys<M extends Model<any, any, any>> = M extends Model<an
|
|
|
28
28
|
[K in Keyof<Fields>]: Fields[K] extends BaseRelation<any, any> ? K : never;
|
|
29
29
|
}[Keyof<Fields>] : never;
|
|
30
30
|
export type RelationlessModelStructure<M extends Model<any, any, any>> = M extends Model<any, infer Fields, any> ? Omit<{
|
|
31
|
-
[K in Keyof<Fields>]: Fields[K] extends BaseRelation<any, any> ? unknown : Fields[K] extends
|
|
31
|
+
[K in Keyof<Fields>]: Fields[K] extends BaseRelation<any, any> ? unknown : Fields[K] extends Property<infer Type, any> ? Type : Fields[K] extends PrimaryKey<any, infer Type> ? Type : never;
|
|
32
32
|
}, AllRelationKeys<M>> : never;
|
|
33
|
+
export type TypeTagWrap<T extends Dict> = {
|
|
34
|
+
[K in keyof T]: TypeTag;
|
|
35
|
+
};
|
|
33
36
|
export type CollectionSchema<C> = C extends Record<infer Keys, Model<any, any, any>> ? {
|
|
34
|
-
[K in Keys]: C[K] extends Model<any, infer Fields, any> ?
|
|
37
|
+
[K in Keys]: C[K] extends Model<any, infer Fields, any> ? TypeTagWrap<ModelStructure<Fields, C>> : never;
|
|
35
38
|
} : never;
|
|
36
39
|
export type FindRelationKey<From extends string, RelationName extends string, M extends Model<any, any, any>> = M extends Model<any, infer Fields, any> ? {
|
|
37
40
|
[K in Keyof<Fields>]: Fields[K] extends BaseRelation<From, infer CurName> ? CurName extends RelationName ? K : never : never;
|
package/dist/model/model.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export default class Model<Name extends string, F extends Record<string, ValidVa
|
|
|
33
33
|
* Generator for all of the entries present on the model
|
|
34
34
|
*/
|
|
35
35
|
entries(): Generator<[key: string, value: ValidValue]>;
|
|
36
|
-
keys(): Keyof<F>[];
|
|
36
|
+
keys(): readonly Keyof<F>[];
|
|
37
37
|
parseField<K extends Keyof<F>>(field: K, value: unknown): ParseResult<any>;
|
|
38
38
|
getDeletedStores<ModelNames extends string, Models extends CollectionObject<ModelNames>>(client: DbClient<string, ModelNames, Models>): Set<ModelNames>;
|
|
39
39
|
static is<Name extends string, Fields extends Dict<ValidValue>, Primary extends FindPrimaryKey<Fields> = FindPrimaryKey<Fields>>(value: object): value is Model<Name, Fields, Primary>;
|
package/dist/object-store.d.ts
CHANGED
|
@@ -2,10 +2,13 @@ import { StoreError } from './error.js';
|
|
|
2
2
|
import { ValidKey } from './field';
|
|
3
3
|
import { Transaction } from './transaction.js';
|
|
4
4
|
import { Dict, Promisable } from './util-types.js';
|
|
5
|
+
/**
|
|
6
|
+
* A paper thin wrapper around IDBObjectStore
|
|
7
|
+
*/
|
|
5
8
|
export declare class ObjectStore<T = Dict> {
|
|
6
9
|
private readonly tx;
|
|
7
|
-
readonly
|
|
8
|
-
constructor(tx: Transaction<IDBTransactionMode, string>,
|
|
10
|
+
readonly internal: IDBObjectStore;
|
|
11
|
+
constructor(tx: Transaction<IDBTransactionMode, string>, internal: IDBObjectStore);
|
|
9
12
|
add(item: T): Promise<ValidKey>;
|
|
10
13
|
/**
|
|
11
14
|
* Attempts to retrieve the value from the object store.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { MaybeGenerator, Promisable } from '../util-types';
|
|
2
|
+
export declare const enum Tag {
|
|
3
|
+
string = 0,
|
|
4
|
+
number = 1,
|
|
5
|
+
date = 2,
|
|
6
|
+
boolean = 3,
|
|
7
|
+
symbol = 4,
|
|
8
|
+
bigint = 5,
|
|
9
|
+
file = 6,
|
|
10
|
+
void = 7,
|
|
11
|
+
unknown = 8,
|
|
12
|
+
literal = 9,
|
|
13
|
+
array = 10,
|
|
14
|
+
set = 11,
|
|
15
|
+
union = 12,
|
|
16
|
+
optional = 13,
|
|
17
|
+
default = 14,
|
|
18
|
+
object = 15,
|
|
19
|
+
custom = 16
|
|
20
|
+
}
|
|
21
|
+
export interface VoidTag {
|
|
22
|
+
tag: Tag.void;
|
|
23
|
+
}
|
|
24
|
+
export interface StringTag {
|
|
25
|
+
tag: Tag.string;
|
|
26
|
+
}
|
|
27
|
+
export interface NumberTag {
|
|
28
|
+
tag: Tag.number;
|
|
29
|
+
}
|
|
30
|
+
export interface DateTag {
|
|
31
|
+
tag: Tag.date;
|
|
32
|
+
}
|
|
33
|
+
export interface BooleanTag {
|
|
34
|
+
tag: Tag.boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface SymbolTag {
|
|
37
|
+
tag: Tag.symbol;
|
|
38
|
+
}
|
|
39
|
+
export interface BigIntTag {
|
|
40
|
+
tag: Tag.bigint;
|
|
41
|
+
}
|
|
42
|
+
export interface UnknownTag {
|
|
43
|
+
tag: Tag.unknown;
|
|
44
|
+
}
|
|
45
|
+
export interface FileTag {
|
|
46
|
+
tag: Tag.file;
|
|
47
|
+
}
|
|
48
|
+
export interface LiteralTag<V = unknown> {
|
|
49
|
+
tag: Tag.literal;
|
|
50
|
+
value: V;
|
|
51
|
+
}
|
|
52
|
+
export interface ArrayTag<V extends TypeTag = TypeTag> {
|
|
53
|
+
tag: Tag.array;
|
|
54
|
+
of: V;
|
|
55
|
+
}
|
|
56
|
+
export interface SetTag<V extends TypeTag = TypeTag> {
|
|
57
|
+
tag: Tag.set;
|
|
58
|
+
of: V;
|
|
59
|
+
}
|
|
60
|
+
export interface OptionalTag<V extends TypeTag = TypeTag> {
|
|
61
|
+
tag: Tag.optional;
|
|
62
|
+
of: V;
|
|
63
|
+
}
|
|
64
|
+
export interface UnionTag<V extends TypeTag[] = TypeTag[]> {
|
|
65
|
+
tag: Tag.union;
|
|
66
|
+
options: V;
|
|
67
|
+
}
|
|
68
|
+
export interface ObjectTag<P extends Record<string, TypeTag> = Record<string, TypeTag>> {
|
|
69
|
+
tag: Tag.object;
|
|
70
|
+
props: P;
|
|
71
|
+
}
|
|
72
|
+
export interface DefaultTag<T extends TypeTag = TypeTag> {
|
|
73
|
+
tag: Tag.default;
|
|
74
|
+
of: T;
|
|
75
|
+
value: MaybeGenerator<unknown>;
|
|
76
|
+
}
|
|
77
|
+
export interface CustomTag<V = any, PR = any> {
|
|
78
|
+
tag: Tag.custom;
|
|
79
|
+
isType: (test: unknown) => boolean;
|
|
80
|
+
parse?: (test: unknown) => PR;
|
|
81
|
+
serialize?: (value: V) => Promisable<unknown>;
|
|
82
|
+
deserialize?: (value: unknown) => Promisable<V>;
|
|
83
|
+
}
|
|
84
|
+
export type TypeTag = VoidTag | LiteralTag | StringTag | NumberTag | DateTag | BooleanTag | SymbolTag | UnknownTag | FileTag | BigIntTag | SetTag | OptionalTag | UnionTag | ArrayTag | ObjectTag | CustomTag | DefaultTag;
|
|
85
|
+
type Dec = [0, 0, 1, 2, 3, 4, 5];
|
|
86
|
+
export type TagToType<T extends TypeTag, Depth extends number = 5> = Depth extends 0 ? any : T extends StringTag ? string : T extends NumberTag ? number : T extends BooleanTag ? boolean : T extends LiteralTag<infer V> ? V : T extends DateTag ? Date : T extends SymbolTag ? symbol : T extends UnknownTag ? unknown : T extends FileTag ? File : T extends BigIntTag ? bigint : T extends SetTag<infer T> ? Set<TagToType<T, Dec[Depth]>> : T extends UnionTag<infer TOpts> ? TagToType<TOpts[number], Dec[Depth]> : T extends ArrayTag<infer T> ? TagToType<T, Dec[Depth]>[] : T extends ObjectTag<infer P> ? {
|
|
87
|
+
[K in keyof P]: TagToType<P[K], Dec[Depth]>;
|
|
88
|
+
} : T extends DefaultTag<infer T> | OptionalTag<infer T> ? TagToType<T, Dec[Depth]> | undefined : T extends CustomTag<infer V> ? V : never;
|
|
89
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Literable } from '../util-types';
|
|
2
|
+
import { ArrayTag, BigIntTag, BooleanTag, CustomTag, DateTag, DefaultTag, FileTag, LiteralTag, NumberTag, ObjectTag, OptionalTag, SetTag, StringTag, SymbolTag, Tag, TagToType, TypeTag, UnionTag, UnknownTag, VoidTag } from './tag';
|
|
3
|
+
interface TypeCache {
|
|
4
|
+
[Tag.string]: StringTag;
|
|
5
|
+
[Tag.number]: NumberTag;
|
|
6
|
+
[Tag.boolean]: BooleanTag;
|
|
7
|
+
[Tag.bigint]: BigIntTag;
|
|
8
|
+
[Tag.symbol]: SymbolTag;
|
|
9
|
+
[Tag.void]: VoidTag;
|
|
10
|
+
[Tag.file]: FileTag;
|
|
11
|
+
[Tag.date]: DateTag;
|
|
12
|
+
[Tag.unknown]: UnknownTag;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Gets a type from the primitive type cache, creating it if it doesn't exist
|
|
16
|
+
* @param tag Primitive tag to acquire a type for
|
|
17
|
+
* @returns Proper typetag
|
|
18
|
+
*/
|
|
19
|
+
export declare function getType<K extends keyof TypeCache>(tag: K): TypeCache[K];
|
|
20
|
+
export declare function String(): StringTag;
|
|
21
|
+
export declare function Number(): NumberTag;
|
|
22
|
+
export declare function Boolean(): BooleanTag;
|
|
23
|
+
export declare function BigInt(): BigIntTag;
|
|
24
|
+
export declare function Symbol(): SymbolTag;
|
|
25
|
+
export declare function Void(): VoidTag;
|
|
26
|
+
export declare function File(): FileTag;
|
|
27
|
+
export declare function Date(): DateTag;
|
|
28
|
+
export declare function Unknown(): UnknownTag;
|
|
29
|
+
export declare function Literal<const V extends Literable>(value: V): LiteralTag<V>;
|
|
30
|
+
export declare function Array<V extends TypeTag>(element: V): ArrayTag<V>;
|
|
31
|
+
export declare function Default<V extends TypeTag>(of: V, value: TagToType<V>): DefaultTag<V>;
|
|
32
|
+
export declare function Set<V extends TypeTag>(element: V): SetTag<V>;
|
|
33
|
+
export declare function Union<const V extends TypeTag[]>(types: V): UnionTag<V>;
|
|
34
|
+
export declare function Optional<V extends TypeTag>(type: V): OptionalTag<V>;
|
|
35
|
+
export declare function Object<R extends Record<string, TypeTag>>(props: R): ObjectTag<R>;
|
|
36
|
+
export declare function Custom<V>(opts: Omit<CustomTag<V>, "tag">): CustomTag<V>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TagToType, TypeTag } from './tag';
|
|
2
|
+
import { ParseResult } from '../field';
|
|
3
|
+
export declare function typeToString(type: TypeTag): string;
|
|
4
|
+
/**
|
|
5
|
+
* Serialize's a type into JSON
|
|
6
|
+
* @param type Type
|
|
7
|
+
* @param value Value to serialize
|
|
8
|
+
*/
|
|
9
|
+
export declare function serializeType<T extends TypeTag>(type: T, value: TagToType<T>): Promise<unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Convert a value from it's JSON serialized version to it's Javascript representation
|
|
12
|
+
* @param type Type to parse the value as
|
|
13
|
+
* @param value JSON value to deserialize
|
|
14
|
+
* @returns Type denoted by the type parameter
|
|
15
|
+
*/
|
|
16
|
+
export declare function deserializeType<T extends TypeTag, R = TagToType<T>>(type: T, value: unknown): Promise<R>;
|
|
17
|
+
/**
|
|
18
|
+
* Checks to see if `test` is a valid subtype of `base`
|
|
19
|
+
* @param base Base type tag
|
|
20
|
+
* @param test Testing type tag
|
|
21
|
+
*/
|
|
22
|
+
export declare function isSubtype(base: TypeTag, test: TypeTag): boolean;
|
|
23
|
+
export declare function isType<T extends TypeTag>(type: T, value: unknown): value is TagToType<T>;
|
|
24
|
+
export declare function parseType<T extends TypeTag>(type: T, value: unknown): ParseResult<TagToType<T>>;
|
package/dist/util-types.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export type RemoveNeverValues<T extends object> = {
|
|
|
24
24
|
* A type representing a dictionary from string to some type
|
|
25
25
|
*/
|
|
26
26
|
export type Dict<T = unknown> = Record<string, T>;
|
|
27
|
+
export type PartialRecord<K extends symbol | number | string, V> = {
|
|
28
|
+
[Q in K]?: V;
|
|
29
|
+
};
|
|
30
|
+
export type MaybeGenerator<T> = T | (() => T);
|
|
27
31
|
type UndefinedKeys<T extends Dict> = {
|
|
28
32
|
[K in Keyof<T>]: undefined extends T[K] ? K : never;
|
|
29
33
|
}[Keyof<T>];
|
package/dist/utils.d.ts
CHANGED
|
@@ -16,3 +16,8 @@ export declare function identity<T>(value: T): T;
|
|
|
16
16
|
* Performs a union over `set1` and `set2`, modifying `set1` to be union of the two sets
|
|
17
17
|
*/
|
|
18
18
|
export declare function unionSets<T>(set: Set<T>, other: Set<T>): Set<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Attempts to coerce a string into a number, if the number is NaN, returns the string instead
|
|
21
|
+
* @param str String to coerce
|
|
22
|
+
*/
|
|
23
|
+
export declare function tryNumberCoerce(str: string): string | number;
|
package/package.json
CHANGED
package/dist/dump/class.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Arrayable, Dict } from '../util-types';
|
|
2
|
-
declare abstract class Dump<T> {
|
|
3
|
-
protected readonly name: string;
|
|
4
|
-
protected readonly content: T;
|
|
5
|
-
protected readonly extension: string;
|
|
6
|
-
constructor(name: string, content: T, extension: string);
|
|
7
|
-
abstract getValue(): T;
|
|
8
|
-
abstract toFile(filename?: string, options?: FilePropertyBag): File;
|
|
9
|
-
download(filename?: string, options?: FilePropertyBag): void;
|
|
10
|
-
}
|
|
11
|
-
type JsonValue = Arrayable<Dict>;
|
|
12
|
-
export declare class JsonDump extends Dump<JsonValue> {
|
|
13
|
-
constructor(name: string, content: JsonValue);
|
|
14
|
-
getValue(): JsonValue;
|
|
15
|
-
toFile(filename?: string, options?: FilePropertyBag): File;
|
|
16
|
-
}
|
|
17
|
-
export declare class CsvDump extends Dump<string> {
|
|
18
|
-
constructor(name: string, content: string);
|
|
19
|
-
getValue(): string;
|
|
20
|
-
toFile(filename?: string, options?: FilePropertyBag): File;
|
|
21
|
-
}
|
|
22
|
-
export {};
|
package/dist/dump/json.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { WhereObject } from '../client/types/find.js';
|
|
2
|
-
import { Dict } from '../util-types';
|
|
3
|
-
import { DbClient } from '../client';
|
|
4
|
-
import { ValidValue } from '../field';
|
|
5
|
-
import { CollectionObject } from '../model';
|
|
6
|
-
import { Transaction } from '../transaction.js';
|
|
7
|
-
import { JsonDump } from './class.js';
|
|
8
|
-
export declare function dumpStoreToJson<Current extends Names, Names extends string, Models extends CollectionObject<Names>>(db: DbClient<string, Names, CollectionObject<Names>>, store: Current, where?: WhereObject<Models[Current] extends Dict<ValidValue> ? Models[Current] : never>, tx?: Transaction<"readonly", Names>): Promise<JsonDump>;
|
|
9
|
-
export declare function dumpDatabaseToJSON<Names extends string>(db: DbClient<string, Names, any>, stores?: Names[]): Promise<JsonDump>;
|