@storion/storion 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -75
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Storion
|
|
2
2
|
|
|
3
|
-
Framework-agnostic client-side database for the browser
|
|
3
|
+
**Framework-agnostic client-side database for the browser.** Use it with React, Vue, Angular, Svelte, or vanilla JS. Create databases, tables, save and fetch records, and run JSON queries on **localStorage**, **sessionStorage**, or **IndexedDB**.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@storion/storion)
|
|
6
|
+
[](https://github.com/storionjs/storion)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Table of contents
|
|
11
|
+
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Install](#install)
|
|
14
|
+
- [Quick start](#quick-start)
|
|
15
|
+
- [Documentation](#documentation)
|
|
16
|
+
- [Database from config](#database-from-config)
|
|
17
|
+
- [Query language](#query-language)
|
|
18
|
+
- [Subscribing to changes](#subscribing-to-changes)
|
|
19
|
+
- [Cross-context sync (e.g. extensions)](#cross-context-sync-eg-extensions)
|
|
20
|
+
- [Storage backends](#storage-backends)
|
|
21
|
+
- [Usage with React / Vue / Angular](#usage-with-react--vue--angular)
|
|
22
|
+
- [API reference](#api-reference)
|
|
23
|
+
- [Links](#links)
|
|
24
|
+
|
|
25
|
+
---
|
|
4
26
|
|
|
5
27
|
## Features
|
|
6
28
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
29
|
+
| Feature | Description |
|
|
30
|
+
|--------|-------------|
|
|
31
|
+
| **Framework-agnostic** | Works with any frontend; no framework-specific code. |
|
|
32
|
+
| **Multiple stores** | Use `localStorage`, `sessionStorage`, or `indexedDB`. |
|
|
33
|
+
| **Tables & schema** | Define tables with columns (int, float, boolean, string, json) and optional foreign keys. |
|
|
34
|
+
| **CRUD** | Insert, fetch, update, and delete records with a simple API. |
|
|
35
|
+
| **Query engine** | Run JSON queries: `where`, `orderBy`, `limit`, `offset`. |
|
|
36
|
+
| **Config from file/URL** | Create a database from a config object or load config from a URL or file. |
|
|
37
|
+
| **Change subscription** | Subscribe to table or row changes so components stay in sync without polling. |
|
|
38
|
+
| **Cross-context** | Optional broadcaster + listener for extensions, background scripts, or multiple tabs. |
|
|
39
|
+
|
|
40
|
+
---
|
|
15
41
|
|
|
16
42
|
## Install
|
|
17
43
|
|
|
@@ -19,12 +45,17 @@ Framework-agnostic client-side database for the browser. Use it with **React**,
|
|
|
19
45
|
npm install @storion/storion
|
|
20
46
|
```
|
|
21
47
|
|
|
48
|
+
- **npm:** [https://www.npmjs.com/package/@storion/storion](https://www.npmjs.com/package/@storion/storion)
|
|
49
|
+
- **Source & issues:** [https://github.com/storionjs/storion](https://github.com/storionjs/storion)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
22
53
|
## Quick start
|
|
23
54
|
|
|
24
55
|
```js
|
|
25
56
|
import { createDatabase } from '@storion/storion';
|
|
26
57
|
|
|
27
|
-
// Create a database
|
|
58
|
+
// Create a database (localStorage, sessionStorage, or indexedDB)
|
|
28
59
|
const db = await createDatabase({
|
|
29
60
|
name: 'myapp',
|
|
30
61
|
storage: 'localStorage'
|
|
@@ -59,13 +90,29 @@ await db.update('users', 1, { name: 'Alice Smith' });
|
|
|
59
90
|
await db.delete('users', 2);
|
|
60
91
|
```
|
|
61
92
|
|
|
62
|
-
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
**Documentation:** https://storionjs.github.io/storion-docs/
|
|
98
|
+
|
|
99
|
+
| Document | Description |
|
|
100
|
+
|----------|-------------|
|
|
101
|
+
| [**API reference**](docs/API.md) | Full API for `createDatabase`, `Database` methods, and helpers. |
|
|
102
|
+
| [**Config format**](docs/CONFIG_FORMAT.md) | How to define tables and databases in a config object or JSON file. |
|
|
103
|
+
| [**Query language**](docs/QUERY_LANGUAGE.md) | `where`, `orderBy`, operators, and examples. |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Database from config
|
|
63
108
|
|
|
64
109
|
You can create a database and its tables from a **config object** (e.g. from a JSON file).
|
|
65
110
|
|
|
66
111
|
### Config in code
|
|
67
112
|
|
|
68
113
|
```js
|
|
114
|
+
import { createDatabase } from '@storion/storion';
|
|
115
|
+
|
|
69
116
|
const config = {
|
|
70
117
|
tables: {
|
|
71
118
|
users: {
|
|
@@ -120,19 +167,21 @@ const db = await createDatabase({
|
|
|
120
167
|
});
|
|
121
168
|
```
|
|
122
169
|
|
|
123
|
-
Config format
|
|
170
|
+
See [Config format](docs/CONFIG_FORMAT.md) for the full schema and options.
|
|
124
171
|
|
|
125
|
-
|
|
172
|
+
---
|
|
126
173
|
|
|
127
|
-
|
|
174
|
+
## Query language
|
|
128
175
|
|
|
129
|
-
|
|
130
|
-
- **orderBy** – Sort: `[{ field, direction: 'asc' | 'desc' }]`
|
|
131
|
-
- **limit** / **offset** – Pagination
|
|
176
|
+
Use `db.query(tableName, query)` with a JSON query object:
|
|
132
177
|
|
|
133
|
-
|
|
178
|
+
| Key | Description |
|
|
179
|
+
|-----|-------------|
|
|
180
|
+
| **where** | Filter: `{ field, op, value }` or `{ and: [...] }` / `{ or: [...] }`. |
|
|
181
|
+
| **orderBy** | Sort: `[{ field, direction: 'asc' \| 'desc' }]`. |
|
|
182
|
+
| **limit** / **offset** | Pagination. |
|
|
134
183
|
|
|
135
|
-
|
|
184
|
+
**Operators:** `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `contains`, `startsWith`, `endsWith`, `in`, `notIn`, `isNull`, `isNotNull`.
|
|
136
185
|
|
|
137
186
|
```js
|
|
138
187
|
const { rows, totalCount } = await db.query('users', {
|
|
@@ -148,11 +197,13 @@ const { rows, totalCount } = await db.query('users', {
|
|
|
148
197
|
});
|
|
149
198
|
```
|
|
150
199
|
|
|
151
|
-
Full reference: [
|
|
200
|
+
Full reference: [Query language](docs/QUERY_LANGUAGE.md).
|
|
201
|
+
|
|
202
|
+
---
|
|
152
203
|
|
|
153
204
|
## Subscribing to changes
|
|
154
205
|
|
|
155
|
-
When multiple components share the same `Database` instance, they can subscribe to change events so that when one component inserts, updates, or deletes data, the others receive an event and can refresh
|
|
206
|
+
When multiple components share the same `Database` instance, they can subscribe to change events so that when one component inserts, updates, or deletes data, the others receive an event and can refresh—without polling.
|
|
156
207
|
|
|
157
208
|
```js
|
|
158
209
|
const db = await createDatabase({ name: 'myapp', storage: 'localStorage' });
|
|
@@ -163,99 +214,79 @@ const unsubscribe = db.subscribe('todos', (event) => {
|
|
|
163
214
|
// Refresh your UI or state here
|
|
164
215
|
});
|
|
165
216
|
|
|
166
|
-
//
|
|
167
|
-
//
|
|
217
|
+
// Subscribe to all tables: db.subscribe((event) => { ... })
|
|
218
|
+
// Subscribe to one row: db.subscribe('todos', 1, (event) => { ... })
|
|
168
219
|
|
|
169
|
-
// When done:
|
|
220
|
+
// When done:
|
|
221
|
+
unsubscribe();
|
|
170
222
|
```
|
|
171
223
|
|
|
172
|
-
|
|
224
|
+
See [API — db.subscribe](docs/API.md) for details.
|
|
173
225
|
|
|
174
|
-
|
|
226
|
+
---
|
|
175
227
|
|
|
176
|
-
|
|
228
|
+
## Cross-context sync (e.g. extensions)
|
|
229
|
+
|
|
230
|
+
Use Storion in one context (e.g. Chrome extension or background script) and stream change events to another (e.g. web app UI) with a broadcaster + listener.
|
|
177
231
|
|
|
178
232
|
```js
|
|
179
233
|
import { createDatabase, createChangeListener } from '@storion/storion';
|
|
180
234
|
|
|
181
|
-
// 1) Producer
|
|
235
|
+
// 1) Producer (e.g. extension popup/background)
|
|
182
236
|
const db = await createDatabase({ name: 'myapp', storage: 'localStorage' });
|
|
183
237
|
|
|
184
|
-
// Forward normalized StorionChangeEvent payloads to the active tab.
|
|
185
238
|
db.setChangeBroadcaster({
|
|
186
239
|
async broadcastChange(event) {
|
|
187
|
-
if (typeof chrome !== 'undefined' && chrome.tabs
|
|
188
|
-
// Chrome extension context: send to the active tab's content script
|
|
240
|
+
if (typeof chrome !== 'undefined' && chrome.tabs?.query) {
|
|
189
241
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
|
190
|
-
const tab = tabs
|
|
191
|
-
if (
|
|
192
|
-
chrome.tabs.sendMessage(tab.id, { action: 'storionChangeEvent', event });
|
|
242
|
+
const tab = tabs?.[0];
|
|
243
|
+
if (tab?.id) chrome.tabs.sendMessage(tab.id, { action: 'storionChangeEvent', event });
|
|
193
244
|
});
|
|
194
245
|
} else {
|
|
195
|
-
// Fallback: same-window postMessage (e.g. two iframes or tabs using BroadcastChannel)
|
|
196
246
|
window.postMessage({ source: 'storion-change', payload: event }, '*');
|
|
197
247
|
}
|
|
198
248
|
}
|
|
199
249
|
});
|
|
200
250
|
|
|
201
|
-
// 2) Consumer
|
|
251
|
+
// 2) Consumer (e.g. web app or another tab)
|
|
202
252
|
const transport = {
|
|
203
253
|
onMessage(handler) {
|
|
204
|
-
|
|
205
|
-
if (
|
|
254
|
+
const listener = (ev) => {
|
|
255
|
+
if (ev.data?.source !== 'storion-change') return;
|
|
206
256
|
handler(ev.data.payload);
|
|
207
|
-
}
|
|
257
|
+
};
|
|
208
258
|
window.addEventListener('message', listener);
|
|
209
259
|
return () => window.removeEventListener('message', listener);
|
|
210
260
|
}
|
|
211
261
|
};
|
|
212
262
|
|
|
213
263
|
const stop = createChangeListener(transport, (event) => {
|
|
214
|
-
// React to inserts/updates/deletes coming from another context
|
|
215
264
|
console.log('Cross-context change:', event.type, event.tableName, event.row);
|
|
216
265
|
});
|
|
217
|
-
|
|
218
|
-
// later, when you no longer need updates:
|
|
219
|
-
// stop();
|
|
266
|
+
// Later: stop();
|
|
220
267
|
```
|
|
221
268
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
## API overview
|
|
225
|
-
|
|
226
|
-
| Method | Description |
|
|
227
|
-
|--------|-------------|
|
|
228
|
-
| `createDatabase(options)` | Create or connect to a DB (name, storage, optional config). |
|
|
229
|
-
| `loadConfigFromUrl(url)` | Fetch config JSON from a URL. |
|
|
230
|
-
| `loadConfigFromFile(file)` | Read config from a File (e.g. file input). |
|
|
231
|
-
| `db.createTable(name, columns)` | Create a table. |
|
|
232
|
-
| `db.listTables()` | List table names. |
|
|
233
|
-
| `db.getTable(name)` | Get table structure and rows. |
|
|
234
|
-
| `db.insert(table, row)` | Insert a row (id auto if omitted). |
|
|
235
|
-
| `db.fetch(table, options?)` | Fetch rows (optional filter, sort, limit). |
|
|
236
|
-
| `db.query(table, query)` | Run JSON query; returns `{ rows, totalCount }`. |
|
|
237
|
-
| `db.update(table, id, data)` | Update a row by id. |
|
|
238
|
-
| `db.delete(table, id)` | Delete a row by id. |
|
|
239
|
-
| `db.deleteTable(name)` | Delete a table. |
|
|
240
|
-
| `db.exportConfig()` | Export DB as config-like object. |
|
|
241
|
-
| `db.subscribe(callback)` / `db.subscribe(table, callback)` / `db.subscribe(table, rowId, callback)` | Subscribe to change events; returns `unsubscribe()`. |
|
|
242
|
-
| `db.unsubscribe(id)` | Remove a subscription by id. |
|
|
243
|
-
| `db.setChangeBroadcaster(broadcaster)` | Optional: broadcast changes to another context (e.g. extension ↔ page). |
|
|
244
|
-
| `createChangeListener(transport, onChange)` | Listen for change events coming from another context via a custom transport. |
|
|
269
|
+
See [API — createChangeListener](docs/API.md) and [API — setChangeBroadcaster](docs/API.md) for details.
|
|
245
270
|
|
|
246
|
-
|
|
271
|
+
---
|
|
247
272
|
|
|
248
273
|
## Storage backends
|
|
249
274
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
275
|
+
| Backend | Description |
|
|
276
|
+
|---------|-------------|
|
|
277
|
+
| **localStorage** | Persists across sessions; same origin; ~5MB typical. |
|
|
278
|
+
| **sessionStorage** | Cleared when the tab/window closes; same origin. |
|
|
279
|
+
| **indexedDB** | Async; larger quota; good for bigger datasets. |
|
|
253
280
|
|
|
254
281
|
All data for a given storage key is stored in one place (default key: `__LS_DB__`). Multiple logical databases (different `name`s) can coexist under the same key.
|
|
255
282
|
|
|
283
|
+
---
|
|
284
|
+
|
|
256
285
|
## Usage with React / Vue / Angular
|
|
257
286
|
|
|
258
|
-
Use the same API in any framework. Share one `Database` instance (e.g. via context, service, or singleton) so
|
|
287
|
+
Use the same API in any framework. Share one `Database` instance (e.g. via context, service, or singleton) so `db.subscribe()` keeps all components in sync.
|
|
288
|
+
|
|
289
|
+
**Example with React:**
|
|
259
290
|
|
|
260
291
|
```js
|
|
261
292
|
import { createDatabase } from '@storion/storion';
|
|
@@ -290,8 +321,41 @@ function UserList() {
|
|
|
290
321
|
}
|
|
291
322
|
```
|
|
292
323
|
|
|
293
|
-
No framework-specific bindings—
|
|
324
|
+
No framework-specific bindings—call the async API and set state as needed.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## API reference
|
|
329
|
+
|
|
330
|
+
| Method / API | Description |
|
|
331
|
+
|--------------|-------------|
|
|
332
|
+
| `createDatabase(options)` | Create or connect to a DB (name, storage, optional config). |
|
|
333
|
+
| `loadConfigFromUrl(url)` | Fetch config JSON from a URL. |
|
|
334
|
+
| `loadConfigFromFile(file)` | Read config from a `File` (e.g. file input). |
|
|
335
|
+
| `db.createTable(name, columns)` | Create a table. |
|
|
336
|
+
| `db.listTables()` | List table names. |
|
|
337
|
+
| `db.getTable(name)` | Get table structure and rows. |
|
|
338
|
+
| `db.insert(table, row)` | Insert a row (id auto if omitted). |
|
|
339
|
+
| `db.fetch(table, options?)` | Fetch rows (optional filter, sort, limit). |
|
|
340
|
+
| `db.query(table, query)` | Run JSON query; returns `{ rows, totalCount }`. |
|
|
341
|
+
| `db.update(table, id, data)` | Update a row by id. |
|
|
342
|
+
| `db.delete(table, id)` | Delete a row by id. |
|
|
343
|
+
| `db.deleteTable(name)` | Delete a table. |
|
|
344
|
+
| `db.exportConfig()` | Export DB as config-like object. |
|
|
345
|
+
| `db.subscribe(callback)` / `db.subscribe(table, callback)` / `db.subscribe(table, rowId, callback)` | Subscribe to change events; returns `unsubscribe()`. |
|
|
346
|
+
| `db.unsubscribe(id)` | Remove a subscription by id. |
|
|
347
|
+
| `db.setChangeBroadcaster(broadcaster)` | Optional: broadcast changes to another context. |
|
|
348
|
+
| `createChangeListener(transport, onChange)` | Listen for change events from another context via a custom transport. |
|
|
349
|
+
|
|
350
|
+
Full details: [API reference](docs/API.md).
|
|
351
|
+
|
|
352
|
+
---
|
|
294
353
|
|
|
295
|
-
##
|
|
354
|
+
## Links
|
|
296
355
|
|
|
297
|
-
|
|
356
|
+
| Resource | URL |
|
|
357
|
+
|----------|-----|
|
|
358
|
+
| **GitHub** | [https://github.com/storionjs/storion](https://github.com/storionjs/storion) |
|
|
359
|
+
| **npm** | [https://www.npmjs.com/package/@storion/storion](https://www.npmjs.com/package/@storion/storion) |
|
|
360
|
+
| **Issues** | [https://github.com/storionjs/storion/issues](https://github.com/storionjs/storion/issues) |
|
|
361
|
+
| **License** | MIT |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storion/storion",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Framework-agnostic client-side database with localStorage, sessionStorage, and IndexedDB. Create databases, tables, save/fetch records, and run JSON queries.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|