tinybase 5.0.0-beta.20 → 5.0.0-beta.21
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/@types/ui-react-inspector/index.d.cts +7 -8
- package/@types/ui-react-inspector/index.d.ts +7 -8
- package/@types/ui-react-inspector/with-schemas/index.d.cts +7 -8
- package/@types/ui-react-inspector/with-schemas/index.d.ts +7 -8
- package/cli/index.js +1 -1
- package/package.json +1 -1
- package/readme.md +3 -3
- package/releases.md +4 -4
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ui-react-
|
|
3
|
-
*
|
|
2
|
+
* The ui-react-inspector module of the TinyBase project provides a component to
|
|
3
|
+
* help debug the state of your TinyBase stores and other objects.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
* appropriate for environments like React Native
|
|
7
|
-
*
|
|
8
|
-
* @see UI Components demos
|
|
5
|
+
* The component in this module uses the react-dom module and so is not
|
|
6
|
+
* appropriate for environments like React Native.
|
|
7
|
+
* @see <Inspector /> demo
|
|
9
8
|
* @packageDocumentation
|
|
10
|
-
* @module ui-react-
|
|
11
|
-
* @since
|
|
9
|
+
* @module ui-react-inspector
|
|
10
|
+
* @since v5.0.0
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
import type {ComponentReturnType} from '../ui-react/index.d.cts';
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ui-react-
|
|
3
|
-
*
|
|
2
|
+
* The ui-react-inspector module of the TinyBase project provides a component to
|
|
3
|
+
* help debug the state of your TinyBase stores and other objects.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
* appropriate for environments like React Native
|
|
7
|
-
*
|
|
8
|
-
* @see UI Components demos
|
|
5
|
+
* The component in this module uses the react-dom module and so is not
|
|
6
|
+
* appropriate for environments like React Native.
|
|
7
|
+
* @see <Inspector /> demo
|
|
9
8
|
* @packageDocumentation
|
|
10
|
-
* @module ui-react-
|
|
11
|
-
* @since
|
|
9
|
+
* @module ui-react-inspector
|
|
10
|
+
* @since v5.0.0
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
import type {ComponentReturnType} from '../ui-react/index.d.ts';
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ui-react-
|
|
3
|
-
*
|
|
2
|
+
* The ui-react-inspector module of the TinyBase project provides a component to
|
|
3
|
+
* help debug the state of your TinyBase stores and other objects.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
* appropriate for environments like React Native
|
|
7
|
-
*
|
|
8
|
-
* @see UI Components demos
|
|
5
|
+
* The component in this module uses the react-dom module and so is not
|
|
6
|
+
* appropriate for environments like React Native.
|
|
7
|
+
* @see <Inspector /> demo
|
|
9
8
|
* @packageDocumentation
|
|
10
|
-
* @module ui-react-
|
|
11
|
-
* @since
|
|
9
|
+
* @module ui-react-inspector
|
|
10
|
+
* @since v5.0.0
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
import type {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ui-react-
|
|
3
|
-
*
|
|
2
|
+
* The ui-react-inspector module of the TinyBase project provides a component to
|
|
3
|
+
* help debug the state of your TinyBase stores and other objects.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
* appropriate for environments like React Native
|
|
7
|
-
*
|
|
8
|
-
* @see UI Components demos
|
|
5
|
+
* The component in this module uses the react-dom module and so is not
|
|
6
|
+
* appropriate for environments like React Native.
|
|
7
|
+
* @see <Inspector /> demo
|
|
9
8
|
* @packageDocumentation
|
|
10
|
-
* @module ui-react-
|
|
11
|
-
* @since
|
|
9
|
+
* @module ui-react-inspector
|
|
10
|
+
* @since v5.0.0
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
import type {
|
package/cli/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import{resolve as e,dirname as t}from"path";import{readFileSync as l,writeFileSync as a}from"fs";import{fileURLToPath as n}from"url";const o=e=>typeof e,s="tinybase",d="",r=o(d),I=o(!0),c=o(0),i=o(o),u="type",$="default",b="utf8",p="Listener",C="add",h="Has",m="Ids",g="Table",f=g+"s",w=g+m,T="Row",y=T+"Count",v=T+m,V="Sorted"+T+m,R="Cell",x=R+m,S="Value",A=S+"s",k=S+m,P=e=>d+e,E=Promise,L=isFinite,O=e=>null==e,D=(e,t,l)=>O(e)?l?.():t(e),N=e=>e==r||e==I,J=e=>o(e)==r,j=e=>o(e)==i,G=e=>Array.isArray(e),M=(e,t,l)=>e.slice(t,l),z=e=>e.length,H=(e,t)=>e.every(t),F=(e,t)=>e.sort(t),W=(e,t)=>e.forEach(t),U=(e,t="")=>e.join(t),B=(e,t)=>e.map(t),_=(e,...t)=>e.push(...t),Z=(e,...t)=>e.unshift(...t),Q=e=>e.shift(),q=Object,K=e=>q.getPrototypeOf(e),X=q.entries,Y=q.isFrozen,ee=e=>!O(e)&&D(K(e),(e=>e==q.prototype||O(K(e))),(()=>!0)),te=q.keys,le=q.freeze,ae=(e,t)=>t in e,ne=(e,t)=>(delete e[t],e),oe=(e,t)=>B(X(e),(([e,l])=>t(l,e))),se=e=>ee(e)&&0==(e=>z(te(e)))(e),de=(e,t,l,a=0)=>O(e)||!ee(e)||!a&&se(e)||Y(e)?(l?.(),!1):(oe(e,((l,a)=>{t(l,a)||ne(e,a)})),!!a||!se(e)),re=e=>e?.size??0,Ie=(e,t)=>e?.has(t)??!1,ce=e=>O(e)||0==re(e),ie=e=>[...e?.values()??[]],ue=e=>e.clear(),$e=(e,t)=>e?.forEach(t),be=(e,t)=>e?.delete(t),pe=e=>new Map(e),Ce=e=>[...e?.keys()??[]],he=(e,t)=>e?.get(t),me=(e,t)=>$e(e,((e,l)=>t(l,e))),ge=(e,t)=>B([...e?.entries()??[]],(([e,l])=>t(l,e))),fe=(e,t,l)=>O(l)?(be(e,t),e):e?.set(t,l),we=(e,t,l,a)=>(Ie(e,t)?a?.(he(e,t)):fe(e,t,l()),he(e,t)),Te=(e,t,l,a=fe)=>(oe(t,((t,a)=>l(e,a,t))),me(e,(l=>ae(t,l)?0:a(e,l))),e),ye=(e,t,l,a)=>{const n={};return $e(e,((e,o)=>{if(!l?.(e,o)){const l=t?t(e,o):e;!a?.(l)&&(n[o]=l)}})),n},ve=(e,t,l)=>ye(e,(e=>ye(e,t,l)),ce,se),Ve=(e,t,l)=>ye(e,(e=>ve(e,t,l)),ce,se),Re=(e,t)=>{const l=pe();return $e(e,((e,a)=>l.set(a,t?.(e)??e))),l},xe=e=>Re(e,Re),Se=e=>Re(e,xe),Ae=(e,t,l,a,n=0)=>D((l?we:he)(e,t[n],n>z(t)-2?l:pe),(o=>{if(n>z(t)-2)return a?.(o)&&fe(e,t[n]),o;const s=Ae(o,t,l,a,n+1);return ce(o)&&fe(e,t[n]),s})),ke=e=>new Set(G(e)||O(e)?e:[e]),Pe=(e,t)=>e?.add(t),Ee=/^\d+$/,Le=()=>{const e=[];let t=0;return[l=>(l?Q(e):null)??d+t++,t=>{Ee.test(t)&&z(e)<1e3&&_(e,t)}]},Oe=e=>[e,e],De=()=>[pe(),pe()],Ne=e=>[...e],Je=([e,t])=>e===t,je=e=>{const t=o(e);return N(t)||t==c&&L(e)?t:void 0},Ge=(e,t,l,a,n)=>O(n)?e.delCell(t,l,a,!0):e.setCell(t,l,a,n),Me=(e,t,l)=>O(l)?e.delValue(t):e.setValue(t,l),ze=e=>JSON.stringify(e,((e,t)=>t instanceof Map?q.fromEntries([...t]):t)),He=JSON.parse;pe(B("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".split(d),((e,t)=>[e,t])));const Fe=(e,t,l)=>fe(e,t,he(e,t)==-l?void 0:l),We=()=>{let e,t,l=!1,a=!1,n=0,o=[];const s=pe(),r=pe(),I=pe(),i=pe(),b=pe(),m=pe(),V=pe(),E=pe(),L=pe(),J=pe(),G=pe(),U=pe(),Z=pe(),Q=pe(),q=ke(),K=pe(),X=pe(),Y=pe(),ee=pe(),te=De(),ie=De(),Ee=De(),Ue=De(),Be=De(),_e=De(),Ze=De(),Qe=De(),qe=De(),Ke=De(),Xe=De(),Ye=De(),et=De(),tt=De(),lt=De(),at=De(),nt=De(),ot=De(),st=De(),dt=De(),rt=De(),It=De(),ct=pe(),it=De(),[ut,$t,bt,pt]=(e=>{let t;const[l,a]=Le(),n=pe();return[(e,a,o,s=[],r=(()=>[]))=>{t??=Dl;const I=l(1);return fe(n,I,[e,a,o,s,r]),Pe(Ae(a,o??[d],ke),I),I},(e,l,...a)=>W(((e,t=[d])=>{const l=[],a=(e,n)=>n==z(t)?_(l,e):null===t[n]?$e(e,(e=>a(e,n+1))):W([t[n],null],(t=>a(he(e,t),n+1)));return a(e,0),l})(e,l),(e=>$e(e,(e=>he(n,e)[0](t,...l??[],...a))))),e=>D(he(n,e),(([,t,l])=>(Ae(t,l??[d],void 0,(t=>(be(t,e),ce(t)?1:0))),fe(n,e),a(e),l))),e=>D(he(n,e),(([e,,l=[],a,n])=>{const o=(...s)=>{const d=z(s);d==z(l)?e(t,...s,...n(s)):O(l[d])?W(a[d]?.(...s)??[],(e=>o(...s,e))):o(...s,l[d])};o()}))]})(),Ct=e=>{if(!de(e,((e,t)=>[u,$].includes(t))))return!1;const t=e[u];return!(!N(t)&&t!=c||(je(e[$])!=t&&ne(e,$),0))},ht=(t,l)=>(!e||Ie(G,l)||_t(l))&&de(t,((e,t)=>mt(l,t,e)),(()=>_t(l))),mt=(e,t,l,a)=>de(a?l:Tt(l,e,t),((a,n)=>D(gt(e,t,n,a),(e=>(l[n]=e,!0)),(()=>!1))),(()=>_t(e,t))),gt=(t,l,a,n)=>e?D(he(he(G,t),a),(e=>je(n)!=e[u]?_t(t,l,a,n,e[$]):n),(()=>_t(t,l,a,n))):O(je(n))?_t(t,l,a,n):n,ft=(e,t)=>de(t?e:yt(e),((t,l)=>D(wt(l,t),(t=>(e[l]=t,!0)),(()=>!1))),(()=>Zt())),wt=(e,l)=>t?D(he(Z,e),(t=>je(l)!=t[u]?Zt(e,l,t[$]):l),(()=>Zt(e,l))):O(je(l))?Zt(e,l):l,Tt=(e,t,l)=>(D(he(U,t),(([a,n])=>{$e(a,((t,l)=>{ae(e,l)||(e[l]=t)})),$e(n,(a=>{ae(e,a)||_t(t,l,a)}))})),e),yt=e=>(t&&($e(Q,((t,l)=>{ae(e,l)||(e[l]=t)})),$e(q,(t=>{ae(e,t)||Zt(t)}))),e),vt=e=>Te(G,e,((e,t,l)=>{const a=pe(),n=ke();Te(we(G,t,pe),l,((e,t,l)=>{fe(e,t,l),D(l[$],(e=>fe(a,t,e)),(()=>Pe(n,t)))})),fe(U,t,[a,n])}),((e,t)=>{fe(G,t),fe(U,t)})),Vt=e=>Te(Z,e,((e,t,l)=>{fe(Z,t,l),D(l[$],(e=>fe(Q,t,e)),(()=>Pe(q,t)))}),((e,t)=>{fe(Z,t),fe(Q,t),be(q,t)})),Rt=e=>se(e)?Rl():wl(e),xt=e=>Te(Y,e,((e,t,l)=>St(t,l)),((e,t)=>Jt(t))),St=(e,t)=>Te(we(Y,e,(()=>(zt(e,1),fe(K,e,Le()),fe(X,e,pe()),pe()))),t,((t,l,a)=>At(e,t,l,a)),((t,l)=>jt(e,t,l))),At=(e,t,l,a,n)=>Te(we(t,l,(()=>(Ht(e,l,1),pe()))),a,((t,a,n)=>kt(e,l,t,a,n)),((a,o)=>Gt(e,t,l,a,o,n))),kt=(e,t,l,a,n)=>{Ie(l,a)||Ft(e,t,a,1);const o=he(l,a);n!==o&&(Wt(e,t,a,o,n),fe(l,a,n))},Pt=(e,t,l,a,n)=>D(he(t,l),(t=>kt(e,l,t,a,n)),(()=>At(e,t,l,Tt({[a]:n},e,l)))),Et=e=>se(e)?Al():Tl(e),Lt=e=>Te(ee,e,((e,t,l)=>Ot(t,l)),((e,t)=>Mt(t))),Ot=(e,t)=>{Ie(ee,e)||Ut(e,1);const l=he(ee,e);t!==l&&(Bt(e,l,t),fe(ee,e,t))},Dt=(e,t)=>{const[l]=he(K,e),a=l(t);return Ie(he(Y,e),a)?Dt(e,t):a},Nt=e=>he(Y,e)??St(e,{}),Jt=e=>St(e,{}),jt=(e,t,l)=>{const[,a]=he(K,e);a(l),At(e,t,l,{},!0)},Gt=(e,t,l,a,n,o)=>{const s=he(he(U,e)?.[0],n);if(!O(s)&&!o)return kt(e,l,a,n,s);const d=t=>{Wt(e,l,t,he(a,t)),Ft(e,l,t,-1),fe(a,t)};O(s)?d(n):me(a,d),ce(a)&&(Ht(e,l,-1),ce(fe(t,l))&&(zt(e,-1),fe(Y,e),fe(K,e),fe(X,e)))},Mt=e=>{const t=he(Q,e);if(!O(t))return Ot(e,t);Bt(e,he(ee,e)),Ut(e,-1),fe(ee,e)},zt=(e,t)=>Fe(s,e,t),Ht=(e,t,l)=>Fe(we(i,e,pe),t,l)&&fe(I,e,we(I,e,(()=>0))+l),Ft=(e,t,l,a)=>{const n=he(X,e),o=he(n,l)??0;(0==o&&1==a||1==o&&-1==a)&&Fe(we(r,e,pe),l,a),fe(n,l,o!=-a?o+a:null),Fe(we(we(b,e,pe),t,pe),l,a)},Wt=(e,t,l,a,n)=>{we(we(we(m,e,pe),t,pe),l,(()=>[a,0]))[1]=n,o[3]?.(e,t,l,n)},Ut=(e,t)=>Fe(V,e,t),Bt=(e,t,l)=>{we(E,e,(()=>[t,0]))[1]=l,o[4]?.(e,l)},_t=(e,t,l,a,n)=>(_(we(we(we(L,e,pe),t,pe),l,(()=>[])),a),n),Zt=(e,t,l)=>(_(we(J,e,(()=>[])),t),l),Qt=(e,t,l)=>D(he(he(he(m,e),t),l),(([e,t])=>[!0,e,t]),(()=>[!1,...Oe(cl(e,t,l))])),qt=e=>D(he(E,e),(([e,t])=>[!0,e,t]),(()=>[!1,...Oe($l(e))])),Kt=e=>ce(L)||ce(at[e])?0:$e(e?Se(L):L,((t,l)=>$e(t,((t,a)=>$e(t,((t,n)=>$t(at[e],[l,a,n],t))))))),Xt=e=>ce(J)||ce(nt[e])?0:$e(e?Re(J):J,((t,l)=>$t(nt[e],[l],t))),Yt=(e,t,l,a)=>{if(!ce(e))return $t(t,a,(()=>ye(e))),me(e,((e,t)=>$t(l,[...a??[],e],1==t))),1},el=e=>{const t=bl();t!=l&&$t(te[e],void 0,t);const a=ce(Ke[e]),n=ce(et[e])&&ce(tt[e])&&ce(qe[e])&&ce(Xe[e])&&ce(_e[e])&&ce(Ze[e])&&ce(Qe[e])&&a&&ce(Ee[e])&&ce(Ue[e]),o=ce(lt[e])&&ce(Ye[e])&&ce(Be[e])&&ce(ie[e]);if(!n||!o){const t=e?[Re(s),xe(r),Re(I),xe(i),Se(b),Se(m)]:[s,r,I,i,b,m];if(!n){Yt(t[0],Ee[e],Ue[e]),$e(t[1],((t,l)=>Yt(t,_e[e],Ze[e],[l]))),$e(t[2],((t,l)=>{0!=t&&$t(Qe[e],[l],sl(l))}));const l=ke();$e(t[3],((t,n)=>{Yt(t,qe[e],Xe[e],[n])&&!a&&($t(Ke[e],[n,null]),Pe(l,n))})),a||$e(t[5],((t,a)=>{if(!Ie(l,a)){const l=ke();$e(t,(e=>$e(e,(([t,a],n)=>a!==t?Pe(l,n):be(e,n))))),$e(l,(t=>$t(Ke[e],[a,t])))}})),$e(t[4],((t,l)=>$e(t,((t,a)=>Yt(t,et[e],tt[e],[l,a])))))}if(!o){let l;$e(t[5],((t,a)=>{let n;$e(t,((t,o)=>{let s;$e(t,(([t,d],r)=>{d!==t&&($t(lt[e],[a,o,r],d,t,Qt),l=n=s=1)})),s&&$t(Ye[e],[a,o],Qt)})),n&&$t(Be[e],[a],Qt)})),l&&$t(ie[e],void 0,Qt)}}},tl=e=>{const t=gl();t!=a&&$t(ot[e],void 0,t);const l=ce(dt[e])&&ce(rt[e]),n=ce(It[e])&&ce(st[e]);if(!l||!n){const t=e?[Re(V),Re(E)]:[V,E];if(l||Yt(t[0],dt[e],rt[e]),!n){let l;$e(t[1],(([t,a],n)=>{a!==t&&($t(It[e],[n],a,t,qt),l=1)})),l&&$t(st[e],void 0,qt)}}},ll=(e,...t)=>(El((()=>e(...B(t,P)))),Dl),al=()=>Ve(Y),nl=()=>Ce(Y),ol=e=>Ce(he(X,P(e))),sl=e=>re(he(Y,P(e))),dl=e=>Ce(he(Y,P(e))),rl=(e,t,l,a=0,n)=>B(M(F(ge(he(Y,P(e)),((e,l)=>[O(t)?l:he(e,P(t)),l])),(([e],[t])=>((e??0)<(t??0)?-1:1)*(l?-1:1))),a,O(n)?n:a+n),(([,e])=>e)),Il=(e,t)=>Ce(he(he(Y,P(e)),P(t))),cl=(e,t,l)=>he(he(he(Y,P(e)),P(t)),P(l)),il=()=>ye(ee),ul=()=>Ce(ee),$l=e=>he(ee,P(e)),bl=()=>!ce(Y),pl=e=>Ie(Y,P(e)),Cl=(e,t)=>Ie(he(X,P(e)),P(t)),hl=(e,t)=>Ie(he(Y,P(e)),P(t)),ml=(e,t,l)=>Ie(he(he(Y,P(e)),P(t)),P(l)),gl=()=>!ce(ee),fl=e=>Ie(ee,P(e)),wl=e=>ll((()=>(e=>de(e,ht,_t))(e)?xt(e):0)),Tl=e=>ll((()=>ft(e)?Lt(e):0)),yl=e=>{try{Rt(He(e))}catch{}return Dl},vl=t=>ll((()=>{if((e=de(t,(e=>de(e,Ct))))&&(vt(t),!ce(Y))){const e=al();Rl(),wl(e)}})),Vl=e=>ll((()=>{if(t=(e=>de(e,Ct))(e)){const l=il();Pl(),Al(),t=!0,Vt(e),Tl(l)}})),Rl=()=>ll((()=>xt({}))),xl=e=>ll((e=>Ie(Y,e)?Jt(e):0),e),Sl=(e,t)=>ll(((e,t)=>D(he(Y,e),(l=>Ie(l,t)?jt(e,l,t):0))),e,t),Al=()=>ll((()=>Lt({}))),kl=()=>ll((()=>{vt({}),e=!1})),Pl=()=>ll((()=>{Vt({}),t=!1})),El=(e,t)=>{if(-1!=n){Ll();const l=e();return Ol(t),l}},Ll=()=>(-1!=n&&n++,1==n&&(o[0]?.(),$t(ct)),Dl),Ol=e=>(n>0&&(n--,0==n&&(n=1,Kt(1),ce(m)||el(1),Xt(1),ce(E)||tl(1),e?.(Dl)&&($e(m,((e,t)=>$e(e,((e,l)=>$e(e,(([e],a)=>Ge(Dl,t,l,a,e))))))),ue(m),$e(E,(([e],t)=>Me(Dl,t,e))),ue(E)),$t(it[0],void 0),n=-1,Kt(0),ce(m)||el(0),Xt(0),ce(E)||tl(0),o[1]?.(),$t(it[1],void 0),o[2]?.(),n=0,l=bl(),a=gl(),W([s,r,I,i,b,m,L,V,E,J],ue))),Dl),Dl={getContent:()=>[al(),il()],getTables:al,getTableIds:nl,getTable:e=>ve(he(Y,P(e))),getTableCellIds:ol,getRowCount:sl,getRowIds:dl,getSortedRowIds:rl,getRow:(e,t)=>ye(he(he(Y,P(e)),P(t))),getCellIds:Il,getCell:cl,getValues:il,getValueIds:ul,getValue:$l,hasTables:bl,hasTable:pl,hasTableCell:Cl,hasRow:hl,hasCell:ml,hasValues:gl,hasValue:fl,getTablesJson:()=>ze(Y),getValuesJson:()=>ze(ee),getJson:()=>ze([Y,ee]),getTablesSchemaJson:()=>ze(G),getValuesSchemaJson:()=>ze(Z),getSchemaJson:()=>ze([G,Z]),hasTablesSchema:()=>e,hasValuesSchema:()=>t,setContent:([e,t])=>ll((()=>{(se(e)?Rl:wl)(e),(se(t)?Al:Tl)(t)})),setTables:wl,setTable:(e,t)=>ll((e=>ht(t,e)?St(e,t):0),e),setRow:(e,t,l)=>ll(((e,t)=>mt(e,t,l)?At(e,Nt(e),t,l):0),e,t),addRow:(e,t,l=!0)=>El((()=>{let a;return mt(e,a,t)&&(e=P(e),At(e,Nt(e),a=Dt(e,l?1:0),t)),a})),setPartialRow:(e,t,l)=>ll(((e,t)=>{if(mt(e,t,l,1)){const a=Nt(e);oe(l,((l,n)=>Pt(e,a,t,n,l)))}}),e,t),setCell:(e,t,l,a)=>ll(((e,t,l)=>D(gt(e,t,l,j(a)?a(cl(e,t,l)):a),(a=>Pt(e,Nt(e),t,l,a)))),e,t,l),setValues:Tl,setPartialValues:e=>ll((()=>ft(e,1)?oe(e,((e,t)=>Ot(t,e))):0)),setValue:(e,t)=>ll((e=>D(wt(e,j(t)?t($l(e)):t),(t=>Ot(e,t)))),e),applyChanges:e=>ll((()=>{oe(e[0],((e,t)=>O(e)?xl(t):oe(e,((e,l)=>O(e)?Sl(t,l):oe(e,((e,a)=>Ge(Dl,t,l,a,e))))))),oe(e[1],((e,t)=>Me(Dl,t,e)))})),setTablesJson:yl,setValuesJson:e=>{try{Et(He(e))}catch{}return Dl},setJson:e=>ll((()=>{try{const[t,l]=He(e);Rt(t),Et(l)}catch{yl(e)}})),setTablesSchema:vl,setValuesSchema:Vl,setSchema:(e,t)=>ll((()=>{vl(e),Vl(t)})),delTables:Rl,delTable:xl,delRow:Sl,delCell:(e,t,l,a)=>ll(((e,t,l)=>D(he(Y,e),(n=>D(he(n,t),(o=>Ie(o,l)?Gt(e,n,t,o,l,a):0))))),e,t,l),delValues:Al,delValue:e=>ll((e=>Ie(ee,e)?Mt(e):0),e),delTablesSchema:kl,delValuesSchema:Pl,delSchema:()=>ll((()=>{kl(),Pl()})),transaction:El,startTransaction:Ll,getTransactionChanges:()=>[ye(m,((e,t)=>-1===he(s,t)?void 0:ye(e,((e,l)=>-1===he(he(i,t),l)?void 0:ye(e,(([,e])=>e),(e=>Je(e)))),ce,se)),ce,se),ye(E,(([,e])=>e),(e=>Je(e))),1],getTransactionLog:()=>[!ce(m),!ce(E),Ve(m,Ne,Je),Ve(L),ye(E,Ne,Je),ye(J),ye(s),ve(i),Ve(b),ye(V)],finishTransaction:Ol,forEachTable:e=>$e(Y,((t,l)=>e(l,(e=>$e(t,((t,l)=>e(l,(e=>me(t,e))))))))),forEachTableCell:(e,t)=>me(he(X,P(e)),t),forEachRow:(e,t)=>$e(he(Y,P(e)),((e,l)=>t(l,(t=>me(e,t))))),forEachCell:(e,t,l)=>me(he(he(Y,P(e)),P(t)),l),forEachValue:e=>me(ee,e),addSortedRowIdsListener:(e,t,l,a,n,o,s)=>{let d=rl(e,t,l,a,n);return ut((()=>{const s=rl(e,t,l,a,n);var r,I;I=d,z(r=s)===z(I)&&H(r,((e,t)=>I[t]===e))||(d=s,o(Dl,e,t,l,a,n,d))}),Ke[s?1:0],[e,t],[nl])},addStartTransactionListener:e=>ut(e,ct),addWillFinishTransactionListener:e=>ut(e,it[0]),addDidFinishTransactionListener:e=>ut(e,it[1]),callListener:e=>(pt(e),Dl),delListener:e=>(bt(e),Dl),getListenerStats:()=>({}),isMergeable:()=>!1,createStore:We,addListener:ut,callListeners:$t,setInternalListeners:(e,t,l,a,n)=>o=[e,t,l,a,n]};return oe({[h+f]:[0,te,[],()=>[bl()]],[f]:[0,ie],[w]:[0,Ee],[h+g]:[1,Ue,[nl],e=>[pl(...e)]],[g]:[1,Be,[nl]],[g+x]:[1,_e,[nl]],[h+g+R]:[2,Ze,[nl,ol],e=>[Cl(...e)]],[y]:[1,Qe,[nl]],[v]:[1,qe,[nl]],[h+T]:[2,Xe,[nl,dl],e=>[hl(...e)]],[T]:[2,Ye,[nl,dl]],[x]:[2,et,[nl,dl]],[h+R]:[3,tt,[nl,dl,Il],e=>[ml(...e)]],[R]:[3,lt,[nl,dl,Il],e=>Oe(cl(...e))],InvalidCell:[3,at],[h+A]:[0,ot,[],()=>[gl()]],[A]:[0,st],[k]:[0,dt],[h+S]:[1,rt,[ul],e=>[fl(...e)]],[S]:[1,It,[ul],e=>Oe($l(e[0]))],InvalidValue:[1,nt]},(([e,t,l,a],n)=>{Dl[C+n+p]=(...n)=>ut(n[e],t[n[e+1]?1:0],e>0?M(n,0,e):void 0,l,a)})),le(Dl)},Ue=e=>e.toUpperCase(),Be=e=>e.toLowerCase(),_e="a ",Ze="A function for",Qe=", and registers a listener so that any changes to that result will cause a re-render",qe="Callback",Ke="Changes",Xe="Count",Ye="Del",et="Deps",tt=et+"?: React.DependencyList",lt="doRollback?: DoRollback",at="actions: () => Return, "+lt,nt="export",ot="Id",st="Invalid",dt="Json",rt=Be(p),It="?: ",ct=" | undefined",it="NonNullable",ut="Partial",$t="Props",bt="Provider",pt=`Registers a ${rt} that will be called`,Ct="Represents",ht="rowId: Id",mt="Schema",gt="Set",ft="[]",wt="the Store",Tt="Transaction",yt=Be(Tt),vt="Execute a "+yt+" to make multiple mutations",Vt="Explicitly starts a "+yt,Rt="Explicitly finishes a "+yt,xt="the end of the "+yt,St="void",At=" => "+St,kt="WhenSet",Pt=" when setting it",Et="a string serialization of",Lt=" ",Ot="Gets a callback that can ",Dt="the ",Nt=" the schema for",Jt=(e=0)=>e?"the existence of ":"",jt=(e=0,t=0,l=0)=>Jt(l)+`the ${ll[e]}content of`+(t?Lt+wt:d),Gt=(e=0,t,l=0,a=0)=>Yt[t]+Lt+Jt(a)+jt(e,1)+(l?" when setting it":d),Mt=(e,t=0)=>Ct+` a Row when ${t?"s":"g"}etting ${jt()} the '${e}' `+g,zt=(e,t,l=0)=>`Gets ${l?"sorted, paginated":"the"} Ids of the ${e}s in `+t,Ht=(e,t)=>`Calls a function for each ${e} in `+t,Ft=e=>"The props passed to a component that renders "+e,Wt=e=>"A function that takes "+e,Ut=(e,t=0,l=0)=>Ze+" listening to changes to "+Jt(l)+tl[e]+" in "+tl[t],Bt=(e,t,l=0,a=0)=>pt+" whenever "+Jt(a)+tl[e]+" in "+tl[t]+" change"+(l?d:"s"),_t=e=>`the '${e}' `+g,Zt=e=>"the specified Row in "+_t(e),Qt=(e,t=0,l=0)=>Yt[t]+Lt+jt(0,0,l)+Lt+_t(e),qt=(e,t=0,l=0)=>Yt[t]+` ${jt(0,0,l)} `+Zt(e),Kt=(e,t,l=0,a=0)=>Yt[l]+Lt+Jt(a)+`the '${t}' Cell for `+Zt(e),Xt=(e,t=0,l=0)=>Yt[t]+Lt+Jt(l)+`the '${e}' Value`,Yt=["Gets","Checks existence of","Sets","Deletes","Sets part of",Ct,"Gets "+Et,"Sets "+Et,pt+" whenever",Ot+"set",Ot+"add",Ot+"set part of",Ot+"delete","Renders","Gets "+Et+Nt,"Sets"+Nt,"Deletes"+Nt],el=["get","has","set","del","set","forEach",C,d],tl=[wt,f,Dt+g+Lt+m,_e+g,Dt+T+Lt+m,_e+T,Dt+R+Lt+m,_e+R,"invalid Cell changes",A,Dt+S+Lt+m,_e+S,"invalid Value changes",Dt+"sorted "+T+Lt+m,Dt+R+Lt+m+" anywhere",Dt+"number of Rows",_e+R+" anywhere"],ll=[d,"tabular ","keyed value "],al=/[^A-Za-z]+/,nl=/[^A-Za-z0-9]+/,ol=/^( *)\/\*\* *(.*?) *\*\/$/gm,sl=e=>e.includes(","),dl=(e,t,l,a=1)=>{const n=`${t}${1==a?"":a}`;return Ie(e,n)?dl(e,t,l,a+1):(fe(e,n,l),n)},rl=e=>e.flat(1e3),Il=(e,t=0)=>U(B(e.split(nl),((e,l)=>(l>0||t?Ue:Be)(M(e,0,1))+M(e,1)))),cl=e=>Ue(U((e&&!al.test(e[0])?e:" "+e).split(nl),"_")),il=e=>`/** ${e}. */`,ul=(...e)=>{return U((t=e=>e,e.filter(t)),", ");var t},$l=(...e)=>"{"+U(e,"; ")+"}",bl=(...e)=>$l(...B(e,(e=>"readonly "+e))),pl=()=>{const e=[pe(),pe(),pe(),pe()],t=pe(),l=pe(),a=e=>{const t=e.indexOf(" as ");return-1!=t?M(e,t+4):e};return[(...e)=>U(rl(e),"\n"),(t,l,...a)=>W(a,(a=>W([0,1],(n=>(t??n)==n?Pe(we(e[n],l,ke),a):0)))),(e,l,a,n="",o=1)=>dl(t,e,[l,a,n,o]),(e,t,a)=>dl(l,e,G(a)?[`(${t}) => {`,a,"}"]:[`(${t}) => ${a}`]),(e,t)=>he(l,e)===t?e:dl(l,e,t),(t=0)=>B([...F(ge(e[t],((e,t)=>`import {${U(F(ie(e),((e,t)=>a(e)>a(t)?1:-1)),", ")}} from '${t}';`)),((e,t)=>sl(e)!=sl(t)?sl(e)?-1:1:e>t?1:-1)),d],(e=>e.replace("{React}","React"))),()=>ge(t,(([e,t,l,a],n)=>[il(t),`${a?nt+" ":d}type ${n}${l} = ${e};`,d])),()=>ge(l,((e,t)=>(e=G(e)?e:[e],_(e,e.pop()+";"),[`const ${t} = ${Q(e)}`,e,d])))]},Cl=(e,t,l)=>[t=>oe(e,((e,a)=>t(a,Il(a,1),l(cl(a),`'${a}'`)))),(t,a)=>oe(e[t],((e,t)=>a(t,e[u],e[$],l(cl(t),`'${t}'`),Il(t,1)))),e=>oe(t,((t,a)=>e(a,t[u],t[$],l(cl(a),`'${a}'`),Il(a,1))))],hl=(e,t="",l="")=>`store.${e}(${t})`+(l?" as "+l:d),ml=(e,t="")=>`fluent(() => ${hl(e,t)})`,gl=(e,t,l)=>{const[a,n,o,r,c,i,b,y]=pl(),[P,E,L]=Cl(e,t,c),[D,N,j]=((e,t,l,a)=>[(a,n)=>{const o=a+": "+n,s=e(f,$l(...t((e=>`'${e}'?: {[rowId: Id]: `+$l(...l(e,((e,t,l)=>`'${e}'${O(l)?"?":d}: ${t}`)))+"}"))),Gt(1,5)),r=e(f+kt,$l(...t((e=>`'${e}'?: {[rowId: Id]: `+$l(...l(e,((e,t)=>`'${e}'?: ${t}`)))+"}"))),Gt(1,5,1)),I=e(g+ot,"keyof "+s,"A Table Id in "+wt),c=`<TId extends ${I}>`,i=e(g,it+`<${s}[TId]>`,"A Table in "+wt,c),u=e(g+kt,it+`<${r}[TId]>`,"A Table in "+wt+Pt,c),$=e(T,i+"<TId>[Id]","A Row in a "+g,c),b=e(T+kt,u+"<TId>[Id]","A Row in a "+g+Pt,c),C=e(R+ot,`Extract<keyof ${$}<TId>, Id>`,"A Cell Id in a "+T,c),m=e(R,it+`<${s}[TId]>[Id][CId]`,"A Cell in a "+T,`<TId extends ${I}, CId extends ${C}<TId>>`),y=e("CellIdCellArray",`CId extends ${C}<TId> ? [cellId: CId, cell: ${m}<TId, CId>] : never`,R+" Ids and types in a "+T,`<TId extends ${I}, CId = ${C}<TId>>`,0),S=e(R+qe,`(...[cellId, cell]: ${y}<TId>)`+At,Wt(_e+R+" Id, and "+R),c),A=e(T+qe,"(rowId: Id, forEachCell: (cellCallback: CellCallback<TId>) "+At+") "+At,Wt("a Row Id, and a Cell iterator"),c),k=e(g+R+qe,`(cellId: ${C}<TId>, count: number) `+At,Wt(_e+R+" Id, and count of how many times it appears"),c),P=e("TableIdForEachRowArray",`TId extends ${I} ? [tableId: TId, forEachRow: (rowCallback: ${A}<TId>)${At}] : never`,g+" Ids and callback types",`<TId = ${I}>`,0),E=e(g+qe,`(...[tableId, forEachRow]: ${P})`+At,Wt(_e+g+" Id, and a "+T+" iterator"),d),L=e("TableIdRowIdCellIdArray",`TId extends ${I} ? [tableId: TId, rowId: Id, cellId: ${C}<TId>] : never`,"Ids for GetCellChange",`<TId = ${I}>`,0),D=e("GetCellChange",`(...[tableId, rowId, cellId]: ${L}) => CellChange`,Ze+" returning information about any Cell's changes during a "+yt),N=e(h+f+p,`(${o}, hasTables: boolean)`+At,Ut(1,0,1)),J=e(f+p,`(${o}, getCellChange: ${D}${ct})`+At,Ut(1)),j=e(w+p,`(${o})`+At,Ut(2)),G=e(h+g+p,`(${o}, tableId: ${I}, hasTable: boolean)`+At,Ut(3,0,1)),M=e(g+p,`(${o}, tableId: ${I}, getCellChange: ${D}${ct})`+At,Ut(3)),z=e(g+x+p,`(${o}, tableId: ${I})`+At,Ut(14,3)),H=e("HasTableCellListenerArgsArrayInner",`CId extends ${C}<TId> ? [${o}, tableId: TId, cellId: CId, hasTableCell: boolean] : never`,"Cell args for HasTableCellListener",`<TId extends ${I}, CId = ${C}<TId>>`,0),F=e("HasTableCellListenerArgsArrayOuter",`TId extends ${I} ? `+H+"<TId> : never","Table args for HasTableCellListener",`<TId = ${I}>`,0),W=e(h+g+R+p,`(...[${a}, tableId, cellId, hasTableCell]: `+F+")"+At,Ut(16,3,1)),U=e(T+"Count"+p,`(${o}, tableId: ${I})`+At,Ut(15,3)),B=e(v+p,`(${o}, tableId: ${I})`+At,Ut(4,3)),_=e(V+p,"("+ul(o,"tableId: "+I,"cellId: Id"+ct,"descending: boolean","offset: number","limit: number"+ct,"sortedRowIds: Ids")+")"+At,Ut(13,3)),Z=e(h+T+p,"("+ul(""+o,"tableId: "+I,ht,"hasRow: boolean")+")"+At,Ut(5,3,1)),Q=e(T+p,"("+ul(""+o,"tableId: "+I,ht,`getCellChange: ${D}${ct}`)+")"+At,Ut(5,3)),q=e(x+p,"("+ul(""+o,"tableId: "+I,ht)+")"+At,Ut(6,5)),K=e("HasCellListenerArgsArrayInner",`CId extends ${C}<TId> ? [${o}, tableId: TId, ${ht}, cellId: CId, hasCell: boolean] : never`,"Cell args for HasCellListener",`<TId extends ${I}, CId = ${C}<TId>>`,0),X=e("HasCellListenerArgsArrayOuter",`TId extends ${I} ? `+K+"<TId> : never","Table args for HasCellListener",`<TId = ${I}>`,0),Y=e(h+R+p,`(...[${a}, tableId, rowId, cellId, hasCell]: `+X+")"+At,Ut(7,5,1)),ee=e("CellListenerArgsArrayInner",`CId extends ${C}<TId> ? [${o}, tableId: TId, ${ht}, cellId: CId, newCell: ${m}<TId, CId> ${ct}, oldCell: ${m}<TId, CId> ${ct}, getCellChange: ${D} ${ct}] : never`,"Cell args for CellListener",`<TId extends ${I}, CId = ${C}<TId>>`,0),te=e("CellListenerArgsArrayOuter",`TId extends ${I} ? `+ee+"<TId> : never","Table args for CellListener",`<TId = ${I}>`,0);return[s,r,I,i,u,$,b,C,m,S,A,k,E,N,J,j,G,M,z,W,U,B,_,Z,Q,q,Y,e(R+p,`(...[${a}, tableId, rowId, cellId, newCell, oldCell, getCellChange]: ${te})`+At,Ut(7,5)),e(st+R+p,`(${o}, tableId: Id, ${ht}, cellId: Id, invalidCells: any[])`+At,Ut(8))]},(t,l)=>{const n=t+": "+l,o=e(A,$l(...a(((e,t,l)=>`'${e}'${O(l)?"?":d}: ${t}`))),Gt(2,5)),s=e(A+kt,$l(...a(((e,t)=>`'${e}'?: ${t}`))),Gt(2,5,1)),r=e(S+ot,"keyof "+o,"A Value Id in "+wt),I=e(S,it+`<${o}[VId]>`,"A Value Id in "+wt,`<VId extends ${r}>`),c=e("ValueIdValueArray",`VId extends ${r} ? [valueId: VId, value: ${I}<VId>] : never`,S+" Ids and types in "+wt,`<VId = ${r}>`,0),i=e(S+qe,`(...[valueId, value]: ${c})`+At,Wt(_e+S+" Id, and "+S)),u=e("GetValueChange",`(valueId: ${r}) => ValueChange`,Ze+" returning information about any Value's changes during a "+yt),$=e(h+A+p,`(${n}, hasValues: boolean)`+At,Ut(9,0,1)),b=e(A+p,`(${n}, getValueChange: ${u}${ct})`+At,Ut(9)),C=e(k+p,`(${n})`+At,Ut(10)),m=e(h+S+p,`(${n}, valueId: ValueId, hasValue: boolean)`+At,Ut(11,0,1)),g=e("ValueListenerArgsArray",`VId extends ${r} ? [${n}, valueId: VId, newValue: ${I}<VId> ${ct}, oldValue: ${I}<VId> ${ct}, getValueChange: ${u} ${ct}] : never`,"Value args for ValueListener",`<VId = ${r}>`,0);return[o,s,r,I,i,$,b,C,m,e(S+p,`(...[${t}, valueId, newValue, oldValue, getValueChange]: `+g+")"+At,Ut(11)),e(st+S+p,`(${n}, valueId: Id, invalidValues: any[])`+At,Ut(12))]},(t,l)=>e(Tt+p,`(${t}: ${l})`+At,Ze+" listening to the completion of a "+yt)])(o,P,E,L),G=pe(),M=(e=0)=>ge(G,(([t,l,a,n,o],s)=>{const r=e?[s+`: ${o}(${t}): ${l} => ${a},`]:[s+o+`(${t}): ${l};`];return e||Z(r,il(n)),_(r,d),r})),z=(e,t,l,a,n,o="")=>dl(G,e,[t,l,a,n,o]),H=(e,t,l,a,n,o="",s="",r="")=>z(el[e]+t+(4==e?ut:d)+l,o,a,(a==Q?ml:hl)(el[e]+(4==e?ut:d)+l,s,e?void 0:a),n,r),F=(e,t,l,a="",n="",o=1,s="")=>z(C+e+p,(a?a+", ":d)+rt+": "+t+(o?", mutator?: boolean":d),ot,((e,t="",l="")=>`store.${e}(${t?t+", ":d}proxy(listener)${l?", "+l:d})`)(C+e+p,n,o?"mutator":d),l,s),B=`./${Il(l)}.d`,Q=Il(l,1),q=Il(Q),K=[],X=pe();let Y=[],ee=[];if(n(1,B,Q,`create${Q} as create${Q}Decl`),se(e))n(null,s,f);else{n(0,s,"CellChange"),n(null,s,m);const[e,t,l,a,r,i,b,p,C,y,S,A,k,L,N,j,G,M,z,Z,ee,te,le,ae,ne,oe,se,de,re]=D(q,Q),Ie=pe();P(((e,t)=>{const l=`<'${e}'>`,s=[o(t+g,a+l,Ct+` the '${e}' `+g),o(t+g+kt,r+l,Ct+` the '${e}' `+g+Pt),o(t+T,i+l,Mt(e)),o(t+T+kt,b+l,Mt(e,1)),o(t+R+ot,p+l,`A Cell Id for the '${e}' `+g),o(t+R+qe,y+l,Wt(`a Cell Id and value from a Row in the '${e}' `+g)),o(t+T+qe,S+l,Wt(`a Row Id from the '${e}' Table, and a Cell iterator`)),o(t+g+R+qe,A+l,Wt(`a Cell Id from anywhere in the '${e}' Table, and a count of how many times it appears`))];fe(Ie,e,s),n(1,B,...s)})),n(1,B,e,t,l,p,k,L,N,j,G,M,z,Z,ee,te,le,ae,ne,oe,se,de,re),Y=[e,t,l,p,L,N,j,G,M,z,Z,ee,te,le,ae,ne,oe,se,de,Ie],W([[e],[I],[Q,"tables: "+t,"tables"],[Q]],(([e,t,l],a)=>H(a,d,f,e,Gt(1,a),t,l))),H(0,d,w,l+ft,zt(g,wt)),H(5,d,g,St,Ht(g,wt),"tableCallback: "+k,"tableCallback as any"),P(((e,t,l)=>{const[a,n,o,s,r,c,i,u]=he(Ie,e);W([[a],[I],[Q,"table: "+n,", table"],[Q]],(([a,n,o=""],s)=>H(s,t,g,a,Qt(e,s),n,l+o))),H(0,t,g+x,m,zt(R,"the whole of "+_t(e)),d,l),H(5,t,g+R,St,Ht(g+R,"the whole of "+_t(e)),"tableCellCallback: "+u,l+", tableCellCallback as any"),H(0,t,T+Xe,"number","Gets the number of Rows in the "+_t(e),d,l),H(0,t,v,m,zt(T,_t(e)),d,l),H(0,t,V,m,zt(T,_t(e),1),"cellId?: "+r+", descending?: boolean, offset?: number, limit?: number",l+", cellId, descending, offset, limit"),H(5,t,T,St,Ht(T,_t(e)),"rowCallback: "+i,l+", rowCallback as any"),W([[o],[I],[Q,", row: "+s,", row"],[Q],[Q,", partialRow: "+s,", partialRow"]],(([a,n="",o=""],s)=>H(s,t,T,a,qt(e,s),ht+n,l+", rowId"+o))),H(6,t,T,ot+ct,"Add a new Row to "+_t(e),"row: "+s+", reuseIds?: boolean",l+", row, reuseIds"),H(0,t,x,r+ft,zt(R,Zt(e)),ht,l+", rowId"),H(5,t,R,St,Ht(R,Zt(e)),ht+", cellCallback: "+c,l+", rowId, cellCallback as any"),E(e,((a,n,o,s,r)=>{const c="Map"+Il(n,1);fe(X,n,c);const i=n+(O(o)?ct:d);W([[i],[I],[Q,`, cell: ${n} | `+c,", cell as any"],[Q]],(([n,o="",d=""],I)=>H(I,t+r,R,n,Kt(e,a,I),ht+o,l+", rowId, "+s+d))),H(1,t+r,g+R,I,Yt[1]+` the '${a}' Cell anywhere in `+_t(e),d,l+", "+s)}))})),H(0,d,f+dt,dt,Gt(1,6)),H(2,d,f+dt,Q,Gt(1,7),"tablesJson: "+dt,"tables"+dt),F(h+f,L,Gt(1,8,0,1)+" changes"),F(f,N,Gt(1,8)+" changes"),F(w,j,Bt(2,0,1)),F(h+g,G,Bt(3,0,0,1),`tableId: ${l} | null`,"tableId"),F(g,M,Bt(3,0),`tableId: ${l} | null`,"tableId"),F(g+x,z,Bt(14,3,1),`tableId: ${l} | null`,"tableId"),F(h+g+R,Z,Bt(16,3,0,1),`tableId: ${l} | null, cellId: ${U(P((e=>he(Ie,e)?.[4]??d))," | ")} | null`,"tableId, cellId"),F(T+Xe,ee,Bt(15,3),`tableId: ${l} | null`,"tableId"),F(v,te,Bt(4,3,1),`tableId: ${l} | null`,"tableId"),F(V,le,Bt(13,3,1),ul("tableId: TId",`cellId: ${p}<TId>`+ct,"descending: boolean","offset: number","limit: number"+ct),ul("tableId","cellId","descending","offset","limit"),1,"<TId extends TableId>"),F(h+T,ae,Bt(5,3,0,1),`tableId: ${l} | null, rowId: IdOrNull`,"tableId, rowId"),F(T,ne,Bt(5,3),`tableId: ${l} | null, rowId: IdOrNull`,"tableId, rowId"),F(x,oe,Bt(6,5,1),`tableId: ${l} | null, rowId: IdOrNull`,"tableId, rowId"),F(h+R,se,Bt(7,5,0,1),`tableId: ${l} | null, rowId: IdOrNull, cellId: ${U(P((e=>he(Ie,e)?.[4]??d))," | ")} | null`,"tableId, rowId, cellId"),F(R,de,Bt(7,5),`tableId: ${l} | null, rowId: IdOrNull, cellId: ${U(P((e=>he(Ie,e)?.[4]??d))," | ")} | null`,"tableId, rowId, cellId"),F(st+R,re,pt+" whenever an invalid Cell change was attempted","tableId: IdOrNull, rowId: IdOrNull, cellId: IdOrNull","tableId, rowId, cellId"),n(1,B,...ie(X)),_(K,".set"+f+mt+"({",rl(P(((e,t,l)=>[`[${l}]: {`,...E(e,((e,t,l,a)=>`[${a}]: {[${c(cl(u),`'${u}'`)}]: ${c(cl(t),`'${t}'`)}${O(l)?d:`, [${c(cl($),`'${$}'`)}]: `+(J(l)?c(cl(l),`'${l}'`):l)}},`)),"},"]))),"})")}if(se(t))n(null,s,A);else{const[e,t,l,a,o,r,i,b,p,C,m]=N(q,Q);n(1,B,e,t,l,o,r,i,b,p,C,m),ee=[e,t,l,r,i,b,p,C],W([[e],[I],[Q,"values: "+t,"values"],[Q],[Q,"partialValues: "+t,"partialValues"]],(([e,t,l],a)=>H(a,d,A,e,Gt(2,a),t,l))),H(0,d,k,l+ft,zt(S,wt)),H(5,d,S,"void",Ht(S,wt),"valueCallback: "+o,"valueCallback as any"),L(((e,t,l,a,n)=>{const o="Map"+Il(t,1);fe(X,t,o),W([[t],[I],[Q,`value: ${t} | `+o,", value as any"],[Q]],(([t,l,o=""],s)=>H(s,n,S,t,Xt(e,s),l,a+o)))})),H(0,d,A+dt,dt,Gt(2,6)),H(2,d,A+dt,Q,Gt(2,7),"valuesJson: "+dt,"values"+dt),F(h+A,r,Gt(2,8,0,1)+" changes"),F(A,i,Gt(2,8)+" changes"),F(k,b,Bt(10,0,1)),F(h+S,p,Bt(11,0,0,1),`valueId: ${l} | null`,"valueId"),F(S,C,Bt(11,0),`valueId: ${l} | null`,"valueId"),F(st+S,m,pt+" whenever an invalid Value change was attempted","valueId: IdOrNull","valueId"),n(1,B,...ie(X)),n(0,s,"ValueChange"),_(K,".set"+A+mt+"({",L(((e,t,l,a)=>[`[${a}]: {[${c(cl(u),`'${u}'`)}]: ${c(cl(t),`'${t}'`)}${O(l)?d:`, [${c(cl($),`'${$}'`)}]: `+(J(l)?c(cl(l),`'${l}'`):l)}},`])),"})")}H(0,d,"Content",`[${f}, ${A}]`,Gt(0,0)),H(2,d,"Content",Q,Gt(0,2),`[tables, values]: [${f}, ${A}]`,"[tables, values]"),H(7,d,"applyChanges",Q,`Applies a set of ${Ke} to the Store`,"changes: "+Ke,"changes"),me(X,((e,t)=>o(t,`(cell: ${e}${ct}) => `+e,`Takes a ${e} Cell value and returns another`))),n(null,s,"DoRollback",ot,"IdOrNull",dt,"Store",Ke),H(0,d,dt,dt,Gt(0,6)),H(2,d,dt,Q,Gt(0,7),"tablesAndValuesJson: "+dt,"tablesAndValuesJson"),H(7,d,yt,"Return",vt,at,"actions, doRollback","<Return>"),H(7,d,"start"+Tt,Q,Vt),H(7,d,"finish"+Tt,Q,Rt,lt,"doRollback");const te=j(q,Q);return F("Start"+Tt,te,pt+" just before the start of the "+yt,d,d,0),F("WillFinish"+Tt,te,pt+" just before "+xt,d,d,0),F("DidFinish"+Tt,te,pt+" just after "+xt,d,d,0),H(7,d,"call"+p,Q,"Manually provoke a listener to be called","listenerId: Id","listenerId"),H(3,d,p,Q,"Remove a listener that was previously added to "+wt,"listenerId: Id","listenerId"),z("getStore",d,"Store","store",Yt[0]+" the underlying Store object"),n(1,s,"createStore"),n(1,B,Q,`create${Q} as create${Q}Decl`,te),c("store",["createStore()",...K]),r("fluent","actions: () => Store",["actions();",`return ${q};`]),r("proxy","listener: any",`(_: Store, ...params: any[]) => listener(${q}, ...params)`),c(q,["{",...M(1),"}"]),[a(...i(0),...b(),nt+" interface "+Q+" {",...M(0),"}",d,il(`Creates a ${Q} object`),nt+" function create"+Q+"(): "+Q+";"),a(...i(1),nt+" const create"+Q+": typeof create"+Q+"Decl = () => {",...y(),`return Object.freeze(${q});`,"};"),Y,ee]},fl=e=>"get"+e,wl=e=>ul(fl(e),fl(e)+et),Tl="debugIds?: boolean",yl="debugIds={debugIds}",vl="then"+tt,Vl="Parameter",Rl=": (parameter: "+Vl+", store: Store) => ",xl="const contextValue = useContext(Context);",Sl=", based on a parameter",Al="<"+Vl+",>",kl=Vl+"ized"+qe+"<"+Vl+">",Pl="rowId",El="rowId={rowId}",Ll=", separator, debugIds",Ol="separator?: ReactElement | string",Dl="then?: (store: Store",Nl=ul(Dl+")"+At,vl),Jl="then, then"+et,jl=Pl+": "+ot,Gl="View",Ml=(e,...t)=>ul(...t,rt+": "+e,rt+tt,"mutator?: boolean"),zl=(...e)=>ul(...e,rt,rt+et,"mutator"),Hl=(e,t,l,a,n)=>{const[o,r,i,u,$,b,C,y]=pl(),[P,E,L]=Cl(e,t,$),D=`./${Il(l)}.d`,N=`./${Il(l)}-ui-react.d`,J="tinybase/ui-react",j=Il(l,1),G=Il(j),M=j+"Or"+j+ot,z=G+"Or"+j+ot,H=G+`={${G}}`,F=pe(),W=(e,t,l,a,n,o="")=>(r(1,N,e+" as "+e+"Decl"),dl(F,e,[t,l,a,n,o])),B=(e,t,l,a,n,o="")=>W("use"+e,t,l,a,n,o),Q=(e,t,l,a,n="",o="",s="",I="",c="")=>(r(1,J,`use${t} as use${t}Core`),B(e,ul(n,ee,I),l,le+`(${z}, use${t}Core, [`+(o||d)+(c?"], ["+c:d)+"]);",a,s)),q=(e,t,l,a)=>W(e,t,1,l,a),K=(e=0)=>ge(F,(([t,l,a,n,o],s)=>{const r=e?[nt+` const ${s}: typeof ${s}Decl = ${o}(${t}): ${1==l?"any":l} =>`,a]:[nt+` function ${s}${o}(${t}): ${1==l?"ComponentReturnType":l};`];return e||Z(r,il(n)),_(r,d),r}));r(null,s,ot,"Store",qe,Vl+"ized"+qe),r(0,J,"ComponentReturnType"),r(1,J,"useCellIds"),r(null,J,"ExtraProps"),r(0,D,j);const X=i(M,j+" | "+ot,`Used when you need to refer to a ${j} in a React hook or component`),Y=i(bt+$t,bl(G+It+j,G+`ById?: {[${G}Id: Id]: ${j}}`),`Used with the ${bt} component, so that a `+j+" can be passed into the context of an application");r(0,"react","ReactElement","ComponentType"),r(1,"react","React"),r(1,N,X,Y);const ee=z+It+X;$("{createContext, useContext, useMemo}","React"),$("Context",`createContext<[${j}?, {[${G}Id: Id]: ${j}}?]>([])`),B("Create"+j,`create: () => ${j}, create`+tt,j,"\n// eslint-disable-next-line react-hooks/exhaustive-deps\nuseMemo(create, createDeps)",`Create a ${j} within a React application with convenient memoization`);const te=B(j,"id?: Id",j+ct,["{",xl,"return id == null ? contextValue[0] : contextValue[1]?.[id];","}"],`Get a reference to a ${j} from within a ${bt} component context`),le=u("useHook",z+`: ${X} | undefined, hook: (...params: any[]) => any, preParams: any[], postParams: any[] = []`,[`const ${G} = ${te}(${z} as Id);`,`return hook(...preParams, ((${z} == null || typeof ${z} == 'string')`,`? ${G} : ${z})?.getStore(), ...postParams)`]),ae=u("getProps","getProps: ((id: any) => ExtraProps) | undefined, id: Id","(getProps == null) ? ({} as ExtraProps) : getProps(id)"),ne=u("wrap",ul("children: any","separator?: any","encloseWithId?: boolean","id?: Id"),["const separated = separator==null || !Array.isArray(children)"," ? children"," : children.map((child, c) => (c > 0 ? [separator, child] : child));","return encloseWithId ? [id, ':{', separated, '}'] : separated;"]),oe=u("useCustomOrDefaultCellIds",ul("customCellIds: Ids | undefined","tableId: Id","rowId: Id",`${z}?: ${X} | undefined`),[`const defaultCellIds = ${le}(${z}, useCellIds, [tableId, rowId]);`,"return customCellIds ?? defaultCellIds;"]),de=$("NullComponent","() => null");if(!se(e)){const[e,t,l,n,o,$,b,C,y,S,A,k,L,J,M,z,F,W,B,_]=a;r(null,D,e,t,l,o,$,b,C,y,S,A,k,L,J,M,z,F,B,W),r(0,D,n),r(1,D,j),r(null,s,m,"IdOrNull");const Z=u("tableView",`{${G}, rowComponent, getRowComponentProps, customCellIds`+Ll+"}: any, rowIds: Ids, tableId: Id, defaultRowComponent: React.ComponentType<any>",["const Row = rowComponent ?? defaultRowComponent;",`return ${ne}(rowIds.map((rowId) => (`,"<Row","{..."+ae+"(getRowComponentProps, rowId)}","key={rowId}","tableId={tableId}",El,"customCellIds={customCellIds}",H,yl,"/>","))",Ll,", tableId,",");"]),K=u("getDefaultTableComponent","tableId: Id",U(P(((e,t,l)=>`tableId == ${l} ? ${t}TableView : `)))+de),X=u("getDefaultCellComponent","tableId: Id, cellId: Id",U(P(((e,t,l)=>`tableId == ${l} ? ${U(E(e,((e,l,a,n,o)=>`cellId == ${n} ? `+t+o+"CellView : ")))+de} : `)))+de);Q(h+f,h+f,I,Gt(1,0,0,1)+Qe),Q(f,f,e,Gt(1,0)+Qe);const Y=Q(w,w,l+ft,zt(g,wt)+Qe);Q(gt+f+qe,gt+f+qe,kl,Gt(1,9)+Sl,ul(fl(f)+Rl+t,fl(f)+tt),wl(f),Al,ul(Dl,`tables: ${t})`+At,vl),Jl),Q(Ye+f+qe,Ye+f+qe,qe,Gt(1,12),d,d,d,Nl,Jl);const ee=i(R+$t,bl("tableId?: TId","rowId: Id","cellId?: CId",G+It+j,Tl),Ft(_e+R),`<TId extends ${l}, CId extends ${n}<TId>>`),te=i(T+$t,bl("tableId?: TId","rowId: Id",G+It+j,"cellComponents?: {readonly [CId in "+n+`<TId>]?: ComponentType<${ee}<TId, CId>>;}`,`getCellComponentProps?: (cellId: ${n}<TId>) => ExtraProps`,`customCellIds?: ${n}<TId>[]`,Ol,Tl),Ft(_e+T),`<TId extends ${l}>`),le=i(g+$t,bl("tableId?: TId",G+It+j,`rowComponent?: ComponentType<${te}<TId>>`,"getRowComponentProps?: (rowId: Id) => ExtraProps","customCellIds?: CellId<TId>[]",Ol,Tl),Ft(_e+g),`<TId extends ${l}>`),se=i("Sorted"+g+$t,bl("tableId?: TId","cellId?: "+n+"<TId>","descending?: boolean","offset?: number","limit?: number",G+It+j,`rowComponent?: ComponentType<${te}<TId>>`,"getRowComponentProps?: (rowId: Id) => ExtraProps","customCellIds?: CellId<TId>[]",Ol,Tl),Ft("a sorted "+g),`<TId extends ${l}>`),re=i(f+$t,bl(G+It+j,"tableComponents?: {readonly [TId in "+l+`]?: ComponentType<${le}<TId>>;}`,`getTableComponentProps?: (tableId: ${l}) => ExtraProps`,Ol,Tl),Ft(jt(1,1)));r(1,N,re,le,se,te,ee),q(f+Gl,"{"+G+", tableComponents, getTableComponentProps"+Ll+"}: "+re,[ne+`(${Y}(${G}).map((tableId) => {`,"const Table = (tableComponents?.[tableId] ?? "+K+"(tableId)) as React.ComponentType<TableProps<typeof tableId>>;","return <Table",`{...${ae}(getTableComponentProps, tableId)}`,"tableId={tableId}","key={tableId}",H,yl,"/>;","}), separator)"],Gt(1,13)+Qe),P(((e,t,l)=>{const[a,n,o,s,i]=he(_,e);r(null,D,a,n,o,s,i),Q(h+t+g,h+g,I,Qt(e,0,1)+Qe,d,l),Q(t+g,g,a,Qt(e)+Qe,d,l),Q(t+g+x,g+x,m,zt(R,"the whole of "+_t(e))+Qe,d,l),Q(t+T+Xe,T+Xe,c,"Gets the number of Rows in "+_t(e)+Qe,d,l);const u=Q(t+v,v,m,zt(T,_t(e))+Qe,d,l),$=Q(t+V,V,m,zt(T,_t(e),1)+Qe,"cellId?: "+i+", descending?: boolean, offset?: number, limit?: number",l+", cellId, descending, offset, limit");Q(h+t+T,h+T,I,qt(e,0,1)+Qe,jl,ul(l,Pl)),Q(t+T,T,o,qt(e)+Qe,jl,ul(l,Pl)),Q(t+x,x,i+ft,zt(R,Zt(e))+Qe,jl,ul(l,Pl)),Q(gt+t+g+qe,gt+g+qe,kl,Qt(e,9)+Sl,ul(fl(g)+Rl+n,fl(g)+tt),ul(l,wl(g)),Al,ul(Dl,`table: ${n})`+At,vl),Jl),Q(Ye+t+g+qe,Ye+g+qe,qe,Qt(e,12),d,l,d,Nl,Jl),Q(gt+t+T+qe,gt+T+qe,kl,qt(e,9)+Sl,ul(jl,fl(T)+Rl+s,fl(T)+tt),ul(l,Pl,wl(T)),Al,ul(Dl,`row: ${s})`+At,vl),Jl),Q("Add"+t+T+qe,"Add"+T+qe,kl,qt(e,10)+Sl,ul(fl(T)+Rl+s,fl(T)+tt),ul(l,wl(T)),Al,"then?: ("+ul(jl+ct,"store: Store","row: "+s+")"+At,"then"+tt)+", reuseRowIds?: boolean",Jl+", reuseRowIds"),Q(gt+t+ut+T+qe,gt+ut+T+qe,kl,qt(e,11)+Sl,ul(jl,fl(ut+T)+Rl+s,fl(ut+T)+tt),ul(l,Pl,wl(ut+T)),Al,ul(Dl,`partialRow: ${s})`+At,vl),Jl),Q(Ye+t+T+qe,Ye+T+qe,qe,qt(e,12),jl,ul(l,Pl),d,Nl,Jl);const b=q(t+T+Gl,"{rowId, "+G+", cellComponents, getCellComponentProps, customCellIds"+Ll+`}: ${te}<'${e}'>`,[ne+`(${oe}(customCellIds, `+l+`, rowId, ${G}).map((cellId: ${i}) => {`,"const Cell = (cellComponents?.[cellId] ?? "+X+`(${l}, cellId)) as React.ComponentType<CellProps<typeof `+l+", typeof cellId>>;","return <Cell",`{...${ae}(getCellComponentProps, cellId)} `,"key={cellId}",`tableId={${l}}`,El,"cellId={cellId}",H,yl,"/>;","})"+Ll+", rowId)"],qt(e,13)+Qe);q(t+"Sorted"+g+Gl,"{cellId, descending, offset, limit, ...props}: "+se+`<'${e}'>`,Z+"(props, "+$+`(cellId, descending, offset, limit, props.${G}), ${l}, ${b});`,Qt(e,13)+", sorted"+Qe),q(t+g+Gl,`props: ${le}<'${e}'>`,Z+"(props, "+u+`(props.${G}), ${l}, ${b});`,Qt(e,13)+Qe),E(e,((a,n,o,s,c)=>{const i="Map"+Il(n,1);r(0,D,i),r(1,D,i),Q(h+t+c+g+R,h+g+R,I,`Gets ${Jt(1)}the '${a}' Cell anywhere in `+_t(e)+Qe,d,ul(l,s)),Q(h+t+c+R,h+R,I,Kt(e,a,0,1)+Qe,jl,ul(l,Pl,s));const u=Q(t+c+R,R,n+(O(o)?ct:d),Kt(e,a)+Qe,jl,ul(l,Pl,s));Q(gt+t+c+R+qe,gt+R+qe,kl,Kt(e,a,9)+Sl,ul(jl,fl(R)+Rl+n+" | "+i,fl(R)+tt),ul(l,Pl,s,wl(R)),Al,ul(Dl,`cell: ${n} | ${i})`+At,vl),Jl),Q(Ye+t+c+R+qe,Ye+R+qe,qe,Kt(e,a,12),ul(jl,"forceDel?: boolean"),ul(l,Pl,s,"forceDel"),d,Nl,Jl),q(t+c+R+Gl,`{rowId, ${G}, debugIds}: `+ee+`<'${e}', '${a}'>`,[ne+`('' + ${u}(rowId, `+G+`) ?? '', undefined, debugIds, ${s})`],Kt(e,a,13)+Qe)}))}));const Ie=U(P((e=>he(_,e)?.[4]??d))," | ");Q(h+f+p,h+f+p,St,Gt(1,8,0,1)+" changes",Ml(o),zl()),Q(f+p,f+p,St,Gt(1,8)+" changes",Ml($),zl()),Q(w+p,w+p,St,Bt(2,0,1),Ml(b),zl()),Q(h+g+p,h+g+p,St,Bt(3,0,0,1),Ml(C,`tableId: ${l} | null`),zl("tableId")),Q(g+p,g+p,St,Bt(3,0),Ml(y,`tableId: ${l} | null`),zl("tableId")),Q(g+x+p,g+x+p,St,Bt(14,3,1),Ml(S,`tableId: ${l} | null`),zl("tableId")),Q(h+g+R+p,h+g+R+p,St,Bt(16,3,0,1),Ml(A,`tableId: ${l} | null`,`cellId: ${Ie} | null`),zl("tableId","cellId")),Q(T+Xe+p,T+Xe+p,St,Bt(15,3),Ml(k,`tableId: ${l} | null`),zl("tableId")),Q(v+p,v+p,St,Bt(4,3,1),Ml(L,`tableId: ${l} | null`),zl("tableId")),Q(V+p,V+p,St,Bt(13,3,1),Ml(J,`tableId: ${l} | null`,"cellId: "+Ie+ct,"descending: boolean","offset: number","limit: number"+ct),zl("tableId","cellId","descending","offset","limit")),Q(h+T+p,h+T+p,St,Bt(5,3,0,1),Ml(M,`tableId: ${l} | null`,Pl+": IdOrNull"),zl("tableId",Pl)),Q(T+p,T+p,St,Bt(5,3),Ml(z,`tableId: ${l} | null`,Pl+": IdOrNull"),zl("tableId",Pl)),Q(x+p,x+p,St,Bt(6,5,1),Ml(F,`tableId: ${l} | null`,Pl+": IdOrNull"),zl("tableId",Pl)),Q(h+R+p,h+R+p,St,Bt(7,5,0,1),Ml(W,`tableId: ${l} | null`,Pl+": IdOrNull",`cellId: ${Ie} | null`),zl("tableId",Pl,"cellId")),Q(R+p,R+p,St,Bt(7,5),Ml(B,`tableId: ${l} | null`,Pl+": IdOrNull",`cellId: ${Ie} | null`),zl("tableId",Pl,"cellId"))}if(!se(t)){const[e,t,l,a,o,s,c,$]=n;r(null,D,...n),r(1,D,j);const b=u("getDefaultValueComponent","valueId: Id",U(L(((e,t,l,a,n)=>`valueId == ${a} ? `+n+"ValueView : ")))+de);Q(h+A,h+A,I,Gt(2,0,0,1)+Qe),Q(A,A,e,Gt(2,0)+Qe);const C=Q(k,k,l+ft,zt(S,wt)+Qe);Q(gt+A+qe,gt+A+qe,kl,Gt(2,9)+Sl,ul(fl(A)+Rl+t,fl(A)+tt),wl(A),Al,ul(Dl,`values: ${t})`+At,vl),Jl),Q(gt+ut+A+qe,gt+ut+A+qe,kl,Gt(2,11)+Sl,ul(fl(ut+A)+Rl+t,fl(ut+A)+tt),wl(ut+A),Al,ul(Dl,`partialValues: ${t})`+At,vl),Jl),Q(Ye+A+qe,Ye+A+qe,qe,Gt(2,12),d,d,d,Nl,Jl);const m=i(S+$t,bl("valueId?: VId",G+It+j,Tl),Ft("a Value"),`<VId extends ${l}>`),g=i(A+$t,bl(G+It+j,"valueComponents?: {readonly [VId in "+l+`]?: ComponentType<${m}<VId>>;}`,`getValueComponentProps?: (valueId: ${l}) => ExtraProps`,Ol,Tl),Ft(jt(2,1)));r(1,N,g,m),q(A+Gl,"{"+G+", valueComponents, getValueComponentProps"+Ll+"}: "+g,[ne+`(${C}(${G}).map((valueId) => {`,"const Value = valueComponents?.[valueId] ?? "+b+"(valueId);","return <Value",`{...${ae}(getValueComponentProps, valueId)}`,"key={valueId}",H,yl,"/>;","}), separator)"],Gt(2,13)+Qe),L(((e,t,l,a,n)=>{const o="Map"+Il(t,1);r(0,D,o),r(1,D,o),Q(h+n+S,h+S,I,Xt(e,0,1)+Qe,d,a);const s=Q(n+S,S,t,Xt(e)+Qe,d,a);Q(gt+n+S+qe,gt+S+qe,kl,Xt(e,9)+Sl,ul(fl(S)+Rl+t+" | "+o,fl(S)+tt),ul(a,wl(S)),Al,ul(Dl,`value: ${t} | ${o})`+At,vl),Jl),Q(Ye+n+S+qe,Ye+S+qe,qe,Xt(e,12),d,a,d,Nl,Jl),q(n+S+Gl,`{${G}, debugIds}: ${m}<'${e}'>`,[ne+`('' + ${s}(`+G+`) ?? '', undefined, debugIds, ${a})`],Xt(e,13)+Qe)})),Q(h+A+p,h+A+p,St,Gt(2,8,0,1)+" changes",Ml(a),zl()),Q(A+p,A+p,St,Gt(2,8)+" changes",Ml(o),zl()),Q(k+p,k+p,St,Bt(10,0,1),Ml(s),zl()),Q(h+S+p,h+S+p,St,Bt(11,0,0,1),Ml(c,`valueId: ${l} | null`),zl("valueId")),Q(S+p,S+p,St,Bt(11,0),Ml($,`valueId: ${l} | null`),zl("valueId"))}return q(bt,`{${G}, ${G}ById, children}: `+Y+" & {readonly children: React.ReactNode}",["{",xl,"return (","<Context."+bt,"value={useMemo(",`() => [${G} ?? contextValue[0], {...contextValue[1], ...${G}ById}],`,`[${G}, ${G}ById, contextValue],`,")}>","{children}",`</Context.${bt}>`,");","}"],"Wraps part of an application in a context that provides default objects to be used by hooks and components within"),[o(...b(0),...C(),...K(0)),o(...b(1),...y(),...K(1))]},Fl="prettier/",Wl=Fl+"plugins/",Ul={parser:"typescript",singleQuote:!0,trailingComma:"all",bracketSpacing:!1,jsdocSingleLineComment:!1},Bl=((e,t)=>{const l=new WeakMap;return e=>(l.has(e)||l.set(e,(e=>{const t=()=>{const t=He(e.getTablesSchemaJson());return!se(t)||H(e.getTableIds(),(l=>{const a=e.getRowIds(l),n=pe();if(H(a,(t=>H(e.getCellIds(l,t),(a=>{const o=e.getCell(l,t,a),s=we(n,a,(()=>[je(o),pe(),[0],0])),[d,r,[I]]=s,c=we(r,o,(()=>0))+1;return c>I&&(s[2]=[c,o]),fe(r,o,c),s[3]++,d==je(o)})))))return t[l]={},$e(n,(([e,,[,n],o],s)=>{t[l][s]={[u]:e,...o==z(a)?{[$]:n}:{}}})),1}))?t:{}},l=()=>{const t=He(e.getValuesSchemaJson());return se(t)&&e.forEachValue(((e,l)=>{t[e]={[u]:je(l)}})),t},a=e=>((e,t,l)=>{if(se(e)&&se(t))return[d,d,d,d];const[a,n,o,s]=gl(e,t,l);return[a,n,...Hl(e,t,l,o,s)]})(t(),l(),e);return le({getStoreStats:t=>{let l=0,a=0,n=0;const o={};return e.forEachTable(((e,s)=>{l++;let d=0,r=0;const I={};s(((e,l)=>{d++;let a=0;l((()=>a++)),r+=a,t&&(I[e]={rowCells:a})})),a+=d,n+=r,t&&(o[e]={tableRows:d,tableCells:r,rows:I})})),{totalTables:l,totalRows:a,totalCells:n,totalValues:z(e.getValueIds()),jsonLength:z(e.getJson()),...t?{detail:{tables:o}}:{}}},getStoreTablesSchema:t,getStoreValuesSchema:l,getStoreApi:a,getPrettyStoreApi:async e=>{const t=["d.ts","ts","d.ts","tsx"],l=[];let n;try{n=(await import(Fl+"standalone")).format,_(l,await import(Wl+"estree"),await import(Wl+"typescript"))}catch(e){n=async e=>e}return await(async e=>E.all(e))(B(a(e),(async(e,a)=>(e=>e.replace(ol,((e,t,l)=>{const a=77-z(t);return`${t}/**\n${l.replace(RegExp(`([^\\n]{1,${a}})(\\s|$)`,"g"),t+" * $1\n")}${t} */`})))(await n(e,{...Ul,plugins:l,filepath:"_."+t[a]})))))},getStore:()=>e})})(e)),l.get(e))})(),_l=(...e)=>W(e,(e=>process.stdout.write(e+"\n"))),Zl=e=>He(l(e,b)),Ql=(t,l,n,o)=>{const s=e(t,l);_l(o.padStart(23)+": "+s),a(s,n,b)},ql=()=>{_l("","tinybase <command>","","Usage:",""),oe(Kl,(([,e,t],l)=>_l(` tinybase ${l} ${e}`," - "+t,""))),_l("See also http://tinybase.org/guides/developer-tools/command-line/","")},Kl={help:[ql,"","print this message"],version:[()=>_l(Zl(e(t(n(import.meta.url)),"../package.json")).version),"","get the current TinyBase version"],getStoreApi:[async(e,t,l)=>{try{const[a,n,o,s]=await(e=>{const t=Zl(e);return Bl(We().setSchema(...G(t)?t:[t]))})(e).getPrettyStoreApi(t);Ql(l,t+".d.ts",a,"Definition"),Ql(l,t+".ts",n,"Implementation"),Ql(l,t+"-ui-react.d.ts",o,"UI React definition"),Ql(l,t+"-ui-react.tsx",s,"UI React implementation")}catch{process.stderr.write("ERROR: provide a valid schemaFile, storeName, and outputDir\n")}},"<schemaFile> <storeName> <outputDir>","generate .d.ts, .ts, and .tsx API files from a schema file"]};(()=>{const[,,e,...t]=process.argv;(Kl[e]?.[0]??ql)(...t)})();
|
|
2
|
+
import{resolve as t,dirname as e}from"path";import{readFileSync as r,writeFileSync as s}from"fs";import{createStore as a}from"tinybase/store";import{createTools as o}from"tinybase/tools";import{fileURLToPath as i}from"url";const n="utf8",m=Object.entries,c=JSON.parse,p=(...t)=>{return e=t=>process.stdout.write(t+"\n"),t.forEach(e);var e},d=t=>c(r(t,n)),l=(e,r,a,o)=>{const i=t(e,r);p(o.padStart(23)+": "+i),s(i,a,n)},u=()=>{var t;p("","tinybase <command>","","Usage:",""),t=([,t,e],r)=>p(` tinybase ${r} ${t}`," - "+e,""),((t,e)=>{m(f).map(e)})(0,(([e,r])=>t(r,e))),p("See also http://tinybase.org/guides/developer-tools/command-line/","")},f={help:[u,"","print this message"],version:[()=>p(d(t(e(i(import.meta.url)),"../package.json")).version),"","get the current TinyBase version"],getStoreApi:[async(t,e,r)=>{try{const[s,i,n,m]=await(t=>{const e=d(t);return o(a().setSchema(...(r=e,Array.isArray(r)?e:[e])));var r})(t).getPrettyStoreApi(e);l(r,e+".d.ts",s,"Definition"),l(r,e+".ts",i,"Implementation"),l(r,e+"-ui-react.d.ts",n,"UI React definition"),l(r,e+"-ui-react.tsx",m,"UI React implementation")}catch{process.stderr.write("ERROR: provide a valid schemaFile, storeName, and outputDir\n")}},"<schemaFile> <storeName> <outputDir>","generate .d.ts, .ts, and .tsx API files from a schema file"]};(()=>{const[,,t,...e]=process.argv;(f[t]?.[0]??u)(...e)})();
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<section id="hero"><h2 id="the-reactive-data-store-for-local-first-apps">The <em>reactive</em> data store for <span>local-first apps</span>.</h2><p id="copy">Build blisteringly fast web apps that work both online and offline. Manage your state locally, synchronize it to the cloud when you need to, or even make it collaborative. But, most importantly... have fun building stuff again!</p></section><p><a href="https://beta.tinybase.org/guides/releases/#v5-0"><em>NEW!</em> v5.0 release</a> <span id="one-with">"The One You Can Sync"</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><ul><li>Manage <a href="#start-with-a-simple-key-value-store">key-value data</a>, <a href="#level-up-to-use-tabular-data">tabular data</a> - or both - with optional <a href="#apply-schemas-to-tables-values">schematization</a> to model your app's data structures.</li><li><a href="#register-granular-listeners">Flexibly reactive</a> to reconciled updates, so you only spend rendering cycles on things that change.</li><li><a href="#build-complex-queries-with-tinyql">Powerful query engine</a> to select, join, filter, group, sort and paginate data - reactively - and without SQL.</li><li>Built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, <a href="#model-table-relationships">tabular relationships</a> - and even an <a href="#set-checkpoints-for-an-undo-stack">undo stack</a> for your app state.</li><li>Create <a href="#type-definitions-orm-like-apis">type definitions & ORM-like APIs</a>, from schema or inference. <a href="#an-inspector-for-your-data">Inspect your data</a> (<em>new!</em>) directly in the browser.</li><li>Easily <a href="#persist-to-storage-sqlite-crdts">sync your data</a> to browser <a href="https://beta.tinybase.org/api/persister-browser">storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://beta.tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>; and (<em>new!</em>) <a href="https://beta.tinybase.org/api/persister-partykit-client/">PartyKit</a> and <a href="https://electric-sql.com/">ElectricSQL</a>.</li><li>Optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and (<em>new!</em>) <a href="#pre-built-reactive-components">pre-built components</a> that let you easily build fully reactive user interfaces.</li><li>Tiny by name, tiny by nature: <a href="#did-we-say-tiny">- </a>, no dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</li></ul><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends!</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://beta.tinybase.org/react.svg"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img width="48" src="https://beta.tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/expo.svg">Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/electric.svg">ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/turso.svg">Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/powersync.svg">PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://beta.tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://beta.tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://beta.tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img width="48" src="https://beta.tinybase.org/automerge.svg"> Automerge</a></div></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&logo=x&logoColor=%23fff&label=Twitter&labelColor=%23333&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=jest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/5.0.0-beta.
|
|
1
|
+
<section id="hero"><h2 id="the-reactive-data-store-for-local-first-apps">The <em>reactive</em> data store for <span>local-first apps</span>.</h2><p id="copy">Build blisteringly fast web apps that work both online and offline. Manage your state locally, synchronize it to the cloud when you need to, or even make it collaborative. But, most importantly... have fun building stuff again!</p></section><p><a href="https://beta.tinybase.org/guides/releases/#v5-0"><em>NEW!</em> v5.0 release</a> <span id="one-with">"The One You Can Sync"</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><ul><li>Manage <a href="#start-with-a-simple-key-value-store">key-value data</a>, <a href="#level-up-to-use-tabular-data">tabular data</a> - or both - with optional <a href="#apply-schemas-to-tables-values">schematization</a> to model your app's data structures.</li><li><a href="#register-granular-listeners">Flexibly reactive</a> to reconciled updates, so you only spend rendering cycles on things that change.</li><li><a href="#build-complex-queries-with-tinyql">Powerful query engine</a> to select, join, filter, group, sort and paginate data - reactively - and without SQL.</li><li>Built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, <a href="#model-table-relationships">tabular relationships</a> - and even an <a href="#set-checkpoints-for-an-undo-stack">undo stack</a> for your app state.</li><li>Create <a href="#type-definitions-orm-like-apis">type definitions & ORM-like APIs</a>, from schema or inference. <a href="#an-inspector-for-your-data">Inspect your data</a> (<em>new!</em>) directly in the browser.</li><li>Easily <a href="#persist-to-storage-sqlite-crdts">sync your data</a> to browser <a href="https://beta.tinybase.org/api/persister-browser">storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://beta.tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>; and (<em>new!</em>) <a href="https://beta.tinybase.org/api/persister-partykit-client/">PartyKit</a> and <a href="https://electric-sql.com/">ElectricSQL</a>.</li><li>Optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and (<em>new!</em>) <a href="#pre-built-reactive-components">pre-built components</a> that let you easily build fully reactive user interfaces.</li><li>Tiny by name, tiny by nature: <a href="#did-we-say-tiny">- </a>, no dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</li></ul><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends!</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://beta.tinybase.org/react.svg"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img width="48" src="https://beta.tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/expo.svg">Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/electric.svg">ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/turso.svg">Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://beta.tinybase.org/powersync.svg">PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://beta.tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://beta.tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://beta.tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img width="48" src="https://beta.tinybase.org/automerge.svg"> Automerge</a></div></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&logo=x&logoColor=%23fff&label=Twitter&labelColor=%23333&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=jest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/5.0.0-beta.20" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://beta.tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
|
|
2
2
|
|
|
3
3
|
```js
|
|
4
4
|
import {createStore} from 'tinybase';
|
|
@@ -58,7 +58,7 @@ console.log(app.innerHTML);
|
|
|
58
58
|
// -> 'Color: walnut'
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
<section><h2 id="pre-built-reactive-components">Pre-built reactive components.</h2><p>The <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module provides bare React components that let you build up a fully reactive user interface based on a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>.</p><p>For web applications in particular, the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module provides pre-built components for tabular display of your data, with lots of customization and interactivity options.</p><p>Try them out in the <a href="https://beta.tinybase.org/demos/ui-components/">UI Components</a> demos, and read more about the underlying <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module in the <a href="https://beta.tinybase.org/guides/building-uis/">Building UIs</a> guides.</p></section><img src="https://beta.tinybase.org/ui-react-dom.webp"><section><h2 id="an-inspector-for-your-data">An inspector for your data.</h2><p>If you are building a web application, the new Inspector component lets you overlay a view of the data in your <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, and so on. You can even edit the data in place and see it update in your app immediately.</p><p>Read more about this powerful new tool in the <a href="https://beta.tinybase.org/guides/developer-tools/inspecting-data/">Inspecting Data</a> guide.</p></section><img src="https://beta.tinybase.org/store-inspector.webp"><section><h2 id="apply-schemas-to-tables-values">Apply schemas to tables & values.</h2><p>By default, a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> can contain any arbitrary <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a>, and a <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> can contain any arbitrary <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a>. But you can add a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a> or a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a> to a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> to ensure that the values are always what you expect: constraining their types, and providing defaults.</p><p>In this example, we set a new <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> without the <code>sold</code> <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> in it. The schema ensures it's present with default of <code>false</code>.</p><p>Read more about schemas in the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/using-schemas/">Using Schemas</a> guide.</p></section>
|
|
61
|
+
<section><h2 id="pre-built-reactive-components">Pre-built reactive components.</h2><p>The <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module provides bare React components that let you build up a fully reactive user interface based on a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>.</p><p>For web applications in particular, the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module provides pre-built components for tabular display of your data, with lots of customization and interactivity options.</p><p>Try them out in the <a href="https://beta.tinybase.org/demos/ui-components/">UI Components</a> demos, and read more about the underlying <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module in the <a href="https://beta.tinybase.org/guides/building-uis/">Building UIs</a> guides.</p></section><img src="https://beta.tinybase.org/ui-react-dom.webp"><section><h2 id="an-inspector-for-your-data">An inspector for your data.</h2><p>If you are building a web application, the new <a href="https://beta.tinybase.org/api/ui-react-inspector/functions/development-components/inspector/"><code>Inspector</code></a> component lets you overlay a view of the data in your <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, and so on. You can even edit the data in place and see it update in your app immediately.</p><p>Read more about this powerful new tool in the <a href="https://beta.tinybase.org/guides/developer-tools/inspecting-data/">Inspecting Data</a> guide.</p></section><img src="https://beta.tinybase.org/store-inspector.webp"><section><h2 id="apply-schemas-to-tables-values">Apply schemas to tables & values.</h2><p>By default, a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> can contain any arbitrary <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a>, and a <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> can contain any arbitrary <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a>. But you can add a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a> or a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a> to a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> to ensure that the values are always what you expect: constraining their types, and providing defaults.</p><p>In this example, we set a new <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> without the <code>sold</code> <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> in it. The schema ensures it's present with default of <code>false</code>.</p><p>Read more about schemas in the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/using-schemas/">Using Schemas</a> guide.</p></section>
|
|
62
62
|
|
|
63
63
|
```js
|
|
64
64
|
store.setTablesSchema({
|
|
@@ -265,4 +265,4 @@ export const createShop: typeof createShopDecl = () => {
|
|
|
265
265
|
};
|
|
266
266
|
```
|
|
267
267
|
|
|
268
|
-
<section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you'll only add a gzipped __ to your app. Incrementally add the other modules as you need more functionality, or get it all for __.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just another __, the auxiliary <a href="https://beta.tinybase.org/api/tools/"><code>tools</code></a> module is __, and everything is super fast. Life's easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>.js.gz</th><th>.js</th><th>debug.js</th><th>.d.ts</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">store</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/metrics/">metrics</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/indexes/">indexes</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/relationships/">relationships</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/queries/">queries</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/checkpoints/">checkpoints</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/mergeable-store/">mergeable-store</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/persisters/">persisters</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/synchronizers/">synchronizers</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/common/">common</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right">tinybase (all)</th><td></td><td></td><td></td><td></td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,372</td><td>2,372</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,556</td><td>2,556</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>999</td><td>999</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>950</td><td>950</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">6,719</td></tr><tr><th class="right">Assertions</th><td colspan="3">31,380</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/expo" target="_blank"><img title="expo" src="https://github.com/expo.png?size=48" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img title="beekeeb" src="https://github.com/beekeeb.png?size=48" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img title="cancelself" src="https://github.com/cancelself.png?size=48" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img title="WonderPanda" src="https://github.com/WonderPanda.png?size=48" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img title="arpitBhalla" src="https://github.com/arpitBhalla.png?size=48" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/Apocalypsor" target="_blank"><img title="Apocalypsor" src="https://github.com/Apocalypsor.png?size=48" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img title="brentvatne" src="https://github.com/brentvatne.png?size=48" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img title="circadian-risk" src="https://github.com/circadian-risk.png?size=48" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img title="cubecull" src="https://github.com/cubecull.png?size=48" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img title="erwinkn" src="https://github.com/erwinkn.png?size=48" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img title="expo" src="https://github.com/expo.png?size=48" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img title="ezra-en" src="https://github.com/ezra-en.png?size=48" width="48" height="48"></a><a href="https://github.com/fdfontes" target="_blank"><img title="fdfontes" src="https://github.com/fdfontes.png?size=48" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img title="feychenie" src="https://github.com/feychenie.png?size=48" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img title="flaming-codes" src="https://github.com/flaming-codes.png?size=48" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img title="fostertheweb" src="https://github.com/fostertheweb.png?size=48" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img title="fostertheweb" src="https://github.com/fostertheweb.png?size=48" width="48" height="48"></a><a href="https://github.com/generates" target="_blank"><img title="generates" src="https://github.com/generates.png?size=48" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img title="Giulio987" src="https://github.com/Giulio987.png?size=48" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img title="itsdevcoffee" src="https://github.com/itsdevcoffee.png?size=48" width="48" height="48"></a><a href="https://github.com/jaysc" target="_blank"><img title="jaysc" src="https://github.com/jaysc.png?size=48" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img title="jbolda" src="https://github.com/jbolda.png?size=48" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img title="Kayoo-asso" src="https://github.com/Kayoo-asso.png?size=48" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img title="kotofurumiya" src="https://github.com/kotofurumiya.png?size=48" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img title="Kudo" src="https://github.com/Kudo.png?size=48" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img title="learn-anything" src="https://github.com/learn-anything.png?size=48" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img title="lluc" src="https://github.com/lluc.png?size=48" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img title="marksteve" src="https://github.com/marksteve.png?size=48" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img title="miking-the-viking" src="https://github.com/miking-the-viking.png?size=48" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img title="mjamesderocher" src="https://github.com/mjamesderocher.png?size=48" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img title="nikitavoloboev" src="https://github.com/nikitavoloboev.png?size=48" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img title="palerdot" src="https://github.com/palerdot.png?size=48" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img title="PorcoRosso85" src="https://github.com/PorcoRosso85.png?size=48" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img title="shaneosullivan" src="https://github.com/shaneosullivan.png?size=48" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img title="sudo-self" src="https://github.com/sudo-self.png?size=48" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img title="SuperSonicHub1" src="https://github.com/SuperSonicHub1.png?size=48" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img title="threepointone" src="https://github.com/threepointone.png?size=48" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img title="uptonking" src="https://github.com/uptonking.png?size=48" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img title="WonderPanda" src="https://github.com/WonderPanda.png?size=48" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
|
|
268
|
+
<section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you'll only add a gzipped __ to your app. Incrementally add the other modules as you need more functionality, or get it all for __.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just another __, the auxiliary <a href="https://beta.tinybase.org/api/tools/"><code>tools</code></a> module is __, and everything is super fast. Life's easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>.js.gz</th><th>.js</th><th>debug.js</th><th>.d.ts</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">store</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/metrics/">metrics</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/indexes/">indexes</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/relationships/">relationships</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/queries/">queries</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/checkpoints/">checkpoints</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/mergeable-store/">mergeable-store</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/persisters/">persisters</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/synchronizers/">synchronizers</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/common/">common</a></th><td></td><td></td><td></td><td></td></tr><tr><th class="right">tinybase (all)</th><td></td><td></td><td></td><td></td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,372</td><td>2,372</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,556</td><td>2,556</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>999</td><td>999</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>950</td><td>950</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">6,720</td></tr><tr><th class="right">Assertions</th><td colspan="3">31,381</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/expo" target="_blank"><img title="expo" src="https://github.com/expo.png?size=48" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img title="beekeeb" src="https://github.com/beekeeb.png?size=48" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img title="cancelself" src="https://github.com/cancelself.png?size=48" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img title="WonderPanda" src="https://github.com/WonderPanda.png?size=48" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img title="arpitBhalla" src="https://github.com/arpitBhalla.png?size=48" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/Apocalypsor" target="_blank"><img title="Apocalypsor" src="https://github.com/Apocalypsor.png?size=48" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img title="brentvatne" src="https://github.com/brentvatne.png?size=48" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img title="circadian-risk" src="https://github.com/circadian-risk.png?size=48" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img title="cubecull" src="https://github.com/cubecull.png?size=48" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img title="erwinkn" src="https://github.com/erwinkn.png?size=48" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img title="expo" src="https://github.com/expo.png?size=48" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img title="ezra-en" src="https://github.com/ezra-en.png?size=48" width="48" height="48"></a><a href="https://github.com/fdfontes" target="_blank"><img title="fdfontes" src="https://github.com/fdfontes.png?size=48" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img title="feychenie" src="https://github.com/feychenie.png?size=48" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img title="flaming-codes" src="https://github.com/flaming-codes.png?size=48" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img title="fostertheweb" src="https://github.com/fostertheweb.png?size=48" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img title="fostertheweb" src="https://github.com/fostertheweb.png?size=48" width="48" height="48"></a><a href="https://github.com/generates" target="_blank"><img title="generates" src="https://github.com/generates.png?size=48" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img title="Giulio987" src="https://github.com/Giulio987.png?size=48" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img title="itsdevcoffee" src="https://github.com/itsdevcoffee.png?size=48" width="48" height="48"></a><a href="https://github.com/jaysc" target="_blank"><img title="jaysc" src="https://github.com/jaysc.png?size=48" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img title="jbolda" src="https://github.com/jbolda.png?size=48" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img title="Kayoo-asso" src="https://github.com/Kayoo-asso.png?size=48" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img title="kotofurumiya" src="https://github.com/kotofurumiya.png?size=48" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img title="Kudo" src="https://github.com/Kudo.png?size=48" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img title="learn-anything" src="https://github.com/learn-anything.png?size=48" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img title="lluc" src="https://github.com/lluc.png?size=48" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img title="marksteve" src="https://github.com/marksteve.png?size=48" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img title="miking-the-viking" src="https://github.com/miking-the-viking.png?size=48" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img title="mjamesderocher" src="https://github.com/mjamesderocher.png?size=48" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img title="nikitavoloboev" src="https://github.com/nikitavoloboev.png?size=48" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img title="palerdot" src="https://github.com/palerdot.png?size=48" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img title="PorcoRosso85" src="https://github.com/PorcoRosso85.png?size=48" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img title="shaneosullivan" src="https://github.com/shaneosullivan.png?size=48" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img title="sudo-self" src="https://github.com/sudo-self.png?size=48" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img title="SuperSonicHub1" src="https://github.com/SuperSonicHub1.png?size=48" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img title="threepointone" src="https://github.com/threepointone.png?size=48" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img title="uptonking" src="https://github.com/uptonking.png?size=48" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img title="WonderPanda" src="https://github.com/WonderPanda.png?size=48" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
|
package/releases.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p>This is a reverse chronological list of the major <a href="https://beta.tinybase.org/">TinyBase</a> releases, with highlighted features.</p><h2 id="v5-0">v5.0</h2><p>This release (
|
|
1
|
+
<p>This is a reverse chronological list of the major <a href="https://beta.tinybase.org/">TinyBase</a> releases, with highlighted features.</p><h2 id="v5-0">v5.0</h2><p>This is a major release for <a href="https://beta.tinybase.org/">TinyBase</a> and adds important new CRDT & synchronization functionality. It also includes some breaking changes that may affect you (but which should easy to fix they do!)</p><p>The main new functionality is in the new <a href="https://beta.tinybase.org/api/mergeable-store/"><code>mergeable-store</code></a> module, which contains a subtype of <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> - called <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> - that can be merged with another with deterministic results. The implementation uses an encoded hybrid logical clock (HLC) to timestamp the changes made so that they can be cleanly merged. A synchronization protocol also lets you negotiate changes between systems.</p><h3 id="local-merging">Local Merging</h3><p>The <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/getter/getmergeablecontent/"><code>getMergeableContent</code></a> method on a <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> is used to get the state of a store that can be merged into another. The <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/setter/applymergeablechanges/"><code>applyMergeableChanges</code></a> method will let you apply that to (another) store. The <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/setter/merge/"><code>merge</code></a> method is a convenience function to bidirectionally merge two stores together:</p>
|
|
2
2
|
|
|
3
3
|
```js
|
|
4
4
|
import {createMergeableStore} from 'tinybase';
|
|
@@ -18,7 +18,7 @@ console.log(localStore2.getContent());
|
|
|
18
18
|
// -> [{pets: {felix: {color: 'black'}, fido: {color: 'brown'}}}, {}]
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
<p>
|
|
21
|
+
<p>This is a simple enough local example to get the idea, but things get more exciting when you synchronize stores between systems...</p><h3 id="persisting-and-syncing-between-systems">Persisting And Syncing Between Systems</h3><p>Firstly, a <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> can be persisted locally, just like a regular <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>. This is supported by certain <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> types: file, local and session storage, and simple SQLite persisters such as Expo and SQLite3. These allows you to persist the state of a <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> locally before it has had the chance to be synchronized online, for example.</p><p>But more importantly, the v5.0 release also introduces the new concept of synchronization. <a href="https://beta.tinybase.org/api/synchronizers/interfaces/synchronizer/synchronizer/"><code>Synchronizer</code></a> objects implement a negotiation protocol that allows multiple <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> objects to be merged across a network for example:</p>
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
import {WebSocketServer, WebSocket} from 'ws';
|
|
@@ -60,7 +60,7 @@ synchronizer2.destroy();
|
|
|
60
60
|
server.destroy();
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
<p>Notice that the <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> assumes that there exists a server that can forward requests to other <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> systems. This can be created using the <a href="https://beta.tinybase.org/api/synchronizer-ws-server/functions/creation/createwsserver/"><code>createWsServer</code></a> function that takes a WebSocketServer as shown above.</p><h3 id="
|
|
63
|
+
<p>This release includes two types of <a href="https://beta.tinybase.org/api/synchronizers/interfaces/synchronizer/synchronizer/"><code>Synchronizer</code></a>: the <a href="https://beta.tinybase.org/api/synchronizer-local/interfaces/synchronizer/localsynchronizer/"><code>LocalSynchronizer</code></a> (for demonstrating synchronization on a single local system), and more importantly the <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> (that uses WebSockets to communicate between different systems, shown above).</p><p>Notice that the <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> assumes that there exists a server that can forward requests to other <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> systems. This can be created using the <a href="https://beta.tinybase.org/api/synchronizer-ws-server/functions/creation/createwsserver/"><code>createWsServer</code></a> function that takes a WebSocketServer as also shown above.</p><h3 id="breaking-changes-in-v5-0">Breaking <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> in v5.0</h3><h4 id="module-file-structure">Module File Structure</h4><p>Previously, the distributed package contained a <code>lib</code> folder with both code and type definitions. In v5.0, they have been hoisted to the top level of the package so that less-capable bundlers can find the correct files.</p><p>If you previously had <code>/lib/</code> in your import paths, you should remove it. You also do not have to explicitly specify whether you need the <code>cjs</code> version of <a href="https://beta.tinybase.org/">TinyBase</a> - if you are using a <code>require</code> rather than an <code>import</code>, you will get it automatically.</p><p>Please read the comprehensive <a href="https://beta.tinybase.org/guides/the-basics/importing-tinybase/">Importing TinyBase</a> guide for more details of how to construct the correct import paths in v5.0.</p><h4 id="the-tinybase-inspector">The <a href="https://beta.tinybase.org/">TinyBase</a> Inspector</h4><p>Previously, the React-based inspector (then known as <code>StoreInspector</code>) resided in the debug version of the <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module. It now lives in its own <a href="https://beta.tinybase.org/api/ui-react-inspector/"><code>ui-react-inspector</code></a> module (so that it can be used against non-debug code) and has been renamed to Inspector.</p><p>Please update your imports and rename the component when used, accordingly. See the API documentation for details, or the <a href="https://beta.tinybase.org/demos/ui-components/inspector/"><inspector></inspector></a>demo, for example.</p><h4 id="api-changes">API <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a></h4><p>The following changes have been made to the existing <a href="https://beta.tinybase.org/">TinyBase</a> API for consistency. These are less common parts of the API but should straightforward to correct if you are using them.</p><p>In the type definitions:</p><ul><li>The GetTransactionChanges and GetTransactionLog types have been removed.</li><li>The TransactionChanges type has been renamed as the <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> type.</li><li>The <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> type now uses <code>undefined</code> instead of <code>null</code> to indicate a <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> or <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> that has been deleted or that was not present.</li><li>The <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/transactionlog/"><code>TransactionLog</code></a> type is now an array instead of a JavaScript object.</li></ul><p>In the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> interface:</p><ul><li>There is a new <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionchanges/"><code>getTransactionChanges</code></a> method and a new getTransactionLog method.</li><li>The setTransactionChanges method is renamed as the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/applychanges/"><code>applyChanges</code></a> method.</li><li>A <a href="https://beta.tinybase.org/api/store/type-aliases/callback/dorollback/"><code>DoRollback</code></a> function no longer gets passed arguments. You can use the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionchanges/"><code>getTransactionChanges</code></a> method and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionlog/"><code>getTransactionLog</code></a> method directly instead.</li><li>Similarly, a <a href="https://beta.tinybase.org/api/store/type-aliases/listener/transactionlistener/"><code>TransactionListener</code></a> function no longer gets passed arguments.</li></ul><p>In the <a href="https://beta.tinybase.org/api/persisters/"><code>persisters</code></a> module:</p><ul><li>The <a href="https://beta.tinybase.org/api/persisters/functions/creation/createcustompersister/"><code>createCustomPersister</code></a> function now takes a final optional boolean (<code>supportsMergeableStore</code>) to indicate that the <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> can support <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> as well as <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> objects.</li><li>A <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a>'s <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/load/"><code>load</code></a> method and <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/startautoload/"><code>startAutoLoad</code></a> method now take a <a href="https://beta.tinybase.org/api/store/type-aliases/store/content/"><code>Content</code></a> object as one parameter, rather than <a href="https://beta.tinybase.org/api/store/type-aliases/store/tables/"><code>Tables</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> as two.</li><li>If you create a custom <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a>, the setPersisted method now receives changes made to a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> directly by reference, rather than via a callback. Similarly, the <a href="https://beta.tinybase.org/api/persisters/type-aliases/creation/persisterlistener/"><code>PersisterListener</code></a> you register in your addPersisterListener implementation now takes <a href="https://beta.tinybase.org/api/store/type-aliases/store/content/"><code>Content</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> objects directly rather than via a callback.</li><li>The broadcastTransactionChanges method in the <a href="https://beta.tinybase.org/api/persister-partykit-server/"><code>persister-partykit-server</code></a> module has been renamed to the broadcastChanges method.</li></ul><h2 id="v4-8">v4.8</h2><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-powersync/"><code>persister-powersync</code></a> module, which provides a <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> for <a href="https://www.powersync.com/">PowerSync's SQLite</a> database.</p><p>Much like the other SQLite persisters, use it by passing in a PowerSync instance to the <a href="https://beta.tinybase.org/api/persister-powersync/functions/creation/createpowersyncpersister/"><code>createPowerSyncPersister</code></a> function; something like:</p>
|
|
64
64
|
|
|
65
65
|
```js yolo
|
|
66
66
|
const powerSync = usePowerSync();
|
|
@@ -193,7 +193,7 @@ console.log(app.innerHTML);
|
|
|
193
193
|
root.unmount();
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
-
<p>The <a href="https://beta.tinybase.org/api/ui-react-dom/functions/store-components/editablecellview/"><code>EditableCellView</code></a> component and <a href="https://beta.tinybase.org/api/ui-react-dom/functions/store-components/editablevalueview/"><code>EditableValueView</code></a> component are interactive input controls for updating <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> content respectively. You can generally use them across your table views by adding the <code>editable</code> prop to your table component.</p><h3 id="the-new-inspector">The new Inspector</h3><p><img src="https://beta.tinybase.org/store-inspector.webp" alt="Inspector" title="Inspector"></p><p>The new Inspector component allows you to view, understand, and edit the content of a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> in a debug web environment. Try it out in most of the demos on the site, including the <a href="https://beta.tinybase.org/demos/movie-database/">Movie Database</a> demo, pictured. This requires a debug build of the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module, which is now also included in the UMD distribution.</p><p>Also in this release, the <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/methods/result/getresulttablecellids/"><code>getResultTableCellIds</code></a> method and <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/methods/listener/addresulttablecellidslistener/"><code>addResultTableCellIdsListener</code></a> method have been added to the <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a> object. The equivalent <a href="https://beta.tinybase.org/api/ui-react/functions/queries-hooks/useresulttablecellids/"><code>useResultTableCellIds</code></a> hook and <a href="https://beta.tinybase.org/api/ui-react/functions/queries-hooks/useresulttablecellidslistener/"><code>useResultTableCellIdsListener</code></a> hook have also been added to <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module. A number of other minor React hooks have been added to support the components above.</p><p><a href="https://beta.tinybase.org/demos/">Demos</a> have been updated to demonstrate the <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module and the Inspector component where appropriate.</p><p>(NB: Previous to v5.0, this component was called <code>StoreInspector</code>.)</p><h2 id="v4-0">v4.0</h2><p>This major release provides <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> modules that connect <a href="https://beta.tinybase.org/">TinyBase</a> to SQLite databases (in both browser and server contexts), and CRDT frameworks that can provide synchronization and local-first reconciliation:</p><div class="table"><table><thead><tr><th>Module</th><th>Function</th><th>Storage</th></tr></thead><tbody><tr><td><a href="https://beta.tinybase.org/api/persister-sqlite3/"><code>persister-sqlite3</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite3/functions/creation/createsqlite3persister/"><code>createSqlite3Persister</code></a></td><td>SQLite in Node, via <a href="https://github.com/TryGhost/node-sqlite3">sqlite3</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/"><code>persister-sqlite-wasm</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/functions/creation/createsqlitewasmpersister/"><code>createSqliteWasmPersister</code></a></td><td>SQLite in a browser, via <a href="https://github.com/tomayac/sqlite-wasm">sqlite-wasm</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm/"><code>persister-cr-sqlite-wasm</code></a></td><td><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm/functions/creation/createcrsqlitewasmpersister/"><code>createCrSqliteWasmPersister</code></a></td><td>SQLite CRDTs, via <a href="https://github.com/vlcn-io/cr-sqlite">cr-sqlite-wasm</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-yjs/"><code>persister-yjs</code></a></td><td><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister/"><code>createYjsPersister</code></a></td><td>Yjs CRDTs, via <a href="https://github.com/yjs/yjs">yjs</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-automerge/"><code>persister-automerge</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/functions/creation/createsqlitewasmpersister/"><code>createSqliteWasmPersister</code></a></td><td>Automerge CRDTs, via <a href="https://github.com/automerge/automerge-repo">automerge-repo</a></td></tr></tbody></table></div><p>See the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence/">Database Persistence</a> guide for details on how to work with SQLite databases, and the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/synchronizing-data/">Synchronizing Data</a> guide for more complex synchronization with the CRDT frameworks.</p><p>Take a look at the <a href="https://github.com/tinyplex/vite-tinybase-ts-react-crsqlite">vite-tinybase-ts-react-crsqlite</a> template, for example, which demonstrates Vulcan's cr-sqlite to provide persistence and synchronization via this technique.</p><h3 id="sqlite-databases">SQLite databases</h3><p>You can persist <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> data to a database with either a JSON serialization or tabular mapping. (See the <a href="https://beta.tinybase.org/api/persisters/type-aliases/configuration/databasepersisterconfig/"><code>DatabasePersisterConfig</code></a> documentation for more details).</p><p>For example, this creates a <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> object and saves and loads the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> to and from a local SQLite database. It uses an explicit tabular one-to-one mapping for the 'pets' table:</p>
|
|
196
|
+
<p>The <a href="https://beta.tinybase.org/api/ui-react-dom/functions/store-components/editablecellview/"><code>EditableCellView</code></a> component and <a href="https://beta.tinybase.org/api/ui-react-dom/functions/store-components/editablevalueview/"><code>EditableValueView</code></a> component are interactive input controls for updating <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> content respectively. You can generally use them across your table views by adding the <code>editable</code> prop to your table component.</p><h3 id="the-new-inspector">The new Inspector</h3><p><img src="https://beta.tinybase.org/store-inspector.webp" alt="Inspector" title="Inspector"></p><p>The new <a href="https://beta.tinybase.org/api/ui-react-inspector/functions/development-components/inspector/"><code>Inspector</code></a> component allows you to view, understand, and edit the content of a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> in a debug web environment. Try it out in most of the demos on the site, including the <a href="https://beta.tinybase.org/demos/movie-database/">Movie Database</a> demo, pictured. This requires a debug build of the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module, which is now also included in the UMD distribution.</p><p>Also in this release, the <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/methods/result/getresulttablecellids/"><code>getResultTableCellIds</code></a> method and <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/methods/listener/addresulttablecellidslistener/"><code>addResultTableCellIdsListener</code></a> method have been added to the <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a> object. The equivalent <a href="https://beta.tinybase.org/api/ui-react/functions/queries-hooks/useresulttablecellids/"><code>useResultTableCellIds</code></a> hook and <a href="https://beta.tinybase.org/api/ui-react/functions/queries-hooks/useresulttablecellidslistener/"><code>useResultTableCellIdsListener</code></a> hook have also been added to <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module. A number of other minor React hooks have been added to support the components above.</p><p><a href="https://beta.tinybase.org/demos/">Demos</a> have been updated to demonstrate the <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module and the <a href="https://beta.tinybase.org/api/ui-react-inspector/functions/development-components/inspector/"><code>Inspector</code></a> component where appropriate.</p><p>(NB: Previous to v5.0, this component was called <code>StoreInspector</code>.)</p><h2 id="v4-0">v4.0</h2><p>This major release provides <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> modules that connect <a href="https://beta.tinybase.org/">TinyBase</a> to SQLite databases (in both browser and server contexts), and CRDT frameworks that can provide synchronization and local-first reconciliation:</p><div class="table"><table><thead><tr><th>Module</th><th>Function</th><th>Storage</th></tr></thead><tbody><tr><td><a href="https://beta.tinybase.org/api/persister-sqlite3/"><code>persister-sqlite3</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite3/functions/creation/createsqlite3persister/"><code>createSqlite3Persister</code></a></td><td>SQLite in Node, via <a href="https://github.com/TryGhost/node-sqlite3">sqlite3</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/"><code>persister-sqlite-wasm</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/functions/creation/createsqlitewasmpersister/"><code>createSqliteWasmPersister</code></a></td><td>SQLite in a browser, via <a href="https://github.com/tomayac/sqlite-wasm">sqlite-wasm</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm/"><code>persister-cr-sqlite-wasm</code></a></td><td><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm/functions/creation/createcrsqlitewasmpersister/"><code>createCrSqliteWasmPersister</code></a></td><td>SQLite CRDTs, via <a href="https://github.com/vlcn-io/cr-sqlite">cr-sqlite-wasm</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-yjs/"><code>persister-yjs</code></a></td><td><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister/"><code>createYjsPersister</code></a></td><td>Yjs CRDTs, via <a href="https://github.com/yjs/yjs">yjs</a></td></tr><tr><td><a href="https://beta.tinybase.org/api/persister-automerge/"><code>persister-automerge</code></a></td><td><a href="https://beta.tinybase.org/api/persister-sqlite-wasm/functions/creation/createsqlitewasmpersister/"><code>createSqliteWasmPersister</code></a></td><td>Automerge CRDTs, via <a href="https://github.com/automerge/automerge-repo">automerge-repo</a></td></tr></tbody></table></div><p>See the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence/">Database Persistence</a> guide for details on how to work with SQLite databases, and the <a href="https://beta.tinybase.org/guides/schemas-and-persistence/synchronizing-data/">Synchronizing Data</a> guide for more complex synchronization with the CRDT frameworks.</p><p>Take a look at the <a href="https://github.com/tinyplex/vite-tinybase-ts-react-crsqlite">vite-tinybase-ts-react-crsqlite</a> template, for example, which demonstrates Vulcan's cr-sqlite to provide persistence and synchronization via this technique.</p><h3 id="sqlite-databases">SQLite databases</h3><p>You can persist <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> data to a database with either a JSON serialization or tabular mapping. (See the <a href="https://beta.tinybase.org/api/persisters/type-aliases/configuration/databasepersisterconfig/"><code>DatabasePersisterConfig</code></a> documentation for more details).</p><p>For example, this creates a <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> object and saves and loads the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> to and from a local SQLite database. It uses an explicit tabular one-to-one mapping for the 'pets' table:</p>
|
|
197
197
|
|
|
198
198
|
```js
|
|
199
199
|
import {createSqliteWasmPersister} from 'tinybase/persisters/persister-sqlite-wasm';
|