tinybase 9.2.0-beta.0 → 9.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/@types/schematizers/index.d.ts +27 -9
  2. package/@types/schematizers/schematizer-arktype/index.d.ts +8 -7
  3. package/@types/schematizers/schematizer-effect/index.d.ts +7 -5
  4. package/@types/schematizers/schematizer-typebox/index.d.ts +8 -7
  5. package/@types/schematizers/schematizer-valibot/index.d.ts +8 -7
  6. package/@types/schematizers/schematizer-yup/index.d.ts +5 -4
  7. package/@types/schematizers/schematizer-zod/index.d.ts +8 -7
  8. package/agents.md +74 -14
  9. package/min/schematizers/index.js +1 -1
  10. package/min/schematizers/index.js.gz +0 -0
  11. package/min/schematizers/schematizer-arktype/index.js +1 -1
  12. package/min/schematizers/schematizer-arktype/index.js.gz +0 -0
  13. package/min/schematizers/schematizer-arktype/with-schemas/index.js +1 -1
  14. package/min/schematizers/schematizer-arktype/with-schemas/index.js.gz +0 -0
  15. package/min/schematizers/schematizer-effect/index.js +1 -1
  16. package/min/schematizers/schematizer-effect/index.js.gz +0 -0
  17. package/min/schematizers/schematizer-effect/with-schemas/index.js +1 -1
  18. package/min/schematizers/schematizer-effect/with-schemas/index.js.gz +0 -0
  19. package/min/schematizers/schematizer-typebox/index.js +1 -1
  20. package/min/schematizers/schematizer-typebox/index.js.gz +0 -0
  21. package/min/schematizers/schematizer-typebox/with-schemas/index.js +1 -1
  22. package/min/schematizers/schematizer-typebox/with-schemas/index.js.gz +0 -0
  23. package/min/schematizers/schematizer-valibot/index.js +1 -1
  24. package/min/schematizers/schematizer-valibot/index.js.gz +0 -0
  25. package/min/schematizers/schematizer-valibot/with-schemas/index.js +1 -1
  26. package/min/schematizers/schematizer-valibot/with-schemas/index.js.gz +0 -0
  27. package/min/schematizers/schematizer-yup/index.js +1 -1
  28. package/min/schematizers/schematizer-yup/index.js.gz +0 -0
  29. package/min/schematizers/schematizer-yup/with-schemas/index.js +1 -1
  30. package/min/schematizers/schematizer-yup/with-schemas/index.js.gz +0 -0
  31. package/min/schematizers/schematizer-zod/index.js +1 -1
  32. package/min/schematizers/schematizer-zod/index.js.gz +0 -0
  33. package/min/schematizers/schematizer-zod/with-schemas/index.js +1 -1
  34. package/min/schematizers/schematizer-zod/with-schemas/index.js.gz +0 -0
  35. package/min/schematizers/with-schemas/index.js +1 -1
  36. package/min/schematizers/with-schemas/index.js.gz +0 -0
  37. package/package.json +12 -5
  38. package/readme.md +3 -3
  39. package/releases.md +8 -2
  40. package/schematizers/index.js +21 -6
  41. package/schematizers/schematizer-arktype/index.js +52 -17
  42. package/schematizers/schematizer-arktype/with-schemas/index.js +52 -17
  43. package/schematizers/schematizer-effect/index.js +41 -11
  44. package/schematizers/schematizer-effect/with-schemas/index.js +41 -11
  45. package/schematizers/schematizer-typebox/index.js +49 -9
  46. package/schematizers/schematizer-typebox/with-schemas/index.js +49 -9
  47. package/schematizers/schematizer-valibot/index.js +38 -10
  48. package/schematizers/schematizer-valibot/with-schemas/index.js +38 -10
  49. package/schematizers/schematizer-yup/index.js +29 -7
  50. package/schematizers/schematizer-yup/with-schemas/index.js +29 -7
  51. package/schematizers/schematizer-zod/index.js +29 -14
  52. package/schematizers/schematizer-zod/with-schemas/index.js +29 -14
  53. package/schematizers/with-schemas/index.js +21 -6
@@ -1 +1 @@
1
- const e=e=>typeof e,t=e(""),r=e(!0),n=e(0),o="object",l="type",a="default",s=e=>(t,r,n)=>e(t)?n?.():r(t),u=e=>null==e,c=s(u),p=s(e=>void 0===e),y=r=>e(r)==t,f=Object,i=e=>f.getPrototypeOf(e),d=f.entries,h=f.keys,v=f.freeze,b=(e=[])=>f.fromEntries(e),m=(e,t)=>((e,t)=>e.forEach(t))(d(e),([e,r])=>t(r,e)),T=e=>e?.def??e?._zod?.def,g=(e,r,n)=>{const s=T(e),u=s?.type;return"optional"===u?g(s.innerType,r,n):"nullable"===u?g(s.innerType,r,!0):u===a?g(s.innerType,s.defaultValue,n):"record"===u?[{type:o},r,n??!1]:"enum"===u?[{[l]:t},r,n??!1]:"literal"===u&&(c=s.values,p=y,c.every(p))?[{[l]:t},r,n??!1]:[e,r,n??!1];var c,p},j=e=>T(e)?.shape,z=()=>((e,s)=>{const y=s=>{const[u,c,y]=e(s),f=u?.type;if(f!==t&&f!==n&&f!==r&&f!==o&&"array"!==f)return;const i={[l]:f};return p(c,e=>{i[a]=e}),y&&(i.allowNull=!0),i};return v({toTablesSchema:e=>{const t=b();return m(e,(e,r)=>{const n=b();var o;p(s(e),e=>m(e,(e,t)=>p(y(e),e=>{n[t]=e}))),(e=>!u(e)&&c(i(e),e=>e==f.prototype||u(i(e)),()=>!0))(o=n)&&0==(e=>h(e).length)(o)||(t[r]=n)}),t},toValuesSchema:e=>{const t=b();return m(e,(e,r)=>p(y(e),e=>{t[r]=e})),t}})})(g,j);export{z as createZodSchematizer};
1
+ const e=e=>typeof e,t=e(""),r=e(!0),o=e(0),n="object",l="type",a="default",u=e=>(t,r,o)=>e(t)?o?.():r(t),s=e=>null==e,c=e=>void 0===e,p=u(s),i=u(c),y=r=>e(r)==t,d=Object,f=e=>d.getPrototypeOf(e),v=d.entries,h=d.keys,b=d.freeze,m=(e=[])=>d.fromEntries(e),T=(e,t)=>((e,t)=>e.forEach(t))(v(e),([e,r])=>t(r,e)),g=e=>e?.def??e?._zod?.def,j=(e,r,o,u=!0)=>{const s=g(e),c=s?.type;return"optional"===c?j(s.innerType,r,o,!1):"nullable"===c?j(s.innerType,r,!0,u):c===a?j(s.innerType,s.defaultValue,o,!1):"record"===c?[{type:n},r,o??!1,u]:"enum"===c?[{[l]:t},r,o??!1,u]:"literal"===c&&(p=s.values,i=y,p.every(i))?[{[l]:t},r,o??!1,u]:[e,r,o??!1,u];var p,i},z=e=>g(e)?.shape,E=()=>((e,u)=>{const y=(u,s)=>{const[p,y,d,f=s]=e(u,void 0,void 0,s),v=p?.type;if(v!==t&&v!==o&&v!==r&&v!==n&&"array"!==v)return;const h={[l]:v};return i(y,e=>{h[a]=e}),d&&(h.allowNull=!0),f&&c(y)&&(h.required=!0),h};return b({toTablesSchema:e=>{const t=m();return T(e,(e,r)=>{const o=m();var n;i(u(e),e=>T(e,(e,t)=>i(y(e,void 0),e=>{o[t]=e}))),(e=>!s(e)&&p(f(e),e=>e==d.prototype||s(f(e)),()=>!0))(n=o)&&0==(e=>h(e).length)(n)||(t[r]=o)}),t},toValuesSchema:e=>{const t=m();return T(e,(e,r)=>i(y(e),e=>{t[r]=e})),t}})})(j,z);export{E as createZodSchematizer};
@@ -1 +1 @@
1
- const e=e=>typeof e,t=e(""),r=e(!0),n=e(0),o="object",l="type",a="default",s=e=>(t,r,n)=>e(t)?n?.():r(t),u=e=>null==e,c=s(u),p=s(e=>void 0===e),y=r=>e(r)==t,f=Object,i=e=>f.getPrototypeOf(e),d=f.entries,h=f.keys,v=f.freeze,b=(e=[])=>f.fromEntries(e),m=(e,t)=>((e,t)=>e.forEach(t))(d(e),([e,r])=>t(r,e)),T=e=>e?.def??e?._zod?.def,g=(e,r,n)=>{const s=T(e),u=s?.type;return"optional"===u?g(s.innerType,r,n):"nullable"===u?g(s.innerType,r,!0):u===a?g(s.innerType,s.defaultValue,n):"record"===u?[{type:o},r,n??!1]:"enum"===u?[{[l]:t},r,n??!1]:"literal"===u&&(c=s.values,p=y,c.every(p))?[{[l]:t},r,n??!1]:[e,r,n??!1];var c,p},j=e=>T(e)?.shape,z=()=>((e,s)=>{const y=s=>{const[u,c,y]=e(s),f=u?.type;if(f!==t&&f!==n&&f!==r&&f!==o&&"array"!==f)return;const i={[l]:f};return p(c,e=>{i[a]=e}),y&&(i.allowNull=!0),i};return v({toTablesSchema:e=>{const t=b();return m(e,(e,r)=>{const n=b();var o;p(s(e),e=>m(e,(e,t)=>p(y(e),e=>{n[t]=e}))),(e=>!u(e)&&c(i(e),e=>e==f.prototype||u(i(e)),()=>!0))(o=n)&&0==(e=>h(e).length)(o)||(t[r]=n)}),t},toValuesSchema:e=>{const t=b();return m(e,(e,r)=>p(y(e),e=>{t[r]=e})),t}})})(g,j);export{z as createZodSchematizer};
1
+ const e=e=>typeof e,t=e(""),r=e(!0),o=e(0),n="object",l="type",a="default",u=e=>(t,r,o)=>e(t)?o?.():r(t),s=e=>null==e,c=e=>void 0===e,p=u(s),i=u(c),y=r=>e(r)==t,d=Object,f=e=>d.getPrototypeOf(e),v=d.entries,h=d.keys,b=d.freeze,m=(e=[])=>d.fromEntries(e),T=(e,t)=>((e,t)=>e.forEach(t))(v(e),([e,r])=>t(r,e)),g=e=>e?.def??e?._zod?.def,j=(e,r,o,u=!0)=>{const s=g(e),c=s?.type;return"optional"===c?j(s.innerType,r,o,!1):"nullable"===c?j(s.innerType,r,!0,u):c===a?j(s.innerType,s.defaultValue,o,!1):"record"===c?[{type:n},r,o??!1,u]:"enum"===c?[{[l]:t},r,o??!1,u]:"literal"===c&&(p=s.values,i=y,p.every(i))?[{[l]:t},r,o??!1,u]:[e,r,o??!1,u];var p,i},z=e=>g(e)?.shape,E=()=>((e,u)=>{const y=(u,s)=>{const[p,y,d,f=s]=e(u,void 0,void 0,s),v=p?.type;if(v!==t&&v!==o&&v!==r&&v!==n&&"array"!==v)return;const h={[l]:v};return i(y,e=>{h[a]=e}),d&&(h.allowNull=!0),f&&c(y)&&(h.required=!0),h};return b({toTablesSchema:e=>{const t=m();return T(e,(e,r)=>{const o=m();var n;i(u(e),e=>T(e,(e,t)=>i(y(e,void 0),e=>{o[t]=e}))),(e=>!s(e)&&p(f(e),e=>e==d.prototype||s(f(e)),()=>!0))(n=o)&&0==(e=>h(e).length)(n)||(t[r]=o)}),t},toValuesSchema:e=>{const t=m();return T(e,(e,r)=>i(y(e),e=>{t[r]=e})),t}})})(j,z);export{E as createZodSchematizer};
@@ -1 +1 @@
1
- const t=t=>typeof t,e=t(""),r=t(!0),o=t(0),n="type",c=t=>(e,r,o)=>t(e)?o?.():r(e),s=t=>null==t,a=c(s),l=c(t=>void 0===t),u=Object,f=t=>u.getPrototypeOf(t),p=u.entries,y=u.keys,h=u.freeze,i=(t=[])=>u.fromEntries(t),b=(t,e)=>((t,e)=>t.forEach(e))(p(t),([t,r])=>e(r,t)),m=(t,c)=>{const p=c=>{const[s,a,u]=t(c),f=s?.type;if(f!==e&&f!==o&&f!==r&&"object"!==f&&"array"!==f)return;const p={[n]:f};return l(a,t=>{p.default=t}),u&&(p.allowNull=!0),p};return h({toTablesSchema:t=>{const e=i();return b(t,(t,r)=>{const o=i();var n;l(c(t),t=>b(t,(t,e)=>l(p(t),t=>{o[e]=t}))),(t=>!s(t)&&a(f(t),t=>t==u.prototype||s(f(t)),()=>!0))(n=o)&&0==(t=>y(t).length)(n)||(e[r]=o)}),e},toValuesSchema:t=>{const e=i();return b(t,(t,r)=>l(p(t),t=>{e[r]=t})),e}})};export{m as createCustomSchematizer};
1
+ const e=e=>typeof e,t=e(""),r=e(!0),o=e(0),n="type",c=e=>(t,r,o)=>e(t)?o?.():r(t),s=e=>null==e,a=e=>void 0===e,l=c(s),u=c(a),f=Object,i=e=>f.getPrototypeOf(e),p=f.entries,y=f.keys,d=f.freeze,h=(e=[])=>f.fromEntries(e),v=(e,t)=>((e,t)=>e.forEach(t))(p(e),([e,r])=>t(r,e)),b=(e,c,p)=>{const b=(c,s)=>{const[l,f,i,p=s]=e(c,void 0,void 0,s),y=l?.type;if(y!==t&&y!==o&&y!==r&&"object"!==y&&"array"!==y)return;const d={[n]:y};return u(f,e=>{d.default=e}),i&&(d.allowNull=!0),p&&a(f)&&(d.required=!0),d};return d({toTablesSchema:e=>{const t=h();return v(e,(e,r)=>{const o=h();var n;u(c(e),t=>v(t,(t,r)=>u(b(t,p?.(e,r,t)),e=>{o[r]=e}))),(e=>!s(e)&&l(i(e),e=>e==f.prototype||s(i(e)),()=>!0))(n=o)&&0==(e=>y(e).length)(n)||(t[r]=o)}),t},toValuesSchema:e=>{const t=h();return v(e,(e,r)=>u(b(e),e=>{t[r]=e})),t}})};export{b as createCustomSchematizer};
package/package.json CHANGED
@@ -1,15 +1,22 @@
1
1
  {
2
2
  "name": "tinybase",
3
- "version": "9.2.0-beta.0",
3
+ "version": "9.3.0-beta.0",
4
4
  "author": "jamesgpearce",
5
5
  "repository": "github:tinyplex/tinybase",
6
6
  "license": "MIT",
7
7
  "homepage": "https://tinybase.org",
8
- "description": "A reactive data store and sync engine.",
8
+ "description": "A reactive in-memory data store with persistence and synchronization for local-first JavaScript and TypeScript apps.",
9
9
  "keywords": [
10
10
  "tiny",
11
11
  "sync engine",
12
12
  "local-first",
13
+ "offline-first",
14
+ "in-memory database",
15
+ "client-side database",
16
+ "reactive database",
17
+ "crdt",
18
+ "indexeddb",
19
+ "typescript",
13
20
  "reactive",
14
21
  "state",
15
22
  "data",
@@ -24,11 +31,11 @@
24
31
  "sideEffects": false,
25
32
  "peerDependencies": {
26
33
  "@automerge/automerge-repo": "^2.5.6",
27
- "@cloudflare/workers-types": "^5.20260708.1",
34
+ "@cloudflare/workers-types": "^5.20260711.1",
28
35
  "@electric-sql/pglite": "^0.5.4",
29
36
  "@libsql/client": "^0.17.4",
30
- "@powersync/common": "^1.57.1",
31
- "@sinclair/typebox": "^0.34.49",
37
+ "@powersync/common": "^1.57.2",
38
+ "@sinclair/typebox": "^0.34.50",
32
39
  "@sqlite.org/sqlite-wasm": "^3.53.0-build1",
33
40
  "@vlcn.io/crsqlite-wasm": "^0.16.0",
34
41
  "arktype": "^2.2.3",
package/readme.md CHANGED
@@ -1,4 +1,4 @@
1
- <link rel="preload" as="image" href="https://tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/solid.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/svelte.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/browser.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/zod.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/typebox.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/valibot.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/arktype.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/yup.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/effect.svg?asImg"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"><link rel="preload" as="image" href="https://tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/fastrepl.png?size=48"><link rel="preload" as="image" href="https://github.com/ComputelessComputer.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/braden-w.png?size=48"><link rel="preload" as="image" href="https://github.com/dylmye.png?size=48"><link rel="preload" as="image" href="https://github.com/gonza224.png?size=48"><link rel="preload" as="image" href="https://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://synclets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/youtube.webp"><section id="hero"><h2 id="local-first"><em>Local</em> first.</h2><h2 id="sync-on-demand"><em>Sync</em> on demand.</h2><h2 id="fast-always"><em>Fast</em> always.</h2><p>TinyBase is a reactive data store &amp; sync engine for apps that need to feel instant, work well when they are offline, and yet stay consistent when they are back online.</p></section><p><a href="https://tinybase.org/guides/releases/#v9-1"><em>NEW!</em> v9.1 release notes</a></p><p><span id="one-with">&quot;The one with required fields!&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/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section><h2 id="your-first-tinybase-app">Your first <em>TinyBase</em> app</h2><p>Create a todo list, a chat app, a drawing tool, a charting app, or a tic-tac-toe game - with sync &amp; persistence! - in less than 60s.</p></section>
1
+ <link rel="preload" as="image" href="https://tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/solid.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/svelte.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/browser.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/zod.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/typebox.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/valibot.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/arktype.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/yup.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/effect.svg?asImg"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="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"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"><link rel="preload" as="image" href="https://tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/fastrepl.png?size=48"><link rel="preload" as="image" href="https://github.com/ComputelessComputer.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/braden-w.png?size=48"><link rel="preload" as="image" href="https://github.com/dylmye.png?size=48"><link rel="preload" as="image" href="https://github.com/gonza224.png?size=48"><link rel="preload" as="image" href="https://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://synclets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinybase.org/youtube.webp"><section id="hero"><h2 id="local-first"><em>Local</em> first.</h2><h2 id="sync-on-demand"><em>Sync</em> on demand.</h2><h2 id="fast-always"><em>Fast</em> always.</h2><p>TinyBase is a reactive in-memory data store with persistence and synchronization for local-first JavaScript and TypeScript apps that need to feel instant, work offline, and stay consistent when they come back online.</p></section><p><a href="https://tinybase.org/guides/releases/#v9-2"><em>NEW!</em> v9.2 release</a></p><p><span id="one-with">&quot;The one for agents!&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/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section><h2 id="your-first-tinybase-app">Your first <em>TinyBase</em> app</h2><p>Create a todo list, a chat app, a drawing tool, a charting app, or a tic-tac-toe game - with sync &amp; persistence! - in less than 60s.</p></section>
2
2
 
3
3
  ```bash
4
4
  > npm create tinybase@latest
@@ -6,7 +6,7 @@
6
6
  📦 Creating your project...
7
7
  ```
8
8
 
9
- <hr><section><h2 id="it-s-reactive">It&#x27;s <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a>, <a href="#pre-built-reactive-components">pre-built components</a>, and <a href="#local-first-data-visualizations">charts</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It&#x27;s <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-or-a-database">persist</a> your data to file, <a href="https://tinybase.org/api/persister-browser">browser storage</a>, <a href="https://tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It&#x27;s Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it&#x27;s especially great for local-first apps: where data is stored locally on the user&#x27;s device and that can be run offline. It&#x27;s tiny by name, tiny by nature: just <a href="#did-we-say-tiny">6.4kB - 14.0kB</a> and with no dependencies - yet <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>!</p></section><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><h3 id="ui-frameworks"><a href="https://tinybase.org/guides/">UI Frameworks</a></h3><div><a href="https://tinybase.org/guides/building-uis-with-react/getting-started-with-ui-react"><img src="https://tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://tinybase.org/guides/building-uis-with-solid/getting-started-with-ui-solid"><img src="https://tinybase.org/solid.svg?asImg" width="48"> Solid</a></div><div><a href="https://tinybase.org/guides/building-uis-with-svelte/getting-started-with-ui-svelte"><img src="https://tinybase.org/svelte.svg?asImg" width="48"> Svelte</a></div><h3 id="storage-sync"><a href="https://tinybase.org/guides/persistence/">Storage &amp; Sync</a></h3><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-browser"><img src="https://tinybase.org/browser.svg?asImg" width="48"> OPFS</a></div><div><a href="https://tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img src="https://tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img src="https://tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><h3 id="schema-systems"><a href="https://tinybase.org/guides/schemas/using-schematizers/">Schema Systems</a></h3><div><a href="https://tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer"><img src="https://tinybase.org/zod.svg?asImg" width="48"> Zod</a></div><div><a href="https://tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer"><img src="https://tinybase.org/typebox.svg?asImg" width="48"> TypeBox</a></div><div><a href="https://tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer"><img src="https://tinybase.org/valibot.svg?asImg" width="48"> Valibot</a></div><div><a href="https://tinybase.org/api/schematizer-arktype/functions/creation/createarktypeschematizer"><img src="https://tinybase.org/arktype.svg?asImg" width="48"> ArkType</a></div><div><a href="https://tinybase.org/api/schematizer-yup/functions/creation/createyupschematizer"><img src="https://tinybase.org/yup.svg?asImg" width="48"> Yup</a></div><div><a href="https://tinybase.org/api/schematizer-effect/functions/creation/createeffectschematizer"><img src="https://tinybase.org/effect.svg?asImg" width="48"> Effect</a></div><p>(Baffled by all these logos? Check out our <a href="https://tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></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://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"> </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><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=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/9.1.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/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://tinybase.org/api/the-essentials/creating-stores/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>
9
+ <hr><section><h2 id="it-s-reactive">It&#x27;s <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a>, <a href="#pre-built-reactive-components">pre-built components</a>, and <a href="#local-first-data-visualizations">charts</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It&#x27;s <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-or-a-database">persist</a> your data to file, <a href="https://tinybase.org/api/persister-browser">browser storage</a>, <a href="https://tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It&#x27;s Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it&#x27;s especially great for local-first apps: where data is stored locally on the user&#x27;s device and that can be run offline. It&#x27;s tiny by name, tiny by nature: just <a href="#did-we-say-tiny">6.4kB - 14.0kB</a> and with no dependencies - yet <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>!</p></section><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><h3 id="ui-frameworks"><a href="https://tinybase.org/guides/">UI Frameworks</a></h3><div><a href="https://tinybase.org/guides/building-uis-with-react/getting-started-with-ui-react"><img src="https://tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://tinybase.org/guides/building-uis-with-solid/getting-started-with-ui-solid"><img src="https://tinybase.org/solid.svg?asImg" width="48"> Solid</a></div><div><a href="https://tinybase.org/guides/building-uis-with-svelte/getting-started-with-ui-svelte"><img src="https://tinybase.org/svelte.svg?asImg" width="48"> Svelte</a></div><h3 id="storage-sync"><a href="https://tinybase.org/guides/persistence/">Storage &amp; Sync</a></h3><div><a href="https://tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://tinybase.org/api/persister-browser"><img src="https://tinybase.org/browser.svg?asImg" width="48"> OPFS</a></div><div><a href="https://tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://tinybase.org/api/persister-partykit-client"><img src="https://tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://tinybase.org/api/persister-automerge"><img src="https://tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><h3 id="schema-systems"><a href="https://tinybase.org/guides/schemas/using-schematizers/">Schema Systems</a></h3><div><a href="https://tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer"><img src="https://tinybase.org/zod.svg?asImg" width="48"> Zod</a></div><div><a href="https://tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer"><img src="https://tinybase.org/typebox.svg?asImg" width="48"> TypeBox</a></div><div><a href="https://tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer"><img src="https://tinybase.org/valibot.svg?asImg" width="48"> Valibot</a></div><div><a href="https://tinybase.org/api/schematizer-arktype/functions/creation/createarktypeschematizer"><img src="https://tinybase.org/arktype.svg?asImg" width="48"> ArkType</a></div><div><a href="https://tinybase.org/api/schematizer-yup/functions/creation/createyupschematizer"><img src="https://tinybase.org/yup.svg?asImg" width="48"> Yup</a></div><div><a href="https://tinybase.org/api/schematizer-effect/functions/creation/createeffectschematizer"><img src="https://tinybase.org/effect.svg?asImg" width="48"> Effect</a></div><p>(Baffled by all these logos? Check out our <a href="https://tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></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://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"> </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><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=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/9.2.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/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://tinybase.org/api/the-essentials/creating-stores/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>
10
10
 
11
11
  ```js
12
12
  import {createStore} from 'tinybase';
@@ -283,4 +283,4 @@ console.log(store.getCell('pets', 'felix', 'sold'));
283
283
  // -> false
284
284
  ```
285
285
 
286
- <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>6.4kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>14.0kB</em>.</p><p>The optional <a href="https://tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.7kB</em>, the ui-react-dom components are another <em>4.1kB</em>, and everything is super fast. Life is 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> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>6.4kB</td><td>68.3kB</td></tr><tr><th class="right">tinybase (complete)</th><td>14.0kB</td><td>155.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react/">ui-react</a></th><td>5.7kB</td><td>62.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>4.1kB</td><td>37.4kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react-dom-charts/">ui-react-dom-charts</a></th><td>8.5kB</td><td>63.8kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-solid/">ui-solid</a></th><td>5.6kB</td><td>61.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-solid-dom/">ui-solid-dom</a></th><td>4.7kB</td><td>45.4kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-svelte/">ui-svelte</a></th><td>4.8kB</td><td>60.7kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-svelte-dom/">ui-svelte-dom</a></th><td>5.8kB</td><td>61.1kB</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 <a href="https://tinybase.org/api/">API</a> 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">Tested lines</th><td>4,537</td><td>4,537</td><td>100.0%</td></tr><tr><th class="right">Tested statements</th><td>4,919</td><td>4,919</td><td>100.0%</td></tr><tr><th class="right">Tested functions</th><td>2,211</td><td>2,211</td><td>100.0%</td></tr><tr><th class="right">Tested branches</th><td>1,432</td><td>1,423</td><td>99.4%</td></tr><tr><th class="right">Tests</th><td colspan="3">8,660</td></tr><tr><th class="right">Assertions</th><td colspan="3">36,094</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-supported-by">Proud to be supported by:</h2><a href="https://github.com/fastrepl" target="_blank"><img src="https://github.com/fastrepl.png?size=48" title="fastrepl" width="48" height="48"></a><a href="https://github.com/ComputelessComputer" target="_blank"><img src="https://github.com/ComputelessComputer.png?size=48" title="ComputelessComputer" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/braden-w" target="_blank"><img src="https://github.com/braden-w.png?size=48" title="braden-w" width="48" height="48"></a><a href="https://github.com/dylmye" target="_blank"><img src="https://github.com/dylmye.png?size=48" title="dylmye" width="48" height="48"></a><a href="https://github.com/gonza224" target="_blank"><img src="https://github.com/gonza224.png?size=48" title="gonza224" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" 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/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" 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/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><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](/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>
286
+ <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>6.4kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>14.0kB</em>.</p><p>The optional <a href="https://tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.7kB</em>, the ui-react-dom components are another <em>4.1kB</em>, and everything is super fast. Life is 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> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>6.4kB</td><td>68.3kB</td></tr><tr><th class="right">tinybase (complete)</th><td>14.0kB</td><td>155.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react/">ui-react</a></th><td>5.7kB</td><td>62.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>4.1kB</td><td>37.4kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-react-dom-charts/">ui-react-dom-charts</a></th><td>8.5kB</td><td>63.8kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-solid/">ui-solid</a></th><td>5.6kB</td><td>61.0kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-solid-dom/">ui-solid-dom</a></th><td>4.7kB</td><td>45.4kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-svelte/">ui-svelte</a></th><td>4.8kB</td><td>60.7kB</td></tr><tr><th class="right"><a href="https://tinybase.org/api/ui-svelte-dom/">ui-svelte-dom</a></th><td>5.8kB</td><td>61.1kB</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 <a href="https://tinybase.org/api/">API</a> 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">Tested lines</th><td>4,537</td><td>4,537</td><td>100.0%</td></tr><tr><th class="right">Tested statements</th><td>4,919</td><td>4,919</td><td>100.0%</td></tr><tr><th class="right">Tested functions</th><td>2,211</td><td>2,211</td><td>100.0%</td></tr><tr><th class="right">Tested branches</th><td>1,432</td><td>1,430</td><td>99.9%</td></tr><tr><th class="right">Tests</th><td colspan="3">8,663</td></tr><tr><th class="right">Assertions</th><td colspan="3">36,100</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-supported-by">Proud to be supported by:</h2><a href="https://github.com/fastrepl" target="_blank"><img src="https://github.com/fastrepl.png?size=48" title="fastrepl" width="48" height="48"></a><a href="https://github.com/ComputelessComputer" target="_blank"><img src="https://github.com/ComputelessComputer.png?size=48" title="ComputelessComputer" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/braden-w" target="_blank"><img src="https://github.com/braden-w.png?size=48" title="braden-w" width="48" height="48"></a><a href="https://github.com/dylmye" target="_blank"><img src="https://github.com/dylmye.png?size=48" title="dylmye" width="48" height="48"></a><a href="https://github.com/gonza224" target="_blank"><img src="https://github.com/gonza224.png?size=48" title="gonza224" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" 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/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" 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/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><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](/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>
package/releases.md CHANGED
@@ -1,4 +1,10 @@
1
- <link rel="preload" as="image" href="https://tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/axis-overrides-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/editablevalueview-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-svelte-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-svelte-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/editablevalueview-svelte-full-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/car-analysis-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/movie-database-demo.png"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v9-1">v9.1</h1><h2 id="required-schema-fields">Required Schema Fields</h2><p><a href="https://tinybase.org/guides/schemas/">Schemas</a> can now mark a <a href="https://tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> or <a href="https://tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> as required without providing a default value (<a href="https://github.com/tinyplex/tinybase/issues/173">#173</a>). Full writes now reject Rows or <a href="https://tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> that omit a required non-default field, while preserving the existing rule that a <code>default</code> also implies &#x27;requiredness&#x27; (and will be filled automatically if omitted).</p>
1
+ <link rel="preload" as="image" href="https://tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/axis-overrides-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/editablevalueview-solid-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-svelte-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-svelte-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/editablevalueview-svelte-full-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/inspector-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://tinybase.org/shots/sortedtableinhtmltable-react-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/car-analysis-demo.png"><link rel="preload" as="image" href="https://tinybase.org/shots/movie-database-demo.png"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v9-2">v9.2</h1><p>TinyBase v9.2 makes the library easier for coding agents and AI systems to discover, evaluate, understand, and use correctly.</p><p>Although there are no changes to TinyBase source code, this is more than just an AI-specific documentation pass. The package and website metadata now describes TinyBase using the concrete problems it solves: reactive in-memory data, offline and local-first applications, persistence, CRDTs, and synchronization. This helps search and retrieval systems connect an application requirement to TinyBase before the library name is already known.</p><h2 id="agent-documentation-and-retrieval">Agent <a href="https://tinybase.org/guides/how-tinybase-is-built/documentation/">Documentation</a> And Retrieval</h2><p>The website now publishes a concise <a href="https://tinybase.org/llms.txt"><code>llms.txt</code></a> orientation file and a fuller <a href="https://tinybase.org/llms-full.txt"><code>llms-full.txt</code></a> agent guide. A new <a href="https://tinybase.org/guides/the-basics/why-tinybase/">Why TinyBase?</a> guide explains when TinyBase is a good architectural fit, when it is not, and which <a href="https://tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>, persistence, synchronization, and UI pieces to start with.</p><p>The repository also includes configuration for current documentation to be indexed by <a href="https://context7.com/">Context7</a>, as well as machine-readable structured metadata for ordinary search and retrieval systems.</p><h2 id="an-official-tinybase-skill">An Official TinyBase Skill</h2><p>The repository now contains an official <a href="https://tinybase.org/skills/build-with-tinybase/SKILL.md"><code>build-with-tinybase</code></a> agent skill. It guides coding agents through architecture selection, scaffolding, safe extension of generated applications, and behavioral verification.</p><p>The skill treats persistence and synchronization as behaviors to prove, not just code that compiles. It instructs agents to verify persisted state across a real reload and synchronized state between multiple clients.</p><h2 id="agent-friendly-scaffolding">Agent-Friendly Scaffolding</h2><p>The <a href="https://github.com/tinyplex/create-tinybase"><code>create-tinybase</code></a> scaffolding tool now exposes its current options as JSON, documents its non-interactive mode, and generates an architecture-specific <code>AGENTS.md</code> in every new project. This gives agents a deterministic path from application requirements to a complete, working TinyBase app.</p><p>Agents can inspect the current generator contract with:</p>
2
+
3
+ ```sh
4
+ npm create tinybase@latest -- --list-options
5
+ ```
6
+
7
+ <p>The generated guidance records the chosen language, UI framework, persistence, synchronization, and schema options, identifies the important files, and states the verification expected for that architecture.</p><p>If you&#x27;re a human, you shouldn&#x27;t notice or mind these changes. If you&#x27;re an agent, we hope this makes it easier to find and use TinyBase correctly. Either way, let us know how it goes!</p><hr><h1 id="v9-1">v9.1</h1><h2 id="required-schema-fields">Required Schema Fields</h2><p><a href="https://tinybase.org/guides/schemas/">Schemas</a> can now mark a <a href="https://tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> or <a href="https://tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> as required without providing a default value (<a href="https://github.com/tinyplex/tinybase/issues/173">#173</a>). Full writes now reject Rows or <a href="https://tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> that omit a required non-default field, while preserving the existing rule that a <code>default</code> also implies &#x27;requiredness&#x27; (and will be filled automatically if omitted).</p>
2
8
 
3
9
  ```js
4
10
  import {createStore} from 'tinybase';
@@ -21,7 +27,7 @@ console.log(requiredSchemaStore.getRow('pets', 'felix'));
21
27
  // -> {}
22
28
  ```
23
29
 
24
- <h2 id="custom-sorting">Custom Sorting</h2><p>This release adds custom sorting for sorted <a href="https://tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> <a href="https://tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> APIs, so applications can opt into numeric or domain-specific ordering without changing TinyBase&#x27;s existing alphanumeric default behavior.</p><p>The <a href="https://tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/getter/getsortedrowids/"><code>getSortedRowIds</code></a> method and <a href="https://tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/listener/addsortedrowidslistener/"><code>addSortedRowIdsListener</code></a> method now support a custom <code>sorter</code> function in the <a href="https://tinybase.org/api/store/type-aliases/store/sortedrowidsargs/"><code>SortedRowIdsArgs</code></a> object. The <a href="https://tinybase.org/api/ui-react/functions/store-hooks/usesortedrowids/"><code>useSortedRowIds</code></a> hook and getSortedRowIds Svelte function also accept the sorter positionally (<a href="https://github.com/tinyplex/tinybase/issues/190">#190</a>, <a href="https://github.com/tinyplex/tinybase/issues/213">#213</a>).</p>
30
+ <p>The v9.1.1 patch also updates the schematizers for Zod, Valibot, ArkType, TypeBox, Yup, and Effect Schema so that required fields in those libraries are reflected as <code>required: true</code> in the generated TinyBase schemas.</p><h2 id="custom-sorting">Custom Sorting</h2><p>This release adds custom sorting for sorted <a href="https://tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> <a href="https://tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> APIs, so applications can opt into numeric or domain-specific ordering without changing TinyBase&#x27;s existing alphanumeric default behavior.</p><p>The <a href="https://tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/getter/getsortedrowids/"><code>getSortedRowIds</code></a> method and <a href="https://tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/methods/listener/addsortedrowidslistener/"><code>addSortedRowIdsListener</code></a> method now support a custom <code>sorter</code> function in the <a href="https://tinybase.org/api/store/type-aliases/store/sortedrowidsargs/"><code>SortedRowIdsArgs</code></a> object. The <a href="https://tinybase.org/api/ui-react/functions/store-hooks/usesortedrowids/"><code>useSortedRowIds</code></a> hook and getSortedRowIds Svelte function also accept the sorter positionally (<a href="https://github.com/tinyplex/tinybase/issues/190">#190</a>, <a href="https://github.com/tinyplex/tinybase/issues/213">#213</a>).</p>
25
31
 
26
32
  ```js
27
33
  const numericSortStore = createStore();
@@ -8,6 +8,7 @@ const ARRAY = 'array';
8
8
  const TYPE = 'type';
9
9
  const DEFAULT = 'default';
10
10
  const ALLOW_NULL = 'allowNull';
11
+ const REQUIRED = 'required';
11
12
 
12
13
  const getIfNotFunction = (predicate) => (value, then, otherwise) =>
13
14
  predicate(value)
@@ -44,9 +45,14 @@ const objForEach = (obj, cb) =>
44
45
  const objSize = (obj) => size(objIds(obj));
45
46
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
46
47
 
47
- const createCustomSchematizer = (unwrapSchema, getProperties) => {
48
- const toCellOrValueSchema = (schema) => {
49
- const [unwrapped, defaultValue, allowNull] = unwrapSchema(schema);
48
+ const createCustomSchematizer = (
49
+ unwrapSchema,
50
+ getProperties,
51
+ getPropertyRequired,
52
+ ) => {
53
+ const toCellOrValueSchema = (schema, required) => {
54
+ const [unwrapped, defaultValue, allowNull, unwrappedRequired = required] =
55
+ unwrapSchema(schema, void 0, void 0, required);
50
56
  const type = unwrapped?.type;
51
57
  if (
52
58
  type !== STRING &&
@@ -64,6 +70,9 @@ const createCustomSchematizer = (unwrapSchema, getProperties) => {
64
70
  if (allowNull) {
65
71
  cellOrValueSchema[ALLOW_NULL] = true;
66
72
  }
73
+ if (unwrappedRequired && isUndefined(defaultValue)) {
74
+ cellOrValueSchema[REQUIRED] = true;
75
+ }
67
76
  return cellOrValueSchema;
68
77
  };
69
78
  const toTablesSchema = (schemas) => {
@@ -72,9 +81,15 @@ const createCustomSchematizer = (unwrapSchema, getProperties) => {
72
81
  const tableSchema = objNew();
73
82
  ifNotUndefined(getProperties(schema), (properties) =>
74
83
  objForEach(properties, (cellSchema, cellId) =>
75
- ifNotUndefined(toCellOrValueSchema(cellSchema), (cellSchema2) => {
76
- tableSchema[cellId] = cellSchema2;
77
- }),
84
+ ifNotUndefined(
85
+ toCellOrValueSchema(
86
+ cellSchema,
87
+ getPropertyRequired?.(schema, cellId, cellSchema),
88
+ ),
89
+ (cellSchema2) => {
90
+ tableSchema[cellId] = cellSchema2;
91
+ },
92
+ ),
78
93
  ),
79
94
  );
80
95
  if (!objIsEmpty(tableSchema)) {
@@ -58,9 +58,14 @@ const objForEach = (obj, cb) =>
58
58
  const objSize = (obj) => size(objIds(obj));
59
59
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
60
60
 
61
- const createCustomSchematizer = (unwrapSchema, getProperties) => {
62
- const toCellOrValueSchema = (schema) => {
63
- const [unwrapped, defaultValue, allowNull] = unwrapSchema(schema);
61
+ const createCustomSchematizer = (
62
+ unwrapSchema,
63
+ getProperties,
64
+ getPropertyRequired,
65
+ ) => {
66
+ const toCellOrValueSchema = (schema, required) => {
67
+ const [unwrapped, defaultValue, allowNull, unwrappedRequired = required] =
68
+ unwrapSchema(schema, void 0, void 0, required);
64
69
  const type = unwrapped?.type;
65
70
  if (
66
71
  type !== STRING &&
@@ -78,6 +83,9 @@ const createCustomSchematizer = (unwrapSchema, getProperties) => {
78
83
  if (allowNull) {
79
84
  cellOrValueSchema[ALLOW_NULL] = true;
80
85
  }
86
+ if (unwrappedRequired && isUndefined(defaultValue)) {
87
+ cellOrValueSchema[REQUIRED] = true;
88
+ }
81
89
  return cellOrValueSchema;
82
90
  };
83
91
  const toTablesSchema = (schemas) => {
@@ -86,9 +94,15 @@ const createCustomSchematizer = (unwrapSchema, getProperties) => {
86
94
  const tableSchema = objNew();
87
95
  ifNotUndefined(getProperties(schema), (properties) =>
88
96
  objForEach(properties, (cellSchema, cellId) =>
89
- ifNotUndefined(toCellOrValueSchema(cellSchema), (cellSchema2) => {
90
- tableSchema[cellId] = cellSchema2;
91
- }),
97
+ ifNotUndefined(
98
+ toCellOrValueSchema(
99
+ cellSchema,
100
+ getPropertyRequired?.(schema, cellId, cellSchema),
101
+ ),
102
+ (cellSchema2) => {
103
+ tableSchema[cellId] = cellSchema2;
104
+ },
105
+ ),
92
106
  ),
93
107
  );
94
108
  if (!objIsEmpty(tableSchema)) {
@@ -112,7 +126,7 @@ const createCustomSchematizer = (unwrapSchema, getProperties) => {
112
126
  });
113
127
  };
114
128
 
115
- const unwrapSchema = (schema, defaultValue, allowNull) => {
129
+ const unwrapSchema = (schema, defaultValue, allowNull, required = true) => {
116
130
  const schemaData = schema?.json ?? schema;
117
131
  if (isArray(schemaData)) {
118
132
  const hasNull = !arrayEvery(
@@ -124,10 +138,10 @@ const unwrapSchema = (schema, defaultValue, allowNull) => {
124
138
  isFalse(schemaData[0]?.[UNIT]) &&
125
139
  isTrue(schemaData[1]?.[UNIT])
126
140
  ) {
127
- return [{[TYPE]: BOOLEAN}, defaultValue, allowNull ?? false];
141
+ return [{[TYPE]: BOOLEAN}, defaultValue, allowNull ?? false, required];
128
142
  }
129
143
  if (arrayEvery(schemaData, (item) => isString(item?.[UNIT] ?? item))) {
130
- return [{[TYPE]: STRING}, defaultValue, allowNull ?? false];
144
+ return [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required];
131
145
  }
132
146
  if (hasNull) {
133
147
  const nonNullItem = arrayFind(
@@ -135,20 +149,21 @@ const unwrapSchema = (schema, defaultValue, allowNull) => {
135
149
  (item) => !isNull(item?.[UNIT]) && !isNull(item) && item !== '=',
136
150
  );
137
151
  if (nonNullItem) {
138
- return unwrapSchema(nonNullItem, defaultValue, true);
152
+ return unwrapSchema(nonNullItem, defaultValue, true, required);
139
153
  }
140
154
  }
141
155
  }
142
156
  if (!isArray(schemaData) && !isUndefined(schemaData?.[SEQUENCE])) {
143
- return [{[TYPE]: ARRAY}, defaultValue, allowNull ?? false];
157
+ return [{[TYPE]: ARRAY}, defaultValue, allowNull ?? false, required];
144
158
  }
145
159
  if (!isArray(schemaData) && isString(schemaData?.[UNIT])) {
146
- return [{[TYPE]: STRING}, defaultValue, allowNull ?? false];
160
+ return [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required];
147
161
  }
148
162
  return [
149
163
  {[TYPE]: schemaData?.[DOMAIN] || schemaData},
150
164
  defaultValue,
151
165
  allowNull ?? false,
166
+ required,
152
167
  ];
153
168
  };
154
169
  const getProperties = (schema) => {
@@ -170,17 +185,37 @@ const getProperties = (schema) => {
170
185
  }
171
186
  return objIsEmpty(properties) ? void 0 : properties;
172
187
  };
173
- const unwrapSchemaWithDefaults = (schema, defaultValue, allowNull) => {
188
+ const getPropertyRequired = (schema, fieldId) => {
189
+ const schemaData = schema?.json ?? schema;
190
+ return isArray(schemaData?.[REQUIRED]) || isArray(schemaData?.[OPTIONAL])
191
+ ? !isUndefined(
192
+ arrayFind(
193
+ schemaData?.[REQUIRED] ?? [],
194
+ (field) => field[KEY] === fieldId,
195
+ ),
196
+ )
197
+ : void 0;
198
+ };
199
+ const unwrapSchemaWithDefaults = (
200
+ schema,
201
+ defaultValue,
202
+ allowNull,
203
+ required = true,
204
+ ) => {
174
205
  if (isArray(schema) && size(schema) === 3 && schema[1] === '=') {
175
206
  const schemaValue = schema[0]?.json ?? schema[0];
176
- return unwrapSchema(schemaValue, schema[2], allowNull);
207
+ return unwrapSchema(schemaValue, schema[2], allowNull, false);
177
208
  }
178
209
  if (schema?.[_VALUE] && !isUndefined(schema?.[DEFAULT])) {
179
- return unwrapSchema(schema[_VALUE], schema[DEFAULT], allowNull);
210
+ return unwrapSchema(schema[_VALUE], schema[DEFAULT], allowNull, false);
180
211
  }
181
- return unwrapSchema(schema, defaultValue, allowNull);
212
+ return unwrapSchema(schema, defaultValue, allowNull, required);
182
213
  };
183
214
  const createArkTypeSchematizer = () =>
184
- createCustomSchematizer(unwrapSchemaWithDefaults, getProperties);
215
+ createCustomSchematizer(
216
+ unwrapSchemaWithDefaults,
217
+ getProperties,
218
+ getPropertyRequired,
219
+ );
185
220
 
186
221
  export {createArkTypeSchematizer};