tinybase 6.7.4 → 6.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents.md +281 -0
- package/package.json +1 -1
- package/readme.md +1 -1
- package/releases.md +1 -1
package/agents.md
CHANGED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Agents Guide
|
|
2
|
+
|
|
3
|
+
This file follows the [agents.md](https://agents.md/) specification for AI agent
|
|
4
|
+
context. If you're a human reading this, it provides a comprehensive overview of
|
|
5
|
+
the TinyBase project for AI assistants working with the codebase.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
**TinyBase** is a reactive data store and sync engine for local-first
|
|
10
|
+
applications. It is a TypeScript library that provides a reactive, in-memory
|
|
11
|
+
data store with a powerful synchronization engine. It's designed for building
|
|
12
|
+
local-first applications that work offline and sync across devices. The library
|
|
13
|
+
is exceptionally small (5.3kB-11.7kB), has zero runtime dependencies, and
|
|
14
|
+
maintains 100% test coverage.
|
|
15
|
+
|
|
16
|
+
- **Website**: https://tinybase.org
|
|
17
|
+
- **Repository**: https://github.com/tinyplex/tinybase
|
|
18
|
+
- **Documentation**: https://tinybase.org/api/
|
|
19
|
+
- **License**: MIT
|
|
20
|
+
- **Author**: James Pearce (@jamesgpearce)
|
|
21
|
+
|
|
22
|
+
## Core Concepts
|
|
23
|
+
|
|
24
|
+
### Data Store
|
|
25
|
+
|
|
26
|
+
TinyBase provides two types of data structures:
|
|
27
|
+
|
|
28
|
+
- **Tables**: Tabular data organized as Table → Row → Cell (similar to
|
|
29
|
+
relational databases)
|
|
30
|
+
- **Values**: Simple key-value pairs for application state
|
|
31
|
+
|
|
32
|
+
Both can coexist in the same Store and support optional schemas with type
|
|
33
|
+
enforcement.
|
|
34
|
+
|
|
35
|
+
### Reactivity
|
|
36
|
+
|
|
37
|
+
The library implements a fine-grained reactive system where you can listen to
|
|
38
|
+
changes at any level:
|
|
39
|
+
|
|
40
|
+
- Entire store changes
|
|
41
|
+
- Table/value additions or removals
|
|
42
|
+
- Row changes within a table
|
|
43
|
+
- Individual cell or value changes
|
|
44
|
+
|
|
45
|
+
Listeners fire automatically when data changes, enabling efficient UI updates
|
|
46
|
+
that only re-render affected components.
|
|
47
|
+
|
|
48
|
+
### Synchronization
|
|
49
|
+
|
|
50
|
+
TinyBase includes native CRDT (Conflict-free Replicated Data Type) support via
|
|
51
|
+
the MergeableStore, allowing deterministic synchronization across multiple
|
|
52
|
+
clients and servers using Hybrid Logical Clocks for causality tracking.
|
|
53
|
+
|
|
54
|
+
## Key Features
|
|
55
|
+
|
|
56
|
+
### Data Management
|
|
57
|
+
|
|
58
|
+
- **Schemas**: Optional TypeScript-inferred schemas for type safety
|
|
59
|
+
- **Indexes**: Fast lookups by cell values with slice-based grouping
|
|
60
|
+
- **Queries**: SQL-like query engine (select, join, filter, group) without
|
|
61
|
+
actual SQL
|
|
62
|
+
- **Relationships**: Define foreign-key relationships between tables
|
|
63
|
+
- **Metrics**: Built-in aggregations (sum, avg, min, max)
|
|
64
|
+
- **Checkpoints**: Undo/redo functionality with branching support
|
|
65
|
+
|
|
66
|
+
### Persistence
|
|
67
|
+
|
|
68
|
+
Multiple storage backends supported via Persisters:
|
|
69
|
+
|
|
70
|
+
- **Browser**: LocalStorage, SessionStorage, IndexedDB, OPFS
|
|
71
|
+
- **Databases**: SQLite (Bun, WASM, sqlite3), PostgreSQL, PGlite, Turso (libSQL)
|
|
72
|
+
- **Third-party**: ElectricSQL, PowerSync, CR-SQLite
|
|
73
|
+
- **Cloud**: PartyKit, Cloudflare Durable Objects
|
|
74
|
+
- **Files**: Node.js file system
|
|
75
|
+
- **CRDT**: Yjs, Automerge integration
|
|
76
|
+
- **React Native**: MMKV, SQLite
|
|
77
|
+
|
|
78
|
+
### Synchronization
|
|
79
|
+
|
|
80
|
+
Synchronizers enable real-time data sync:
|
|
81
|
+
|
|
82
|
+
- WebSocket (client and server)
|
|
83
|
+
- BroadcastChannel (same-origin tabs)
|
|
84
|
+
- Local (in-memory for testing)
|
|
85
|
+
- Custom transports (extensible)
|
|
86
|
+
|
|
87
|
+
### React Integration
|
|
88
|
+
|
|
89
|
+
Optional `ui-react` module provides:
|
|
90
|
+
|
|
91
|
+
- **Hooks**: `useCell`, `useRow`, `useTable`, `useTables`, `useValue`, etc.
|
|
92
|
+
- **Components**: Pre-built reactive views for data rendering
|
|
93
|
+
- **Context**: Multi-store support with ID-based contexts
|
|
94
|
+
- **DOM Components**: `ui-react-dom` with interactive tables
|
|
95
|
+
- **Inspector**: Developer tools overlay for debugging
|
|
96
|
+
|
|
97
|
+
## Architecture
|
|
98
|
+
|
|
99
|
+
### Modular Design
|
|
100
|
+
|
|
101
|
+
TinyBase uses a modular architecture where each feature is an independent module
|
|
102
|
+
that can be imported separately:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
tinybase # Core store module
|
|
106
|
+
tinybase/indexes # Indexing
|
|
107
|
+
tinybase/queries # Query engine
|
|
108
|
+
tinybase/relationships # Relationships
|
|
109
|
+
tinybase/metrics # Aggregations
|
|
110
|
+
tinybase/checkpoints # Undo/redo
|
|
111
|
+
tinybase/mergeable-store # CRDT support
|
|
112
|
+
tinybase/persisters/persister-* # Storage backends
|
|
113
|
+
tinybase/synchronizers/synchronizer-* # Sync transports
|
|
114
|
+
tinybase/ui-react # React hooks
|
|
115
|
+
tinybase/ui-react-dom # React DOM components
|
|
116
|
+
tinybase/ui-react-inspector # DevTools
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Type System
|
|
120
|
+
|
|
121
|
+
Strong TypeScript support with:
|
|
122
|
+
|
|
123
|
+
- Generic types that infer from schemas
|
|
124
|
+
- Conditional types for schema-aware APIs
|
|
125
|
+
- Mapped types for compile-time validation
|
|
126
|
+
- Type-safe hooks and components
|
|
127
|
+
|
|
128
|
+
### Build System
|
|
129
|
+
|
|
130
|
+
- **Gulp**: Build orchestration
|
|
131
|
+
- **TypeScript**: Source language with strict mode
|
|
132
|
+
- **Rollup**: Bundling (implied)
|
|
133
|
+
- **ESM**: Primary module format
|
|
134
|
+
- **Tree-shaking**: Aggressive optimization for minimal bundles
|
|
135
|
+
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
### Prerequisites
|
|
139
|
+
|
|
140
|
+
- Node.js >= 23.10.0
|
|
141
|
+
- npm >= 10.9.2
|
|
142
|
+
|
|
143
|
+
### Setup
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
git clone https://github.com/tinyplex/tinybase.git
|
|
147
|
+
cd tinybase
|
|
148
|
+
npm install
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Common Commands
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm run compileAndTestUnit # Compile and run unit tests
|
|
155
|
+
npm run testUnitFast # Quick test iteration
|
|
156
|
+
npm run lint # Run ESLint
|
|
157
|
+
npm run spell # Spell check
|
|
158
|
+
npm run preCommit # Full pre-commit check
|
|
159
|
+
npm run compileDocs # Generate API documentation
|
|
160
|
+
npm run serveDocs # Preview documentation locally
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Testing
|
|
164
|
+
|
|
165
|
+
- **Framework**: Vitest
|
|
166
|
+
- **Coverage**: 100% required (enforced)
|
|
167
|
+
- **Types**: Unit, performance, end-to-end, production
|
|
168
|
+
- **Environment**: happy-dom (unit), puppeteer (e2e)
|
|
169
|
+
|
|
170
|
+
### Code Style
|
|
171
|
+
|
|
172
|
+
- **ESLint**: Enforced with strict rules
|
|
173
|
+
- **Prettier**: Automatic formatting
|
|
174
|
+
- **Max line length**: 80 characters
|
|
175
|
+
- **Quotes**: Single quotes (template literals allowed)
|
|
176
|
+
- **Semicolons**: Required
|
|
177
|
+
- **Object spacing**: No spaces in braces `{key: value}`
|
|
178
|
+
|
|
179
|
+
## Project Structure
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
tinybase/
|
|
183
|
+
├── src/ # Source code
|
|
184
|
+
│ ├── @types/ # TypeScript declarations
|
|
185
|
+
│ ├── store/ # Core store implementation
|
|
186
|
+
│ ├── indexes/ # Indexing module
|
|
187
|
+
│ ├── queries/ # Query engine
|
|
188
|
+
│ ├── relationships/ # Relationships module
|
|
189
|
+
│ ├── metrics/ # Metrics module
|
|
190
|
+
│ ├── checkpoints/ # Checkpoints module
|
|
191
|
+
│ ├── mergeable-store/ # CRDT implementation
|
|
192
|
+
│ ├── persisters/ # Storage backends
|
|
193
|
+
│ ├── synchronizers/ # Sync transports
|
|
194
|
+
│ ├── ui-react/ # React hooks
|
|
195
|
+
│ ├── ui-react-dom/ # React DOM components
|
|
196
|
+
│ ├── ui-react-inspector/ # DevTools
|
|
197
|
+
│ └── common/ # Shared utilities
|
|
198
|
+
├── test/ # Tests
|
|
199
|
+
│ ├── unit/ # Unit tests
|
|
200
|
+
│ ├── perf/ # Performance tests
|
|
201
|
+
│ ├── e2e/ # End-to-end tests
|
|
202
|
+
│ └── prod/ # Production build tests
|
|
203
|
+
├── docs/ # Generated documentation
|
|
204
|
+
├── dist/ # Build output
|
|
205
|
+
├── site/ # Documentation site source
|
|
206
|
+
├── gulpfile.mjs # Build configuration
|
|
207
|
+
├── vitest.config.ts # Test configuration
|
|
208
|
+
├── eslint.config.js # Linting rules
|
|
209
|
+
└── tsconfig.json # TypeScript config
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
Contributions are welcome! This is a spare-time project, so response times may
|
|
215
|
+
vary.
|
|
216
|
+
|
|
217
|
+
**Requirements**:
|
|
218
|
+
|
|
219
|
+
1. Follow the Prettier and ESLint configurations
|
|
220
|
+
2. Maintain 100% test coverage
|
|
221
|
+
3. Update documentation for API changes
|
|
222
|
+
4. Add examples for new features
|
|
223
|
+
|
|
224
|
+
**Process**:
|
|
225
|
+
|
|
226
|
+
1. Fork the repository
|
|
227
|
+
2. Create a feature branch
|
|
228
|
+
3. Make your changes with tests
|
|
229
|
+
4. Run `npm run preCommit` to verify
|
|
230
|
+
5. Submit a pull request
|
|
231
|
+
|
|
232
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
233
|
+
|
|
234
|
+
## Community
|
|
235
|
+
|
|
236
|
+
- **Discord**: https://discord.com/invite/mGz3mevwP8
|
|
237
|
+
- **Discussions**: https://github.com/tinyplex/tinybase/discussions
|
|
238
|
+
- **Issues**: https://github.com/tinyplex/tinybase/issues
|
|
239
|
+
- **Bluesky**: https://bsky.app/profile/tinybase.bsky.social
|
|
240
|
+
- **Twitter/X**: https://x.com/tinybasejs
|
|
241
|
+
|
|
242
|
+
## Use Cases
|
|
243
|
+
|
|
244
|
+
TinyBase is ideal for:
|
|
245
|
+
|
|
246
|
+
- **Local-first applications**: Apps that work offline and sync later
|
|
247
|
+
- **Real-time collaboration**: Multi-user applications with CRDT sync
|
|
248
|
+
- **Reactive UIs**: Applications requiring fine-grained reactivity
|
|
249
|
+
- **Mobile apps**: React Native apps with local storage
|
|
250
|
+
- **Edge computing**: Cloudflare Workers, Durable Objects
|
|
251
|
+
- **Progressive Web Apps**: Offline-capable web applications
|
|
252
|
+
- **Games**: Real-time state management with undo/redo
|
|
253
|
+
- **Data dashboards**: Reactive data visualization
|
|
254
|
+
|
|
255
|
+
## Performance
|
|
256
|
+
|
|
257
|
+
- Tiny bundle sizes (5.3kB - 11.7kB depending on features)
|
|
258
|
+
- Zero runtime dependencies
|
|
259
|
+
- Efficient change detection and listener notification
|
|
260
|
+
- Memory pooling for ID generation
|
|
261
|
+
- Tree-shakeable modular design
|
|
262
|
+
- Optimized for bundle size and runtime performance
|
|
263
|
+
|
|
264
|
+
## Related Projects
|
|
265
|
+
|
|
266
|
+
- **Synclets**: Generic synchronization library (https://synclets.org)
|
|
267
|
+
- **TinyWidgets**: Widget toolkit built on TinyBase (https://tinywidgets.org)
|
|
268
|
+
- **TinyTick**: Reactive ticker tape component (https://tinytick.org)
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
**Note for AI Agents**: TinyBase uses unique patterns including utility function
|
|
277
|
+
wrappers (e.g., `arrayForEach`, `mapGet`, `objHas`) instead of native methods
|
|
278
|
+
for consistency and tree-shaking. Always use factory functions (`createStore`,
|
|
279
|
+
`createIndexes`, etc.) with builder pattern chaining. Maintain 100% test
|
|
280
|
+
coverage and follow the strict 80-character line length. See
|
|
281
|
+
`.github/copilot-instructions.md` for detailed coding patterns.
|
package/package.json
CHANGED
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/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://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"><link rel="preload" as="image" href="https://tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/cpojer.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/beekeeb.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/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="a-reactive-data-store-sync-engine">A <em>reactive</em> data store & <span><em>sync</em> engine</span></h2></section><p><a href="https://tinybase.org/guides/releases/#v6-7"><em>NEW!</em> v6.7 release</a></p><p><span id="one-with">"The one with OPFS!"</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="it-s-reactive">It'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> and <a href="#pre-built-reactive-components">pre-built components</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'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-databases-more">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's Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it's especially great for local-first apps: where data is stored locally on the user's device and that can be run offline. It's tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.3kB - 11.7kB</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><div><a href="https://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://tinybase.org/react.svg?asImg" width="48"> React</a></div><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><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&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&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&logo=bluesky&logoColor=%23fff&color=%23333&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&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/6.7.3" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://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>
|
|
1
|
+
<link rel="preload" as="image" href="https://tinybase.org/react.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://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"><link rel="preload" as="image" href="https://tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/cpojer.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/beekeeb.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/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="a-reactive-data-store-sync-engine">A <em>reactive</em> data store & <span><em>sync</em> engine</span></h2></section><p><a href="https://tinybase.org/guides/releases/#v6-7"><em>NEW!</em> v6.7 release</a></p><p><span id="one-with">"The one with OPFS!"</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="it-s-reactive">It'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> and <a href="#pre-built-reactive-components">pre-built components</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'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-databases-more">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's Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it's especially great for local-first apps: where data is stored locally on the user's device and that can be run offline. It's tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.3kB - 11.7kB</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><div><a href="https://tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://tinybase.org/react.svg?asImg" width="48"> React</a></div><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><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&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&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&logo=bluesky&logoColor=%23fff&color=%23333&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&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/6.7.4" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://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>
|
|
2
2
|
|
|
3
3
|
```js
|
|
4
4
|
import {createStore} from 'tinybase';
|
package/releases.md
CHANGED
|
@@ -477,7 +477,7 @@ const automergePersister = createAutomergePersister(store, docHandler);
|
|
|
477
477
|
|
|
478
478
|
await automergePersister.save();
|
|
479
479
|
// Store will be saved to the document.
|
|
480
|
-
console.log(
|
|
480
|
+
console.log(docHandler.doc());
|
|
481
481
|
// -> {tinybase: {t: {pets: {fido: {species: 'dog'}}}, v: {}}}
|
|
482
482
|
await automergePersister.destroy();
|
|
483
483
|
|