tinybase 4.4.0 → 4.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/lib/cjs/persisters/persister-partykit-server.cjs +1 -1
  2. package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
  3. package/lib/cjs/ui-react.cjs +1 -1
  4. package/lib/cjs/ui-react.cjs.gz +0 -0
  5. package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -1
  6. package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
  7. package/lib/cjs-es6/ui-react.cjs +1 -1
  8. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  9. package/lib/debug/checkpoints.js +8 -8
  10. package/lib/debug/indexes.js +8 -8
  11. package/lib/debug/metrics.js +8 -8
  12. package/lib/debug/persisters/persister-automerge.js +23 -23
  13. package/lib/debug/persisters/persister-partykit-server.js +35 -21
  14. package/lib/debug/persisters/persister-yjs.js +23 -23
  15. package/lib/debug/queries.js +10 -10
  16. package/lib/debug/relationships.js +6 -6
  17. package/lib/debug/store.js +10 -10
  18. package/lib/debug/tinybase.js +24 -24
  19. package/lib/debug/tools.js +2 -2
  20. package/lib/debug/ui-react-dom.js +12 -12
  21. package/lib/debug/ui-react.js +56 -22
  22. package/lib/es6/persisters/persister-partykit-server.js +1 -1
  23. package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
  24. package/lib/es6/ui-react.js +1 -1
  25. package/lib/es6/ui-react.js.gz +0 -0
  26. package/lib/persisters/persister-partykit-server.js +1 -1
  27. package/lib/persisters/persister-partykit-server.js.gz +0 -0
  28. package/lib/types/metrics.d.ts +2 -2
  29. package/lib/types/persisters/persister-partykit-server.d.ts +58 -2
  30. package/lib/types/persisters/persister-remote.d.ts +6 -1
  31. package/lib/types/queries.d.ts +2 -45
  32. package/lib/types/ui-react.d.ts +53 -0
  33. package/lib/types/with-schemas/metrics.d.ts +2 -2
  34. package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +61 -0
  35. package/lib/types/with-schemas/persisters/persister-remote.d.ts +6 -1
  36. package/lib/types/with-schemas/queries.d.ts +2 -45
  37. package/lib/types/with-schemas/store.d.ts +8 -8
  38. package/lib/types/with-schemas/ui-react.d.ts +59 -0
  39. package/lib/ui-react.js +1 -1
  40. package/lib/ui-react.js.gz +0 -0
  41. package/lib/umd/persisters/persister-partykit-server.js +1 -1
  42. package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
  43. package/lib/umd/ui-react.js +1 -1
  44. package/lib/umd/ui-react.js.gz +0 -0
  45. package/lib/umd-es6/persisters/persister-partykit-server.js +1 -1
  46. package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
  47. package/lib/umd-es6/ui-react.js +1 -1
  48. package/lib/umd-es6/ui-react.js.gz +0 -0
  49. package/package.json +19 -19
  50. package/readme.md +2 -2
@@ -1 +1 @@
1
- var e,t;e=this,t=function(e){"use strict";const t=e=>typeof e,n="",r=t(n),l="t",i=(e,t)=>e.startsWith(t),o=Promise,s=e=>null==e,a=(e,t,n)=>s(e)?null==n?void 0:n():t(e),u=(e,t,n)=>e.slice(t,n),c=e=>e.length,d=e=>{return t=function*(){return o.all(e)},new Promise(((e,n)=>{var r=e=>{try{i(t.next(e))}catch(e){n(e)}},l=e=>{try{i(t.throw(e))}catch(e){n(e)}},i=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,l);i((t=t.apply(void 0,null)).next())}));var t},f=(e,t)=>e.map(t),h=(e,...t)=>e.push(...t),y=Object,v=(e=[])=>y.fromEntries(e),p=(e,t)=>f(y.entries(e),(([e,n])=>t(n,e))),g=(e,t,n)=>(((e,t)=>!s(((e,t)=>a(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=n()),e[t]),P=e=>JSON.stringify(e,((e,t)=>t instanceof Map?y.fromEntries([...t]):t)),S=JSON.parse,m=(e,n,l)=>e+n+(t(l)==r?l:P(l)),x=(e,t,n)=>{const r=c(e);return i(t,e)?[t[r],(n?S:String)(u(t,r+1))]:void 0},w=(e,t)=>((e,t)=>null==e?void 0:e.forEach(t))(e,((e,n)=>t(n,e)));var b=(e,t,n)=>new Promise(((r,l)=>{var i=e=>{try{s(n.next(e))}catch(e){l(e)}},o=e=>{try{s(n.throw(e))}catch(e){l(e)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(i,o);s((n=n.apply(e,t)).next())}));const T="hasStore",D=v(f(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),R=e=>b(void 0,null,(function*(){var t;return yield e.party.storage.get((null!=(t=e.config.storagePrefix)?t:n)+T)})),C=(e,t,r,o)=>b(void 0,null,(function*(){var a;const u=e.party.storage,f=null!=(a=e.config.storagePrefix)?a:n,y={[f+T]:1},v=[],g=[];yield d(p(t[0],((t,n)=>b(void 0,null,(function*(){return s(t)?!r&&e.canDelTable(n,o)&&((e,...t)=>e.unshift(...t))(g,O(f,l,n)):e.canSetTable(n,r,o)&&(yield d(p(t,((t,i)=>b(void 0,null,(function*(){return s(t)?!r&&e.canDelRow(n,i,o)&&h(g,O(f,l,n,i)):e.canSetRow(n,i,r,o)&&(yield d(p(t,((t,a)=>b(void 0,null,(function*(){const c=[n,i,a],d=O(f,l,...c);s(t)?!r&&e.canDelCell(...c,o)&&h(v,d):e.canSetCell(...c,t,r,o,yield u.get(d))&&(y[d]=t)}))))))}))))))}))))),yield d(p(t[1],((t,n)=>b(void 0,null,(function*(){const l=f+"v"+n;s(t)?!r&&e.canDelValue(n,o)&&h(v,l):e.canSetValue(n,t,r,o,yield u.get(l))&&(y[l]=t)}))))),0!=c(g)&&w(yield u.list(),(e=>g.every((t=>!i(e,t)||h(v,e)&&0)))),yield u.delete(v),yield u.put(y)})),O=(e,t,...n)=>m(e,t,u(P(n),1,-1)),V=(e,t,n=null)=>b(void 0,null,(function*(){var r;return new Response(n,{status:t,headers:null!=(r=e.config.responseHeaders)?r:D})}));e.TinyBasePartyKitServer=class{constructor(e){this.party=e,this.config={}}onRequest(e){return b(this,null,(function*(){var t;const r=null!=(t=this.config.storePath)?t:"/store";if(new URL(e.url).pathname.endsWith(r)){const t=yield R(this),r=yield e.text();return"PUT"==e.method?t?V(this,205):(yield C(this,S(r),!0,e),V(this,201)):V(this,200,t?P(yield(i=this,b(void 0,null,(function*(){var e;const t={},r={},o=null!=(e=i.config.storagePrefix)?e:n;return w(yield i.party.storage.list(),((e,n)=>a(x(o,e),(([e,i])=>{if(e==l){const[e,r,l]=S("["+i+"]");g(g(t,e,v),r,v)[l]=n}else"v"==e&&(r[i]=n)})))),[t,r]})))):n)}var i;return V(this,404)}))}onMessage(e,t){return b(this,null,(function*(){var r;const l=null!=(r=this.config.messagePrefix)?r:n;yield a(x(l,e,1),(e=>b(this,[e],(function*([e,n]){"s"==e&&(yield R(this))&&(yield C(this,n,!1,t),this.party.broadcast(m(l,"s",n)))}))))}))}canSetTable(e,t,n){return!0}canDelTable(e,t){return!0}canSetRow(e,t,n,r){return!0}canDelRow(e,t,n){return!0}canSetCell(e,t,n,r,l,i,o){return!0}canDelCell(e,t,n,r){return!0}canSetValue(e,t,n,r,l){return!0}canDelValue(e,t){return!0}}},"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBasePersisterPartyKitServer={});
1
+ var e,t;e=this,t=function(e){"use strict";const t=e=>typeof e,n=t(""),r="t",i=(e,t)=>e.startsWith(t),o=Promise,s=e=>null==e,l=(e,t,n)=>s(e)?null==n?void 0:n():t(e),a=(e,t,n)=>e.slice(t,n),c=e=>e.length,u=e=>{return t=function*(){return o.all(e)},new Promise(((e,n)=>{var r=e=>{try{o(t.next(e))}catch(e){n(e)}},i=e=>{try{o(t.throw(e))}catch(e){n(e)}},o=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,i);o((t=t.apply(void 0,null)).next())}));var t},d=(e,t)=>e.map(t),f=(e,...t)=>e.push(...t),h=Object,y=(e=[])=>h.fromEntries(e),g=(e,t)=>d(h.entries(e),(([e,n])=>t(n,e))),v=(e,t,n)=>(((e,t)=>!s(((e,t)=>l(e,(e=>e[t])))(e,t)))(e,t)||(e[t]=n()),e[t]),p=e=>JSON.stringify(e,((e,t)=>t instanceof Map?h.fromEntries([...t]):t)),P=JSON.parse,S=(e,r,i)=>e+r+(t(i)==n?i:p(i)),m=(e,t,n)=>{const r=c(e);return i(t,e)?[t[r],(n?P:String)(a(t,r+1))]:void 0},x=(e,t)=>((e,t)=>null==e?void 0:e.forEach(t))(e,((e,n)=>t(n,e)));var w=(e,t,n)=>new Promise(((r,i)=>{var o=e=>{try{l(n.next(e))}catch(e){i(e)}},s=e=>{try{l(n.throw(e))}catch(e){i(e)}},l=e=>e.done?r(e.value):Promise.resolve(e.value).then(o,s);l((n=n.apply(e,t)).next())}));const b="hasStore",T=y(d(["Origin","Methods","Headers"],(e=>["Access-Control-Allow-"+e,"*"]))),D=(e,...t)=>w(void 0,[e,...t],(function*(e,t=""){return!!(yield e.get(t+b))})),R=(e,...t)=>w(void 0,[e,...t],(function*(e,t=""){const n={},i={};return x(yield e.list(),((e,o)=>l(m(t,e),(([e,t])=>{if(e==r){const[e,r,i]=P("["+t+"]");v(v(n,e,y),r,y)[i]=o}else"v"==e&&(i[t]=o)})))),[n,i]})),C=(e,t,n,o)=>w(void 0,null,(function*(){const l=e.party.storage,a=e.config.storagePrefix,d={[a+b]:1},h=[],y=[];yield u(g(t[0],((t,i)=>w(void 0,null,(function*(){return s(t)?!n&&e.canDelTable(i,o)&&((e,...t)=>e.unshift(...t))(y,H(a,r,i)):e.canSetTable(i,n,o)&&(yield u(g(t,((t,c)=>w(void 0,null,(function*(){return s(t)?!n&&e.canDelRow(i,c,o)&&f(y,H(a,r,i,c)):e.canSetRow(i,c,n,o)&&(yield u(g(t,((t,u)=>w(void 0,null,(function*(){const y=[i,c,u],g=H(a,r,...y);s(t)?!n&&e.canDelCell(...y,o)&&f(h,g):e.canSetCell(...y,t,n,o,yield l.get(g))&&(d[g]=t)}))))))}))))))}))))),yield u(g(t[1],((t,r)=>w(void 0,null,(function*(){const i=a+"v"+r;s(t)?!n&&e.canDelValue(r,o)&&f(h,i):e.canSetValue(r,t,n,o,yield l.get(i))&&(d[i]=t)}))))),0!=c(y)&&x(yield l.list(),(e=>y.every((t=>!i(e,t)||f(h,e)&&0)))),yield l.delete(h),yield l.put(d)})),H=(e,t,...n)=>S(e,t,a(p(n),1,-1)),O=(e,t,n=null)=>w(void 0,null,(function*(){return new Response(n,{status:t,headers:e.config.responseHeaders})}));e.TinyBasePartyKitServer=class{constructor(e){var t,n,r,i;this.party=e,this.config={},null!=(t=this.config).storePath||(t.storePath="/store"),null!=(n=this.config).messagePrefix||(n.messagePrefix=""),null!=(r=this.config).storagePrefix||(r.storagePrefix=""),null!=(i=this.config).responseHeaders||(i.responseHeaders=T)}onRequest(e){return w(this,null,(function*(){const{party:{storage:t},config:{storePath:n,storagePrefix:r}}=this;if(new URL(e.url).pathname.endsWith(n)){const n=yield D(t,r),i=yield e.text();return"PUT"==e.method?n?O(this,205):(yield C(this,P(i),!0,e),O(this,201)):O(this,200,n?p(yield R(t,r)):"")}return O(this,404)}))}onMessage(e,t){return w(this,null,(function*(){const{party:{storage:n,broadcast:r},config:{messagePrefix:i,storagePrefix:o}}=this;yield l(m(i,e,1),(e=>w(this,[e],(function*([e,s]){"s"==e&&(yield D(n,o))&&(yield C(this,s,!1,t),r(S(i,"s",s),[t.id]))}))))}))}canSetTable(e,t,n){return!0}canDelTable(e,t){return!0}canSetRow(e,t,n,r){return!0}canDelRow(e,t,n){return!0}canSetCell(e,t,n,r,i,o,s){return!0}canDelCell(e,t,n,r){return!0}canSetValue(e,t,n,r,i){return!0}canDelValue(e,t){return!0}},e.hasStoreInStorage=D,e.loadStoreFromStorage=R},"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBasePersisterPartyKitServer={});
@@ -1 +1 @@
1
- var e,s;e=this,s=function(e,s){"use strict";const t=e=>typeof e,l="",o=t(l),r="Listener",u="Result",n="Has",d="has",i="Ids",a="Table",c=a+"s",I=a+i,p="Row",C=p+"Count",b=p+i,w="Sorted"+p+i,R="Cell",k=R+i,v="Value",g=v+"s",h=v+i,y=e=>null==e,m=(e,s,t)=>y(e)?null==t?void 0:t():s(e),L=e=>t(e)==o,f=()=>{},T=(e,s)=>e.map(s),V=Object.keys,{createContext:S,useContext:x}=s,P=S([]),O=(e,s)=>{var t;const l=x(P);return y(e)?l[s]:L(e)?((e,s)=>m(e,(e=>e[s])))(null!=(t=l[s+1])?t:{},e):e},q=(e,s)=>{const t=O(e,s);return y(e)||L(e)?t:e},B=e=>{var s;return V(null!=(s=x(P)[e])?s:{})},H=e=>q(e,0),M=e=>q(e,2),D=e=>q(e,4),j=e=>q(e,6),F=e=>q(e,8),Q=e=>q(e,10),E=e=>e.toLowerCase();E(r);const A="Transaction";E(A);const{useCallback:G,useEffect:U,useMemo:W,useLayoutEffect:z,useRef:J,useState:K}=s,N=[],X={},Y=[[],void 0,[]],Z=(e,s,t=N)=>{const l=W((()=>s(e)),[e,...t]);return U((()=>()=>l.destroy()),[l]),l},$=(e,s,t,l=N,o,r="get",u="")=>{const[,n]=K(),d=G((()=>{var o,u;return null!=(u=null==(o=null==s?void 0:s[r+e])?void 0:o.call(s,...l))?u:t}),[s,e,...l,t]),i=J();return W((()=>i.current=d()),[d]),_(u+e,s,((...e)=>{i.current=y(o)?d():e[o],n([])}),[d,o],l),i.current},_=(e,s,t,l=N,o=N,...u)=>z((()=>{var l;const n=null==(l=null==s?void 0:s["add"+e+r])?void 0:l.call(s,...o,t,...u);return()=>null==s?void 0:s.delListener(n)}),[s,e,...o,...l,...u]),ee=(e,s,t,l=N,o=f,r=N,...u)=>{const n=H(e);return G((e=>m(n,(l=>m(t(e,l),(e=>o(l["set"+s](...u,e),e)))))),[n,s,...l,...r,...u])},se=(e,s,t=f,l=N,...o)=>{const r=H(e);return G((()=>t(null==r?void 0:r["del"+s](...o))),[r,s,...l,...o])},te=(e,s,t)=>{const l=Q(e);return G((()=>null==l?void 0:l[s](t)),[l,s,t])},le=e=>$(I,H(e),N),oe=(e,s)=>$(b,H(s),N,[e]),re=(e,s,t,l=0,o,r)=>$(w,H(r),N,[e,s,t,l,o],6),ue=(e,s,t)=>$(k,H(t),N,[e,s]),ne=(e,s,t,l)=>$(R,H(l),void 0,[e,s,t],4),de=e=>$(h,H(e),N),ie=(e,s)=>$(v,H(s),void 0,[e]),ae=(e,s)=>$("Metric",M(s),void 0,[e]),ce=(e,s)=>$("SliceIds",D(s),N,[e]),Ie=(e,s,t)=>$("Slice"+b,D(t),N,[e,s]),pe=(e,s,t)=>$("RemoteRowId",j(t),void 0,[e,s]),Ce=(e,s,t)=>$("Local"+b,j(t),N,[e,s]),be=(e,s,t)=>$("Linked"+b,j(t),N,[e,s]),we=(e,s)=>$(u+b,F(s),N,[e]),Re=(e,s,t,l=0,o,r)=>$(u+w,F(r),N,[e,s,t,l,o],6),ke=(e,s,t)=>$(u+k,F(t),N,[e,s]),ve=(e,s,t,l)=>$(u+R,F(l),void 0,[e,s,t]),ge=e=>$("CheckpointIds",Q(e),Y),he=(e,s)=>$("Checkpoint",Q(s),void 0,[e]),ye=e=>te(e,"goBackward"),me=e=>te(e,"goForward"),{PureComponent:Le,Fragment:fe,createElement:Te,useCallback:Ve,useLayoutEffect:Se,useRef:xe,useState:Pe}=s,Oe=(e,...s)=>y(e)?{}:e(...s),qe=(e,s)=>[e,null==e?void 0:e.getStore(),null==e?void 0:e.getLocalTableId(s),null==e?void 0:e.getRemoteTableId(s)];var Be=Object.defineProperty,He=Object.defineProperties,Me=Object.getOwnPropertyDescriptors,De=Object.getOwnPropertySymbols,je=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable,Qe=(e,s,t)=>s in e?Be(e,s,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[s]=t,Ee=(e,s)=>{for(var t in s||(s={}))je.call(s,t)&&Qe(e,t,s[t]);if(De)for(var t of De(s))Fe.call(s,t)&&Qe(e,t,s[t]);return e},Ae=(e,s)=>He(e,Me(s)),Ge=(e,s)=>{var t={};for(var l in e)je.call(e,l)&&s.indexOf(l)<0&&(t[l]=e[l]);if(null!=e&&De)for(var l of De(e))s.indexOf(l)<0&&Fe.call(e,l)&&(t[l]=e[l]);return t};const{useMemo:Ue}=s,We=({tableId:e,store:s,rowComponent:t=Ye,getRowComponentProps:l,customCellIds:o,separator:r,debugIds:u},n)=>Ne(T(n,(r=>Te(t,Ae(Ee({},Oe(l,r)),{key:r,tableId:e,rowId:r,customCellIds:o,store:s,debugIds:u})))),r,u,e),ze=({queryId:e,queries:s,resultRowComponent:t=ss,getResultRowComponentProps:l,separator:o,debugIds:r},u)=>Ne(T(u,(o=>Te(t,Ae(Ee({},Oe(l,o)),{key:o,queryId:e,rowId:o,queries:s,debugIds:r})))),o,r,e),Je=({relationshipId:e,relationships:s,rowComponent:t=Ye,getRowComponentProps:l,separator:o,debugIds:r},u,n)=>{const[d,i,a]=qe(j(s),e),c=u(e,n,d);return Ne(T(c,(e=>Te(t,Ae(Ee({},Oe(l,e)),{key:e,tableId:a,rowId:e,store:i,debugIds:r})))),o,r,n)},Ke=e=>({checkpoints:s,checkpointComponent:t=ts,getCheckpointComponentProps:l,separator:o,debugIds:r})=>{const u=Q(s);return Ne(T(e(ge(u)),(e=>Te(t,Ae(Ee({},Oe(l,e)),{key:e,checkpoints:u,checkpointId:e,debugIds:r})))),o)},Ne=(e,s,t,l)=>{const o=y(s)||!Array.isArray(e)?e:T(e,((e,t)=>t>0?[s,e]:e));return t?[l,":{",o,"}"]:o},Xe=({tableId:e,rowId:s,cellId:t,store:o,debugIds:r})=>{var u;return Ne(l+(null!=(u=ne(e,s,t,o))?u:l),void 0,r,t)},Ye=({tableId:e,rowId:s,store:t,cellComponent:l=Xe,getCellComponentProps:o,customCellIds:r,separator:u,debugIds:n})=>Ne(T(((e,s,t,l)=>{const o=ue(s,t,l);return null!=e?e:o})(r,e,s,t),(r=>Te(l,Ae(Ee({},Oe(o,r)),{key:r,tableId:e,rowId:s,cellId:r,store:t,debugIds:n})))),u,n,s),Ze=e=>We(e,oe(e.tableId,e.store)),$e=({valueId:e,store:s,debugIds:t})=>{var o;return Ne(l+(null!=(o=ie(e,s))?o:l),void 0,t,e)},_e=({indexId:e,sliceId:s,indexes:t,rowComponent:l=Ye,getRowComponentProps:o,separator:r,debugIds:u})=>{const[n,d,i]=((e,s)=>[e,null==e?void 0:e.getStore(),null==e?void 0:e.getTableId(s)])(D(t),e),a=Ie(e,s,n);return Ne(T(a,(e=>Te(l,Ae(Ee({},Oe(o,e)),{key:e,tableId:i,rowId:e,store:d,debugIds:u})))),r,u,s)},es=({queryId:e,rowId:s,cellId:t,queries:o,debugIds:r})=>{var u;return Ne(l+(null!=(u=ve(e,s,t,o))?u:l),void 0,r,t)},ss=({queryId:e,rowId:s,queries:t,resultCellComponent:l=es,getResultCellComponentProps:o,separator:r,debugIds:u})=>Ne(T(ke(e,s,t),(r=>Te(l,Ae(Ee({},Oe(o,r)),{key:r,queryId:e,rowId:s,cellId:r,queries:t,debugIds:u})))),r,u,s),ts=({checkpoints:e,checkpointId:s,debugIds:t})=>{var o;return Ne(null!=(o=he(s,e))?o:l,void 0,t,s)},ls=Ke((e=>e[0])),os=Ke((e=>y(e[1])?[]:[e[1]])),rs=Ke((e=>e[2]));e.BackwardCheckpointsView=ls,e.CellView=Xe,e.CheckpointView=ts,e.CurrentCheckpointView=os,e.ForwardCheckpointsView=rs,e.IndexView=({indexId:e,indexes:s,sliceComponent:t=_e,getSliceComponentProps:l,separator:o,debugIds:r})=>Ne(T(ce(e,s),(o=>Te(t,Ae(Ee({},Oe(l,o)),{key:o,indexId:e,sliceId:o,indexes:s,debugIds:r})))),o,r,e),e.LinkedRowsView=e=>Je(e,be,e.firstRowId),e.LocalRowsView=e=>Je(e,Ce,e.remoteRowId),e.MetricView=({metricId:e,metrics:s,debugIds:t})=>{var o;return Ne(null!=(o=ae(e,s))?o:l,void 0,t,e)},e.Provider=({store:e,storesById:t,metrics:l,metricsById:o,indexes:r,indexesById:u,relationships:n,relationshipsById:d,queries:i,queriesById:a,checkpoints:c,checkpointsById:I,children:p})=>{const C=s.useContext(P);return Te(P.Provider,{value:Ue((()=>[null!=e?e:C[0],Ee(Ee({},C[1]),t),null!=l?l:C[2],Ee(Ee({},C[3]),o),null!=r?r:C[4],Ee(Ee({},C[5]),u),null!=n?n:C[6],Ee(Ee({},C[7]),d),null!=i?i:C[8],Ee(Ee({},C[9]),a),null!=c?c:C[10],Ee(Ee({},C[11]),I)]),[e,t,l,o,r,u,n,d,i,a,c,I,C])},p)},e.RemoteRowView=({relationshipId:e,localRowId:s,relationships:t,rowComponent:l=Ye,getRowComponentProps:o,debugIds:r})=>{const[u,n,,d]=qe(j(t),e),i=pe(e,s,u);return Ne(y(d)||y(i)?null:Te(l,Ae(Ee({},Oe(o,i)),{key:i,tableId:d,rowId:i,store:n,debugIds:r})),void 0,r,s)},e.ResultCellView=es,e.ResultRowView=ss,e.ResultSortedTableView=e=>{var s=e,{cellId:t,descending:l,offset:o,limit:r}=s,u=Ge(s,["cellId","descending","offset","limit"]);return ze(u,Re(u.queryId,t,l,o,r,u.queries))},e.ResultTableView=e=>ze(e,we(e.queryId,e.queries)),e.RowView=Ye,e.SliceView=_e,e.SortedTableView=e=>{var s=e,{cellId:t,descending:l,offset:o,limit:r}=s,u=Ge(s,["cellId","descending","offset","limit"]);return We(u,re(u.tableId,t,l,o,r,u.store))},e.TableView=Ze,e.TablesView=({store:e,tableComponent:s=Ze,getTableComponentProps:t,separator:l,debugIds:o})=>Ne(T(le(e),(l=>Te(s,Ae(Ee({},Oe(t,l)),{key:l,tableId:l,store:e,debugIds:o})))),l),e.ValueView=$e,e.ValuesView=({store:e,valueComponent:s=$e,getValueComponentProps:t,separator:l,debugIds:o})=>Ne(T(de(e),(l=>Te(s,Ae(Ee({},Oe(t,l)),{key:l,valueId:l,store:e,debugIds:o})))),l),e.useAddRowCallback=(e,s,t=N,l,o=f,r=N,u=!0)=>{const n=H(l);return G((t=>m(n,(l=>m(s(t,l),(s=>o(l.addRow(e,s,u),l,s)))))),[n,e,...t,...r,u])},e.useCell=ne,e.useCellIds=ue,e.useCellIdsListener=(e,s,t,l,o,r)=>_(k,H(r),t,l,[e,s],o),e.useCellListener=(e,s,t,l,o,r,u)=>_(R,H(u),l,o,[e,s,t],r),e.useCheckpoint=he,e.useCheckpointIds=ge,e.useCheckpointIdsListener=(e,s,t)=>_("CheckpointIds",Q(t),e,s),e.useCheckpointListener=(e,s,t,l)=>_("Checkpoint",Q(l),s,t,[e]),e.useCheckpoints=e=>O(e,10),e.useCheckpointsIds=()=>B(11),e.useCheckpointsOrCheckpointsById=Q,e.useCreateCheckpoints=(e,s,t)=>Z(e,s,t),e.useCreateIndexes=(e,s,t)=>Z(e,s,t),e.useCreateMetrics=(e,s,t)=>Z(e,s,t),e.useCreatePersister=(e,s,t=N,l,o=N,r,u=N)=>{const[,n]=K(),d=W((()=>s(e)),[e,...t]);return U((()=>{var e;return e=function*(){l&&(yield l(d),n([]))},new Promise(((s,t)=>{var l=s=>{try{r(e.next(s))}catch(e){t(e)}},o=s=>{try{r(e.throw(s))}catch(e){t(e)}},r=e=>e.done?s(e.value):Promise.resolve(e.value).then(l,o);r((e=e.apply(void 0,null)).next())})),()=>{null==d||d.destroy(),null==r||r(d)}}),[d,...o,...u]),d},e.useCreateQueries=(e,s,t)=>Z(e,s,t),e.useCreateRelationships=(e,s,t)=>Z(e,s,t),e.useCreateStore=(e,s=N)=>W(e,s),e.useDelCellCallback=(e,s,t,l,o,r,u)=>se(o,R,r,u,e,s,t,l),e.useDelRowCallback=(e,s,t,l,o)=>se(t,p,l,o,e,s),e.useDelTableCallback=(e,s,t,l)=>se(s,a,t,l,e),e.useDelTablesCallback=(e,s,t)=>se(e,c,s,t),e.useDelValueCallback=(e,s,t,l)=>se(s,v,t,l,e),e.useDelValuesCallback=(e,s,t)=>se(e,g,s,t),e.useDidFinishTransactionListener=(e,s,t)=>_("DidFinish"+A,H(t),e,s),e.useGoBackwardCallback=ye,e.useGoForwardCallback=me,e.useGoToCallback=(e,s=N,t,l=f,o=N)=>{const r=Q(t);return G((s=>m(r,(t=>m(e(s),(e=>l(t.goTo(e),e)))))),[r,...s,...o])},e.useHasCell=(e,s,t,l)=>$(R,H(l),!1,[e,s,t],4,d,n),e.useHasCellListener=(e,s,t,l,o,r,u)=>_(n+R,H(u),l,o,[e,s,t],r),e.useHasRow=(e,s,t)=>$(p,H(t),!1,[e,s],3,d,n),e.useHasRowListener=(e,s,t,l,o,r)=>_(n+p,H(r),t,l,[e,s],o),e.useHasTable=(e,s)=>$(a,H(s),!1,[e],2,d,n),e.useHasTableCell=(e,s,t)=>$(a+R,H(t),!1,[e,s],3,d,n),e.useHasTableCellListener=(e,s,t,l,o,r)=>_(n+a+R,H(r),t,l,[e,s],o),e.useHasTableListener=(e,s,t,l,o)=>_(n+a,H(o),s,t,[e],l),e.useHasTables=e=>$(c,H(e),!1,[],1,d,n),e.useHasTablesListener=(e,s,t,l)=>_(n+c,H(l),e,s,[],t),e.useHasValue=(e,s)=>$(v,H(s),!1,[e],2,d,n),e.useHasValueListener=(e,s,t,l,o)=>_(n+v,H(o),s,t,[e],l),e.useHasValues=e=>$(g,H(e),!1,[],1,d,n),e.useHasValuesListener=(e,s,t,l)=>_(n+g,H(l),e,s,[],t),e.useIndexIds=e=>$("IndexIds",D(e),N),e.useIndexes=e=>O(e,4),e.useIndexesIds=()=>B(5),e.useIndexesOrIndexesById=D,e.useLinkedRowIds=be,e.useLinkedRowIdsListener=(e,s,t,l,o)=>_("Linked"+b,j(o),t,l,[e,s]),e.useLocalRowIds=Ce,e.useLocalRowIdsListener=(e,s,t,l,o)=>_("Local"+b,j(o),t,l,[e,s]),e.useMetric=ae,e.useMetricIds=e=>$("MetricIds",M(e),N),e.useMetricListener=(e,s,t,l)=>_("Metric",M(l),s,t,[e]),e.useMetrics=e=>O(e,2),e.useMetricsIds=()=>B(3),e.useMetricsOrMetricsById=M,e.useQueries=e=>O(e,8),e.useQueriesIds=()=>B(9),e.useQueriesOrQueriesById=F,e.useQueryIds=e=>$("QueryIds",F(e),N),e.useRedoInformation=e=>{var s;const t=Q(e),[,,[o]]=ge(t);return[!y(o),me(t),o,null!=(s=m(o,(e=>null==t?void 0:t.getCheckpoint(e))))?s:l]},e.useRelationshipIds=e=>$("RelationshipIds",j(e),N),e.useRelationships=e=>O(e,6),e.useRelationshipsIds=()=>B(7),e.useRelationshipsOrRelationshipsById=j,e.useRemoteRowId=pe,e.useRemoteRowIdListener=(e,s,t,l,o)=>_("RemoteRowId",j(o),t,l,[e,s]),e.useResultCell=ve,e.useResultCellIds=ke,e.useResultCellIdsListener=(e,s,t,l,o)=>_(u+k,F(o),t,l,[e,s]),e.useResultCellListener=(e,s,t,l,o,r)=>_(u+R,F(r),l,o,[e,s,t]),e.useResultRow=(e,s,t)=>$(u+p,F(t),X,[e,s]),e.useResultRowCount=(e,s)=>$(u+C,F(s),0,[e]),e.useResultRowCountListener=(e,s,t,l)=>_(u+C,F(l),s,t,[e]),e.useResultRowIds=we,e.useResultRowIdsListener=(e,s,t,l)=>_(u+b,F(l),s,t,[e]),e.useResultRowListener=(e,s,t,l,o)=>_(u+p,F(o),t,l,[e,s]),e.useResultSortedRowIds=Re,e.useResultSortedRowIdsListener=(e,s,t,l,o,r,n,d)=>_(u+w,F(d),r,n,[e,s,t,l,o]),e.useResultTable=(e,s)=>$(u+a,F(s),X,[e]),e.useResultTableCellIds=(e,s)=>$(u+a+k,F(s),N,[e]),e.useResultTableCellIdsListener=(e,s,t,l)=>_(u+a+k,F(l),s,t,[e]),e.useResultTableListener=(e,s,t,l)=>_(u+a,F(l),s,t,[e]),e.useRow=(e,s,t)=>$(p,H(t),X,[e,s]),e.useRowCount=(e,s)=>$(C,H(s),0,[e]),e.useRowCountListener=(e,s,t,l,o)=>_(C,H(o),s,t,[e],l),e.useRowIds=oe,e.useRowIdsListener=(e,s,t,l,o)=>_(b,H(o),s,t,[e],l),e.useRowListener=(e,s,t,l,o,r)=>_(p,H(r),t,l,[e,s],o),e.useSetCellCallback=(e,s,t,l,o,r,u,n)=>ee(r,R,l,o,u,n,e,s,t),e.useSetCheckpointCallback=(e=f,s=N,t,l=f,o=N)=>{const r=Q(t);return G((s=>m(r,(t=>{const o=e(s);l(t.addCheckpoint(o),t,o)}))),[r,...s,...o])},e.useSetPartialRowCallback=(e,s,t,l,o,r,u)=>ee(o,"PartialRow",t,l,r,u,e,s),e.useSetPartialValuesCallback=(e,s,t,l,o)=>ee(t,"PartialValues",e,s,l,o),e.useSetRowCallback=(e,s,t,l,o,r,u)=>ee(o,p,t,l,r,u,e,s),e.useSetTableCallback=(e,s,t,l,o,r)=>ee(l,a,s,t,o,r,e),e.useSetTablesCallback=(e,s,t,l,o)=>ee(t,c,e,s,l,o),e.useSetValueCallback=(e,s,t,l,o,r)=>ee(l,v,s,t,o,r,e),e.useSetValuesCallback=(e,s,t,l,o)=>ee(t,g,e,s,l,o),e.useSliceIds=ce,e.useSliceIdsListener=(e,s,t,l)=>_("SliceIds",D(l),s,t,[e]),e.useSliceRowIds=Ie,e.useSliceRowIdsListener=(e,s,t,l,o)=>_("Slice"+b,D(o),t,l,[e,s]),e.useSortedRowIds=re,e.useSortedRowIdsListener=(e,s,t,l,o,r,u,n,d)=>_(w,H(d),r,u,[e,s,t,l,o],n),e.useStartTransactionListener=(e,s,t)=>_("Start"+A,H(t),e,s),e.useStore=e=>O(e,0),e.useStoreIds=()=>B(1),e.useStoreOrStoreById=H,e.useTable=(e,s)=>$(a,H(s),X,[e]),e.useTableCellIds=(e,s)=>$(a+k,H(s),N,[e]),e.useTableCellIdsListener=(e,s,t,l,o)=>_(a+k,H(o),s,t,[e],l),e.useTableIds=le,e.useTableIdsListener=(e,s,t,l)=>_(I,H(l),e,s,N,t),e.useTableListener=(e,s,t,l,o)=>_(a,H(o),s,t,[e],l),e.useTables=e=>$(c,H(e),X),e.useTablesListener=(e,s,t,l)=>_(c,H(l),e,s,N,t),e.useUndoInformation=e=>{var s;const t=Q(e),[o,r]=ge(t);return[(u=o,!(0==u.length)),ye(t),r,null!=(s=m(r,(e=>null==t?void 0:t.getCheckpoint(e))))?s:l];var u},e.useValue=ie,e.useValueIds=de,e.useValueIdsListener=(e,s,t,l)=>_(h,H(l),e,s,N,t),e.useValueListener=(e,s,t,l,o)=>_(v,H(o),s,t,[e],l),e.useValues=e=>$(g,H(e),X),e.useValuesListener=(e,s,t,l)=>_(g,H(l),e,s,N,t),e.useWillFinishTransactionListener=(e,s,t)=>_("WillFinish"+A,H(t),e,s)},"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBaseUiReact={},e.React);
1
+ var e,s;e=this,s=function(e,s){"use strict";const t=e=>typeof e,l="",o=t(l),r="Listener",u="Result",n="Has",d="has",i="Ids",a="Table",c=a+"s",I=a+i,C="Row",p=C+"Count",b=C+i,w="Sorted"+C+i,R="Cell",k=R+i,v="Value",g=v+"s",h=v+i,y=e=>null==e,m=(e,s,t)=>y(e)?null==t?void 0:t():s(e),L=e=>t(e)==o,f=()=>{},T=(e,s)=>e.map(s),V=Object.keys,S=(e,s)=>m(e,(e=>e[s])),{createContext:P,useContext:x,useEffect:O}=s,q=P([]),B=(e,s)=>{var t;const l=x(q);return y(e)?l[s]:L(e)?S(null!=(t=l[s+1])?t:{},e):e},H=(e,s)=>{const t=B(e,s);return y(e)||L(e)?t:e},M=e=>{var s;return V(null!=(s=x(q)[e])?s:{})},D=e=>H(e,0),j=e=>H(e,2),F=e=>H(e,4),Q=e=>H(e,6),E=e=>H(e,8),A=e=>H(e,10),G=e=>e.toLowerCase();G(r);const U="Transaction";G(U);const{useCallback:W,useEffect:z,useMemo:J,useLayoutEffect:K,useRef:N,useState:X}=s,Y=[],Z={},$=[[],void 0,[]],_=(e,s,t=Y)=>{const l=J((()=>s(e)),[e,...t]);return z((()=>()=>l.destroy()),[l]),l},ee=(e,s,t,l=Y,o,r="get",u="")=>{const[,n]=X(),d=W((()=>{var o,u;return null!=(u=null==(o=null==s?void 0:s[r+e])?void 0:o.call(s,...l))?u:t}),[s,e,...l,t]),i=N();return J((()=>i.current=d()),[d]),se(u+e,s,((...e)=>{i.current=y(o)?d():e[o],n([])}),[d,o],l),i.current},se=(e,s,t,l=Y,o=Y,...u)=>K((()=>{var l;const n=null==(l=null==s?void 0:s["add"+e+r])?void 0:l.call(s,...o,t,...u);return()=>null==s?void 0:s.delListener(n)}),[s,e,...o,...l,...u]),te=(e,s,t,l=Y,o=f,r=Y,...u)=>{const n=D(e);return W((e=>m(n,(l=>m(t(e,l),(e=>o(l["set"+s](...u,e),e)))))),[n,s,...l,...r,...u])},le=(e,s,t=f,l=Y,...o)=>{const r=D(e);return W((()=>t(null==r?void 0:r["del"+s](...o))),[r,s,...l,...o])},oe=(e,s,t)=>{const l=A(e);return W((()=>null==l?void 0:l[s](t)),[l,s,t])},re=e=>ee(I,D(e),Y),ue=(e,s)=>ee(b,D(s),Y,[e]),ne=(e,s,t,l=0,o,r)=>ee(w,D(r),Y,[e,s,t,l,o],6),de=(e,s,t)=>ee(k,D(t),Y,[e,s]),ie=(e,s,t,l)=>ee(R,D(l),void 0,[e,s,t],4),ae=e=>ee(h,D(e),Y),ce=(e,s)=>ee(v,D(s),void 0,[e]),Ie=(e,s)=>ee("Metric",j(s),void 0,[e]),Ce=(e,s)=>ee("SliceIds",F(s),Y,[e]),pe=(e,s,t)=>ee("Slice"+b,F(t),Y,[e,s]),be=(e,s,t)=>ee("RemoteRowId",Q(t),void 0,[e,s]),we=(e,s,t)=>ee("Local"+b,Q(t),Y,[e,s]),Re=(e,s,t)=>ee("Linked"+b,Q(t),Y,[e,s]),ke=(e,s)=>ee(u+b,E(s),Y,[e]),ve=(e,s,t,l=0,o,r)=>ee(u+w,E(r),Y,[e,s,t,l,o],6),ge=(e,s,t)=>ee(u+k,E(t),Y,[e,s]),he=(e,s,t,l)=>ee(u+R,E(l),void 0,[e,s,t]),ye=e=>ee("CheckpointIds",A(e),$),me=(e,s)=>ee("Checkpoint",A(s),void 0,[e]),Le=e=>oe(e,"goBackward"),fe=e=>oe(e,"goForward"),{PureComponent:Te,Fragment:Ve,createElement:Se,useCallback:Pe,useLayoutEffect:xe,useRef:Oe,useState:qe}=s,Be=(e,...s)=>y(e)?{}:e(...s),He=(e,s)=>[e,null==e?void 0:e.getStore(),null==e?void 0:e.getLocalTableId(s),null==e?void 0:e.getRemoteTableId(s)];var Me=Object.defineProperty,De=Object.defineProperties,je=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertySymbols,Qe=Object.prototype.hasOwnProperty,Ee=Object.prototype.propertyIsEnumerable,Ae=(e,s,t)=>s in e?Me(e,s,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[s]=t,Ge=(e,s)=>{for(var t in s||(s={}))Qe.call(s,t)&&Ae(e,t,s[t]);if(Fe)for(var t of Fe(s))Ee.call(s,t)&&Ae(e,t,s[t]);return e},Ue=(e,s)=>De(e,je(s)),We=(e,s)=>{var t={};for(var l in e)Qe.call(e,l)&&s.indexOf(l)<0&&(t[l]=e[l]);if(null!=e&&Fe)for(var l of Fe(e))s.indexOf(l)<0&&Ee.call(e,l)&&(t[l]=e[l]);return t};const{useCallback:ze,useContext:Je,useMemo:Ke,useState:Ne}=s,Xe=({tableId:e,store:s,rowComponent:t=ss,getRowComponentProps:l,customCellIds:o,separator:r,debugIds:u},n)=>_e(T(n,(r=>Se(t,Ue(Ge({},Be(l,r)),{key:r,tableId:e,rowId:r,customCellIds:o,store:s,debugIds:u})))),r,u,e),Ye=({queryId:e,queries:s,resultRowComponent:t=us,getResultRowComponentProps:l,separator:o,debugIds:r},u)=>_e(T(u,(o=>Se(t,Ue(Ge({},Be(l,o)),{key:o,queryId:e,rowId:o,queries:s,debugIds:r})))),o,r,e),Ze=({relationshipId:e,relationships:s,rowComponent:t=ss,getRowComponentProps:l,separator:o,debugIds:r},u,n)=>{const[d,i,a]=He(Q(s),e),c=u(e,n,d);return _e(T(c,(e=>Se(t,Ue(Ge({},Be(l,e)),{key:e,tableId:a,rowId:e,store:i,debugIds:r})))),o,r,n)},$e=e=>({checkpoints:s,checkpointComponent:t=ns,getCheckpointComponentProps:l,separator:o,debugIds:r})=>{const u=A(s);return _e(T(e(ye(u)),(e=>Se(t,Ue(Ge({},Be(l,e)),{key:e,checkpoints:u,checkpointId:e,debugIds:r})))),o)},_e=(e,s,t,l)=>{const o=y(s)||!Array.isArray(e)?e:T(e,((e,t)=>t>0?[s,e]:e));return t?[l,":{",o,"}"]:o},es=({tableId:e,rowId:s,cellId:t,store:o,debugIds:r})=>{var u;return _e(l+(null!=(u=ie(e,s,t,o))?u:l),void 0,r,t)},ss=({tableId:e,rowId:s,store:t,cellComponent:l=es,getCellComponentProps:o,customCellIds:r,separator:u,debugIds:n})=>_e(T(((e,s,t,l)=>{const o=de(s,t,l);return null!=e?e:o})(r,e,s,t),(r=>Se(l,Ue(Ge({},Be(o,r)),{key:r,tableId:e,rowId:s,cellId:r,store:t,debugIds:n})))),u,n,s),ts=e=>Xe(e,ue(e.tableId,e.store)),ls=({valueId:e,store:s,debugIds:t})=>{var o;return _e(l+(null!=(o=ce(e,s))?o:l),void 0,t,e)},os=({indexId:e,sliceId:s,indexes:t,rowComponent:l=ss,getRowComponentProps:o,separator:r,debugIds:u})=>{const[n,d,i]=((e,s)=>[e,null==e?void 0:e.getStore(),null==e?void 0:e.getTableId(s)])(F(t),e),a=pe(e,s,n);return _e(T(a,(e=>Se(l,Ue(Ge({},Be(o,e)),{key:e,tableId:i,rowId:e,store:d,debugIds:u})))),r,u,s)},rs=({queryId:e,rowId:s,cellId:t,queries:o,debugIds:r})=>{var u;return _e(l+(null!=(u=he(e,s,t,o))?u:l),void 0,r,t)},us=({queryId:e,rowId:s,queries:t,resultCellComponent:l=rs,getResultCellComponentProps:o,separator:r,debugIds:u})=>_e(T(ge(e,s,t),(r=>Se(l,Ue(Ge({},Be(o,r)),{key:r,queryId:e,rowId:s,cellId:r,queries:t,debugIds:u})))),r,u,s),ns=({checkpoints:e,checkpointId:s,debugIds:t})=>{var o;return _e(null!=(o=me(s,e))?o:l,void 0,t,s)},ds=$e((e=>e[0])),is=$e((e=>y(e[1])?[]:[e[1]])),as=$e((e=>e[2]));e.BackwardCheckpointsView=ds,e.CellView=es,e.CheckpointView=ns,e.CurrentCheckpointView=is,e.ForwardCheckpointsView=as,e.IndexView=({indexId:e,indexes:s,sliceComponent:t=os,getSliceComponentProps:l,separator:o,debugIds:r})=>_e(T(Ce(e,s),(o=>Se(t,Ue(Ge({},Be(l,o)),{key:o,indexId:e,sliceId:o,indexes:s,debugIds:r})))),o,r,e),e.LinkedRowsView=e=>Ze(e,Re,e.firstRowId),e.LocalRowsView=e=>Ze(e,we,e.remoteRowId),e.MetricView=({metricId:e,metrics:s,debugIds:t})=>{var o;return _e(null!=(o=Ie(e,s))?o:l,void 0,t,e)},e.Provider=({store:e,storesById:s,metrics:t,metricsById:l,indexes:o,indexesById:r,relationships:u,relationshipsById:n,queries:d,queriesById:i,checkpoints:a,checkpointsById:c,children:I})=>{const C=Je(q),[p,b]=Ne({}),w=ze(((e,s)=>b((t=>S(t,e)==s?t:Ue(Ge({},t),{[e]:s})))),[]),R=ze((e=>b((s=>Ge({},((e,s)=>(delete e[s],e))(s,e))))),[]);return Se(q.Provider,{value:Ke((()=>[null!=e?e:C[0],Ge(Ge(Ge({},C[1]),s),p),null!=t?t:C[2],Ge(Ge({},C[3]),l),null!=o?o:C[4],Ge(Ge({},C[5]),r),null!=u?u:C[6],Ge(Ge({},C[7]),n),null!=d?d:C[8],Ge(Ge({},C[9]),i),null!=a?a:C[10],Ge(Ge({},C[11]),c),w,R]),[e,s,p,t,l,o,r,u,n,d,i,a,c,C,w,R])},I)},e.RemoteRowView=({relationshipId:e,localRowId:s,relationships:t,rowComponent:l=ss,getRowComponentProps:o,debugIds:r})=>{const[u,n,,d]=He(Q(t),e),i=be(e,s,u);return _e(y(d)||y(i)?null:Se(l,Ue(Ge({},Be(o,i)),{key:i,tableId:d,rowId:i,store:n,debugIds:r})),void 0,r,s)},e.ResultCellView=rs,e.ResultRowView=us,e.ResultSortedTableView=e=>{var s=e,{cellId:t,descending:l,offset:o,limit:r}=s,u=We(s,["cellId","descending","offset","limit"]);return Ye(u,ve(u.queryId,t,l,o,r,u.queries))},e.ResultTableView=e=>Ye(e,ke(e.queryId,e.queries)),e.RowView=ss,e.SliceView=os,e.SortedTableView=e=>{var s=e,{cellId:t,descending:l,offset:o,limit:r}=s,u=We(s,["cellId","descending","offset","limit"]);return Xe(u,ne(u.tableId,t,l,o,r,u.store))},e.TableView=ts,e.TablesView=({store:e,tableComponent:s=ts,getTableComponentProps:t,separator:l,debugIds:o})=>_e(T(re(e),(l=>Se(s,Ue(Ge({},Be(t,l)),{key:l,tableId:l,store:e,debugIds:o})))),l),e.ValueView=ls,e.ValuesView=({store:e,valueComponent:s=ls,getValueComponentProps:t,separator:l,debugIds:o})=>_e(T(ae(e),(l=>Se(s,Ue(Ge({},Be(t,l)),{key:l,valueId:l,store:e,debugIds:o})))),l),e.useAddRowCallback=(e,s,t=Y,l,o=f,r=Y,u=!0)=>{const n=D(l);return W((t=>m(n,(l=>m(s(t,l),(s=>o(l.addRow(e,s,u),l,s)))))),[n,e,...t,...r,u])},e.useCell=ie,e.useCellIds=de,e.useCellIdsListener=(e,s,t,l,o,r)=>se(k,D(r),t,l,[e,s],o),e.useCellListener=(e,s,t,l,o,r,u)=>se(R,D(u),l,o,[e,s,t],r),e.useCheckpoint=me,e.useCheckpointIds=ye,e.useCheckpointIdsListener=(e,s,t)=>se("CheckpointIds",A(t),e,s),e.useCheckpointListener=(e,s,t,l)=>se("Checkpoint",A(l),s,t,[e]),e.useCheckpoints=e=>B(e,10),e.useCheckpointsIds=()=>M(11),e.useCheckpointsOrCheckpointsById=A,e.useCreateCheckpoints=(e,s,t)=>_(e,s,t),e.useCreateIndexes=(e,s,t)=>_(e,s,t),e.useCreateMetrics=(e,s,t)=>_(e,s,t),e.useCreatePersister=(e,s,t=Y,l,o=Y,r,u=Y)=>{const[,n]=X(),d=J((()=>s(e)),[e,...t]);return z((()=>{var e;return e=function*(){l&&(yield l(d),n([]))},new Promise(((s,t)=>{var l=s=>{try{r(e.next(s))}catch(e){t(e)}},o=s=>{try{r(e.throw(s))}catch(e){t(e)}},r=e=>e.done?s(e.value):Promise.resolve(e.value).then(l,o);r((e=e.apply(void 0,null)).next())})),()=>{null==d||d.destroy(),null==r||r(d)}}),[d,...o,...u]),d},e.useCreateQueries=(e,s,t)=>_(e,s,t),e.useCreateRelationships=(e,s,t)=>_(e,s,t),e.useCreateStore=(e,s=Y)=>J(e,s),e.useDelCellCallback=(e,s,t,l,o,r,u)=>le(o,R,r,u,e,s,t,l),e.useDelRowCallback=(e,s,t,l,o)=>le(t,C,l,o,e,s),e.useDelTableCallback=(e,s,t,l)=>le(s,a,t,l,e),e.useDelTablesCallback=(e,s,t)=>le(e,c,s,t),e.useDelValueCallback=(e,s,t,l)=>le(s,v,t,l,e),e.useDelValuesCallback=(e,s,t)=>le(e,g,s,t),e.useDidFinishTransactionListener=(e,s,t)=>se("DidFinish"+U,D(t),e,s),e.useGoBackwardCallback=Le,e.useGoForwardCallback=fe,e.useGoToCallback=(e,s=Y,t,l=f,o=Y)=>{const r=A(t);return W((s=>m(r,(t=>m(e(s),(e=>l(t.goTo(e),e)))))),[r,...s,...o])},e.useHasCell=(e,s,t,l)=>ee(R,D(l),!1,[e,s,t],4,d,n),e.useHasCellListener=(e,s,t,l,o,r,u)=>se(n+R,D(u),l,o,[e,s,t],r),e.useHasRow=(e,s,t)=>ee(C,D(t),!1,[e,s],3,d,n),e.useHasRowListener=(e,s,t,l,o,r)=>se(n+C,D(r),t,l,[e,s],o),e.useHasTable=(e,s)=>ee(a,D(s),!1,[e],2,d,n),e.useHasTableCell=(e,s,t)=>ee(a+R,D(t),!1,[e,s],3,d,n),e.useHasTableCellListener=(e,s,t,l,o,r)=>se(n+a+R,D(r),t,l,[e,s],o),e.useHasTableListener=(e,s,t,l,o)=>se(n+a,D(o),s,t,[e],l),e.useHasTables=e=>ee(c,D(e),!1,[],1,d,n),e.useHasTablesListener=(e,s,t,l)=>se(n+c,D(l),e,s,[],t),e.useHasValue=(e,s)=>ee(v,D(s),!1,[e],2,d,n),e.useHasValueListener=(e,s,t,l,o)=>se(n+v,D(o),s,t,[e],l),e.useHasValues=e=>ee(g,D(e),!1,[],1,d,n),e.useHasValuesListener=(e,s,t,l)=>se(n+g,D(l),e,s,[],t),e.useIndexIds=e=>ee("IndexIds",F(e),Y),e.useIndexes=e=>B(e,4),e.useIndexesIds=()=>M(5),e.useIndexesOrIndexesById=F,e.useLinkedRowIds=Re,e.useLinkedRowIdsListener=(e,s,t,l,o)=>se("Linked"+b,Q(o),t,l,[e,s]),e.useLocalRowIds=we,e.useLocalRowIdsListener=(e,s,t,l,o)=>se("Local"+b,Q(o),t,l,[e,s]),e.useMetric=Ie,e.useMetricIds=e=>ee("MetricIds",j(e),Y),e.useMetricListener=(e,s,t,l)=>se("Metric",j(l),s,t,[e]),e.useMetrics=e=>B(e,2),e.useMetricsIds=()=>M(3),e.useMetricsOrMetricsById=j,e.useProvideStore=(e,s)=>{const{12:t,13:l}=x(q);O((()=>(null==t||t(e,s),()=>null==l?void 0:l(e))),[t,e,s,l])},e.useQueries=e=>B(e,8),e.useQueriesIds=()=>M(9),e.useQueriesOrQueriesById=E,e.useQueryIds=e=>ee("QueryIds",E(e),Y),e.useRedoInformation=e=>{var s;const t=A(e),[,,[o]]=ye(t);return[!y(o),fe(t),o,null!=(s=m(o,(e=>null==t?void 0:t.getCheckpoint(e))))?s:l]},e.useRelationshipIds=e=>ee("RelationshipIds",Q(e),Y),e.useRelationships=e=>B(e,6),e.useRelationshipsIds=()=>M(7),e.useRelationshipsOrRelationshipsById=Q,e.useRemoteRowId=be,e.useRemoteRowIdListener=(e,s,t,l,o)=>se("RemoteRowId",Q(o),t,l,[e,s]),e.useResultCell=he,e.useResultCellIds=ge,e.useResultCellIdsListener=(e,s,t,l,o)=>se(u+k,E(o),t,l,[e,s]),e.useResultCellListener=(e,s,t,l,o,r)=>se(u+R,E(r),l,o,[e,s,t]),e.useResultRow=(e,s,t)=>ee(u+C,E(t),Z,[e,s]),e.useResultRowCount=(e,s)=>ee(u+p,E(s),0,[e]),e.useResultRowCountListener=(e,s,t,l)=>se(u+p,E(l),s,t,[e]),e.useResultRowIds=ke,e.useResultRowIdsListener=(e,s,t,l)=>se(u+b,E(l),s,t,[e]),e.useResultRowListener=(e,s,t,l,o)=>se(u+C,E(o),t,l,[e,s]),e.useResultSortedRowIds=ve,e.useResultSortedRowIdsListener=(e,s,t,l,o,r,n,d)=>se(u+w,E(d),r,n,[e,s,t,l,o]),e.useResultTable=(e,s)=>ee(u+a,E(s),Z,[e]),e.useResultTableCellIds=(e,s)=>ee(u+a+k,E(s),Y,[e]),e.useResultTableCellIdsListener=(e,s,t,l)=>se(u+a+k,E(l),s,t,[e]),e.useResultTableListener=(e,s,t,l)=>se(u+a,E(l),s,t,[e]),e.useRow=(e,s,t)=>ee(C,D(t),Z,[e,s]),e.useRowCount=(e,s)=>ee(p,D(s),0,[e]),e.useRowCountListener=(e,s,t,l,o)=>se(p,D(o),s,t,[e],l),e.useRowIds=ue,e.useRowIdsListener=(e,s,t,l,o)=>se(b,D(o),s,t,[e],l),e.useRowListener=(e,s,t,l,o,r)=>se(C,D(r),t,l,[e,s],o),e.useSetCellCallback=(e,s,t,l,o,r,u,n)=>te(r,R,l,o,u,n,e,s,t),e.useSetCheckpointCallback=(e=f,s=Y,t,l=f,o=Y)=>{const r=A(t);return W((s=>m(r,(t=>{const o=e(s);l(t.addCheckpoint(o),t,o)}))),[r,...s,...o])},e.useSetPartialRowCallback=(e,s,t,l,o,r,u)=>te(o,"PartialRow",t,l,r,u,e,s),e.useSetPartialValuesCallback=(e,s,t,l,o)=>te(t,"PartialValues",e,s,l,o),e.useSetRowCallback=(e,s,t,l,o,r,u)=>te(o,C,t,l,r,u,e,s),e.useSetTableCallback=(e,s,t,l,o,r)=>te(l,a,s,t,o,r,e),e.useSetTablesCallback=(e,s,t,l,o)=>te(t,c,e,s,l,o),e.useSetValueCallback=(e,s,t,l,o,r)=>te(l,v,s,t,o,r,e),e.useSetValuesCallback=(e,s,t,l,o)=>te(t,g,e,s,l,o),e.useSliceIds=Ce,e.useSliceIdsListener=(e,s,t,l)=>se("SliceIds",F(l),s,t,[e]),e.useSliceRowIds=pe,e.useSliceRowIdsListener=(e,s,t,l,o)=>se("Slice"+b,F(o),t,l,[e,s]),e.useSortedRowIds=ne,e.useSortedRowIdsListener=(e,s,t,l,o,r,u,n,d)=>se(w,D(d),r,u,[e,s,t,l,o],n),e.useStartTransactionListener=(e,s,t)=>se("Start"+U,D(t),e,s),e.useStore=e=>B(e,0),e.useStoreIds=()=>M(1),e.useStoreOrStoreById=D,e.useTable=(e,s)=>ee(a,D(s),Z,[e]),e.useTableCellIds=(e,s)=>ee(a+k,D(s),Y,[e]),e.useTableCellIdsListener=(e,s,t,l,o)=>se(a+k,D(o),s,t,[e],l),e.useTableIds=re,e.useTableIdsListener=(e,s,t,l)=>se(I,D(l),e,s,Y,t),e.useTableListener=(e,s,t,l,o)=>se(a,D(o),s,t,[e],l),e.useTables=e=>ee(c,D(e),Z),e.useTablesListener=(e,s,t,l)=>se(c,D(l),e,s,Y,t),e.useUndoInformation=e=>{var s;const t=A(e),[o,r]=ye(t);return[(u=o,!(0==u.length)),Le(t),r,null!=(s=m(r,(e=>null==t?void 0:t.getCheckpoint(e))))?s:l];var u},e.useValue=ce,e.useValueIds=ae,e.useValueIdsListener=(e,s,t,l)=>se(h,D(l),e,s,Y,t),e.useValueListener=(e,s,t,l,o)=>se(v,D(o),s,t,[e],l),e.useValues=e=>ee(g,D(e),Z),e.useValuesListener=(e,s,t,l)=>se(g,D(l),e,s,Y,t),e.useWillFinishTransactionListener=(e,s,t)=>se("WillFinish"+U,D(t),e,s)},"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).TinyBaseUiReact={},e.React);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinybase",
3
- "version": "4.4.0",
3
+ "version": "4.4.2",
4
4
  "author": "jamesgpearce",
5
5
  "repository": "github:tinyplex/tinybase",
6
6
  "license": "MIT",
@@ -213,31 +213,31 @@
213
213
  "publishPackage": "gulp publishPackage"
214
214
  },
215
215
  "devDependencies": {
216
- "@automerge/automerge": "^2.1.6",
216
+ "@automerge/automerge": "^2.1.7",
217
217
  "@babel/cli": "^7.23.0",
218
- "@babel/core": "^7.23.2",
219
- "@babel/preset-env": "^7.23.2",
220
- "@babel/preset-react": "^7.22.15",
221
- "@babel/preset-typescript": "^7.23.2",
218
+ "@babel/core": "^7.23.3",
219
+ "@babel/preset-env": "^7.23.3",
220
+ "@babel/preset-react": "^7.23.3",
221
+ "@babel/preset-typescript": "^7.23.3",
222
222
  "@prettier/sync": "^0.3.0",
223
223
  "@rollup/plugin-image": "^3.0.3",
224
224
  "@rollup/plugin-replace": "^5.0.5",
225
225
  "@rollup/plugin-terser": "^0.4.4",
226
- "@sqlite.org/sqlite-wasm": "^3.44.0-build1",
226
+ "@sqlite.org/sqlite-wasm": "^3.44.0-build2",
227
227
  "@types/asciichart": "^1.5.8",
228
228
  "@types/expect-puppeteer": "^5.0.6",
229
229
  "@types/http-server": "^0.12.4",
230
- "@types/jest": "^29.5.7",
230
+ "@types/jest": "^29.5.8",
231
231
  "@types/jest-environment-puppeteer": "^5.0.6",
232
232
  "@types/less": "^3.0.6",
233
- "@types/node": "^20.8.10",
233
+ "@types/node": "^20.9.0",
234
234
  "@types/puppeteer": "^5.4.7",
235
- "@types/react": "^18.2.36",
236
- "@types/react-dom": "^18.2.14",
237
- "@types/react-test-renderer": "^18.0.5",
235
+ "@types/react": "^18.2.37",
236
+ "@types/react-dom": "^18.2.15",
237
+ "@types/react-test-renderer": "^18.0.6",
238
238
  "@types/tmp": "^0.2.6",
239
- "@typescript-eslint/eslint-plugin": "^6.10.0",
240
- "@typescript-eslint/parser": "^6.10.0",
239
+ "@typescript-eslint/eslint-plugin": "^6.11.0",
240
+ "@typescript-eslint/parser": "^6.11.0",
241
241
  "@vlcn.io/crsqlite-wasm": "^0.15.2",
242
242
  "asciichart": "^1.5.25",
243
243
  "automerge-repo": "^0.1.0",
@@ -253,7 +253,7 @@
253
253
  "eslint": "^8.53.0",
254
254
  "eslint-config-prettier": "^9.0.0",
255
255
  "eslint-plugin-jest": "^27.6.0",
256
- "eslint-plugin-jsdoc": "^46.8.2",
256
+ "eslint-plugin-jsdoc": "^46.9.0",
257
257
  "eslint-plugin-react": "7.33.2",
258
258
  "eslint-plugin-react-hooks": "^4.6.0",
259
259
  "expo-sqlite": "^11.6.0",
@@ -267,14 +267,14 @@
267
267
  "jest-fetch-mock": "^3.0.3",
268
268
  "jest-puppeteer": "^9.0.1",
269
269
  "less": "^4.2.0",
270
- "partykit": "^0.0.34",
270
+ "partykit": "^0.0.35",
271
271
  "partysocket": "^0.0.14",
272
- "prettier": "^3.0.3",
272
+ "prettier": "^3.1.0",
273
273
  "puppeteer": "21.1.1",
274
274
  "react": "^18.2.0",
275
275
  "react-dom": "^18.2.0",
276
276
  "react-test-renderer": "^18.2.0",
277
- "rollup": "^4.3.0",
277
+ "rollup": "^4.4.1",
278
278
  "rollup-plugin-esbuild": "^6.1.0",
279
279
  "rollup-plugin-gzip": "^3.1.0",
280
280
  "rollup-plugin-preserve-shebang": "^1.0.1",
@@ -291,7 +291,7 @@
291
291
  "@sqlite.org/sqlite-wasm": "^3.44.0-build1",
292
292
  "@vlcn.io/crsqlite-wasm": "^0.15.2",
293
293
  "automerge-repo": "^0.1.0",
294
- "partykit": "^0.0.34",
294
+ "partykit": "^0.0.35",
295
295
  "partysocket": "^0.0.14",
296
296
  "prettier": "^3.0.3",
297
297
  "react": "^18.2.0",
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://tinybase.org/guides/releases/#v4-4"><em>NEW!</em> v4.4 release</a> <span id="one-with">&quot;The One With More Listeners&quot;</span></p><p><a class="start" href="https://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://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&#x27;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 &amp; 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://tinybase.org/api/persister-browser">storage</a>, <a href="https://tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>, and (<em>new!</em>) <a href="https://tinybase.org/api/persister-partykit-client/">PartyKit</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">5.0kB - 9.4kB</a>, zero dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://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://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://tinybase.org/react.svg"> React</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img width="48" src="https://tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img width="48" src="https://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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;label=Twitter&amp;labelColor=%23333&amp;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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/4.4.0" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;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://tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://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://tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
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://tinybase.org/guides/releases/#v4-4"><em>NEW!</em> v4.4 release</a> <span id="one-with">&quot;The One With More Listeners&quot;</span></p><p><a class="start" href="https://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://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&#x27;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 &amp; 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://tinybase.org/api/persister-browser">storage</a>, <a href="https://tinybase.org/api/persister-indexed-db/">IndexedDB</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence/">SQLite</a>, <a href="https://tinybase.org/guides/schemas-and-persistence/synchronizing-data/">CRDTs</a>, and (<em>new!</em>) <a href="https://tinybase.org/api/persister-partykit-client/">PartyKit</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">5.0kB - 9.4kB</a>, no dependencies. <a href="#well-tested-and-documented">100% tested</a>, <a href="https://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://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img width="48" src="https://tinybase.org/react.svg"> React</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img width="48" src="https://tinybase.org/partykit.svg"> PartyKit</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img width="48" src="https://tinybase.org/sqlite.svg"> SQLite</a></div><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img width="48" src="https://tinybase.org/indexeddb.svg"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img width="48" src="https://tinybase.org/yjs.svg"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img width="48" src="https://tinybase.org/crsqlite.png"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img width="48" src="https://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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"> </a><a href="https://twitter.com/tinybasejs" target="_blank"><img src="https://img.shields.io/twitter/follow/tinybasejs?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;label=Twitter&amp;labelColor=%23333&amp;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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;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&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/4.4.2" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;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://tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://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://tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
2
2
 
3
3
  ```js
4
4
  const store = createStore()
@@ -247,4 +247,4 @@ export const createShop: typeof createShopDecl = () => {
247
247
  };
248
248
  ```
249
249
 
250
- <section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://tinybase.org/api/store/"><code>store</code></a> module alone, you&#x27;ll only add a gzipped <em>5.0kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>9.4kB</em>.</p><p>The optional <a href="https://tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just another <em>4.1kB</em>, the auxiliary <a href="https://tinybase.org/api/tools/"><code>tools</code></a> module is <em>11.1kB</em>, and everything is super fast. Life&#x27;s easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://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://tinybase.org/api/store/">store</a></th><td>5.0kB</td><td>12.0kB</td><td>51.6kB</td><td>252.6kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/metrics/">metrics</a></th><td>1.8kB</td><td>3.6kB</td><td>15.2kB</td><td>30.9kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/indexes/">indexes</a></th><td>1.9kB</td><td>3.8kB</td><td>17.0kB</td><td>35.6kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/relationships/">relationships</a></th><td>1.9kB</td><td>3.7kB</td><td>17.1kB</td><td>44.2kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/queries/">queries</a></th><td>2.8kB</td><td>5.7kB</td><td>25.6kB</td><td>127.8kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/checkpoints/">checkpoints</a></th><td>1.5kB</td><td>3.1kB</td><td>12.4kB</td><td>33.3kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/persisters/">persisters</a></th><td>0.8kB</td><td>1.5kB</td><td>5.3kB</td><td>43.5kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/common/">common</a></th><td>0.1kB</td><td>0.1kB</td><td>0.1kB</td><td>3.5kB</td></tr><tr><th class="right">tinybase (all)</th><td>9.4kB</td><td>23.2kB</td><td>100.5kB</td><td>0.3kB</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://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>1,946</td><td>1,946</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,102</td><td>2,102</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>837</td><td>837</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>711</td><td>711</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">3,778</td></tr><tr><th class="right">Assertions</th><td colspan="3">17,830</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/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/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/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/jaysc" target="_blank"><img title="jaysc" src="https://github.com/jaysc.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/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/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/nikitavoloboev" target="_blank"><img title="nikitavoloboev" src="https://github.com/nikitavoloboev.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/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://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://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://tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://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://tinybase.org/youtube.webp"></a></section>
250
+ <section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://tinybase.org/api/store/"><code>store</code></a> module alone, you&#x27;ll only add a gzipped <em>5.0kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>9.4kB</em>.</p><p>The optional <a href="https://tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just another <em>4.3kB</em>, the auxiliary <a href="https://tinybase.org/api/tools/"><code>tools</code></a> module is <em>11.1kB</em>, and everything is super fast. Life&#x27;s easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://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://tinybase.org/api/store/">store</a></th><td>5.0kB</td><td>12.0kB</td><td>51.6kB</td><td>252.6kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/metrics/">metrics</a></th><td>1.8kB</td><td>3.6kB</td><td>15.2kB</td><td>30.9kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/indexes/">indexes</a></th><td>1.9kB</td><td>3.8kB</td><td>17.0kB</td><td>35.6kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/relationships/">relationships</a></th><td>1.9kB</td><td>3.7kB</td><td>17.1kB</td><td>44.2kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/queries/">queries</a></th><td>2.8kB</td><td>5.7kB</td><td>25.6kB</td><td>126.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/checkpoints/">checkpoints</a></th><td>1.5kB</td><td>3.1kB</td><td>12.5kB</td><td>33.3kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/persisters/">persisters</a></th><td>0.8kB</td><td>1.5kB</td><td>5.3kB</td><td>43.5kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/common/">common</a></th><td>0.1kB</td><td>0.1kB</td><td>0.1kB</td><td>3.5kB</td></tr><tr><th class="right">tinybase (all)</th><td>9.4kB</td><td>23.2kB</td><td>100.6kB</td><td>0.3kB</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://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>1,960</td><td>1,960</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,118</td><td>2,118</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>845</td><td>845</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>713</td><td>713</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">3,779</td></tr><tr><th class="right">Assertions</th><td colspan="3">17,838</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/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/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/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/jaysc" target="_blank"><img title="jaysc" src="https://github.com/jaysc.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/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/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/nikitavoloboev" target="_blank"><img title="nikitavoloboev" src="https://github.com/nikitavoloboev.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/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://tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://tinybase.org/demos/">Try the demos</a></p><p><a href="https://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://tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://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://tinybase.org/youtube.webp"></a></section>