@storion/storion 1.0.0 → 1.0.1
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 +137 -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,27 @@ 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
|
+
| Document | Description |
|
|
98
|
+
|----------|-------------|
|
|
99
|
+
| [**API reference**](docs/API.md) | Full API for `createDatabase`, `Database` methods, and helpers. |
|
|
100
|
+
| [**Config format**](docs/CONFIG_FORMAT.md) | How to define tables and databases in a config object or JSON file. |
|
|
101
|
+
| [**Query language**](docs/QUERY_LANGUAGE.md) | `where`, `orderBy`, operators, and examples. |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Database from config
|
|
63
106
|
|
|
64
107
|
You can create a database and its tables from a **config object** (e.g. from a JSON file).
|
|
65
108
|
|
|
66
109
|
### Config in code
|
|
67
110
|
|
|
68
111
|
```js
|
|
112
|
+
import { createDatabase } from '@storion/storion';
|
|
113
|
+
|
|
69
114
|
const config = {
|
|
70
115
|
tables: {
|
|
71
116
|
users: {
|
|
@@ -120,19 +165,21 @@ const db = await createDatabase({
|
|
|
120
165
|
});
|
|
121
166
|
```
|
|
122
167
|
|
|
123
|
-
Config format
|
|
168
|
+
See [Config format](docs/CONFIG_FORMAT.md) for the full schema and options.
|
|
124
169
|
|
|
125
|
-
|
|
170
|
+
---
|
|
126
171
|
|
|
127
|
-
|
|
172
|
+
## Query language
|
|
128
173
|
|
|
129
|
-
|
|
130
|
-
- **orderBy** – Sort: `[{ field, direction: 'asc' | 'desc' }]`
|
|
131
|
-
- **limit** / **offset** – Pagination
|
|
174
|
+
Use `db.query(tableName, query)` with a JSON query object:
|
|
132
175
|
|
|
133
|
-
|
|
176
|
+
| Key | Description |
|
|
177
|
+
|-----|-------------|
|
|
178
|
+
| **where** | Filter: `{ field, op, value }` or `{ and: [...] }` / `{ or: [...] }`. |
|
|
179
|
+
| **orderBy** | Sort: `[{ field, direction: 'asc' \| 'desc' }]`. |
|
|
180
|
+
| **limit** / **offset** | Pagination. |
|
|
134
181
|
|
|
135
|
-
|
|
182
|
+
**Operators:** `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `contains`, `startsWith`, `endsWith`, `in`, `notIn`, `isNull`, `isNotNull`.
|
|
136
183
|
|
|
137
184
|
```js
|
|
138
185
|
const { rows, totalCount } = await db.query('users', {
|
|
@@ -148,11 +195,13 @@ const { rows, totalCount } = await db.query('users', {
|
|
|
148
195
|
});
|
|
149
196
|
```
|
|
150
197
|
|
|
151
|
-
Full reference: [
|
|
198
|
+
Full reference: [Query language](docs/QUERY_LANGUAGE.md).
|
|
199
|
+
|
|
200
|
+
---
|
|
152
201
|
|
|
153
202
|
## Subscribing to changes
|
|
154
203
|
|
|
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
|
|
204
|
+
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
205
|
|
|
157
206
|
```js
|
|
158
207
|
const db = await createDatabase({ name: 'myapp', storage: 'localStorage' });
|
|
@@ -163,99 +212,79 @@ const unsubscribe = db.subscribe('todos', (event) => {
|
|
|
163
212
|
// Refresh your UI or state here
|
|
164
213
|
});
|
|
165
214
|
|
|
166
|
-
//
|
|
167
|
-
//
|
|
215
|
+
// Subscribe to all tables: db.subscribe((event) => { ... })
|
|
216
|
+
// Subscribe to one row: db.subscribe('todos', 1, (event) => { ... })
|
|
168
217
|
|
|
169
|
-
// When done:
|
|
218
|
+
// When done:
|
|
219
|
+
unsubscribe();
|
|
170
220
|
```
|
|
171
221
|
|
|
172
|
-
|
|
222
|
+
See [API — db.subscribe](docs/API.md) for details.
|
|
223
|
+
|
|
224
|
+
---
|
|
173
225
|
|
|
174
|
-
## Cross-context sync (
|
|
226
|
+
## Cross-context sync (e.g. extensions)
|
|
175
227
|
|
|
176
|
-
Storion
|
|
228
|
+
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
229
|
|
|
178
230
|
```js
|
|
179
231
|
import { createDatabase, createChangeListener } from '@storion/storion';
|
|
180
232
|
|
|
181
|
-
// 1) Producer
|
|
233
|
+
// 1) Producer (e.g. extension popup/background)
|
|
182
234
|
const db = await createDatabase({ name: 'myapp', storage: 'localStorage' });
|
|
183
235
|
|
|
184
|
-
// Forward normalized StorionChangeEvent payloads to the active tab.
|
|
185
236
|
db.setChangeBroadcaster({
|
|
186
237
|
async broadcastChange(event) {
|
|
187
|
-
if (typeof chrome !== 'undefined' && chrome.tabs
|
|
188
|
-
// Chrome extension context: send to the active tab's content script
|
|
238
|
+
if (typeof chrome !== 'undefined' && chrome.tabs?.query) {
|
|
189
239
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
|
190
|
-
const tab = tabs
|
|
191
|
-
if (
|
|
192
|
-
chrome.tabs.sendMessage(tab.id, { action: 'storionChangeEvent', event });
|
|
240
|
+
const tab = tabs?.[0];
|
|
241
|
+
if (tab?.id) chrome.tabs.sendMessage(tab.id, { action: 'storionChangeEvent', event });
|
|
193
242
|
});
|
|
194
243
|
} else {
|
|
195
|
-
// Fallback: same-window postMessage (e.g. two iframes or tabs using BroadcastChannel)
|
|
196
244
|
window.postMessage({ source: 'storion-change', payload: event }, '*');
|
|
197
245
|
}
|
|
198
246
|
}
|
|
199
247
|
});
|
|
200
248
|
|
|
201
|
-
// 2) Consumer
|
|
249
|
+
// 2) Consumer (e.g. web app or another tab)
|
|
202
250
|
const transport = {
|
|
203
251
|
onMessage(handler) {
|
|
204
|
-
|
|
205
|
-
if (
|
|
252
|
+
const listener = (ev) => {
|
|
253
|
+
if (ev.data?.source !== 'storion-change') return;
|
|
206
254
|
handler(ev.data.payload);
|
|
207
|
-
}
|
|
255
|
+
};
|
|
208
256
|
window.addEventListener('message', listener);
|
|
209
257
|
return () => window.removeEventListener('message', listener);
|
|
210
258
|
}
|
|
211
259
|
};
|
|
212
260
|
|
|
213
261
|
const stop = createChangeListener(transport, (event) => {
|
|
214
|
-
// React to inserts/updates/deletes coming from another context
|
|
215
262
|
console.log('Cross-context change:', event.type, event.tableName, event.row);
|
|
216
263
|
});
|
|
217
|
-
|
|
218
|
-
// later, when you no longer need updates:
|
|
219
|
-
// stop();
|
|
264
|
+
// Later: stop();
|
|
220
265
|
```
|
|
221
266
|
|
|
222
|
-
|
|
267
|
+
See [API — createChangeListener](docs/API.md) and [API — setChangeBroadcaster](docs/API.md) for details.
|
|
223
268
|
|
|
224
|
-
|
|
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. |
|
|
245
|
-
|
|
246
|
-
Full API: [docs/API.md](docs/API.md).
|
|
269
|
+
---
|
|
247
270
|
|
|
248
271
|
## Storage backends
|
|
249
272
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
273
|
+
| Backend | Description |
|
|
274
|
+
|---------|-------------|
|
|
275
|
+
| **localStorage** | Persists across sessions; same origin; ~5MB typical. |
|
|
276
|
+
| **sessionStorage** | Cleared when the tab/window closes; same origin. |
|
|
277
|
+
| **indexedDB** | Async; larger quota; good for bigger datasets. |
|
|
253
278
|
|
|
254
279
|
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
280
|
|
|
281
|
+
---
|
|
282
|
+
|
|
256
283
|
## Usage with React / Vue / Angular
|
|
257
284
|
|
|
258
|
-
Use the same API in any framework. Share one `Database` instance (e.g. via context, service, or singleton) so
|
|
285
|
+
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.
|
|
286
|
+
|
|
287
|
+
**Example with React:**
|
|
259
288
|
|
|
260
289
|
```js
|
|
261
290
|
import { createDatabase } from '@storion/storion';
|
|
@@ -290,8 +319,41 @@ function UserList() {
|
|
|
290
319
|
}
|
|
291
320
|
```
|
|
292
321
|
|
|
293
|
-
No framework-specific bindings—
|
|
322
|
+
No framework-specific bindings—call the async API and set state as needed.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## API reference
|
|
327
|
+
|
|
328
|
+
| Method / API | Description |
|
|
329
|
+
|--------------|-------------|
|
|
330
|
+
| `createDatabase(options)` | Create or connect to a DB (name, storage, optional config). |
|
|
331
|
+
| `loadConfigFromUrl(url)` | Fetch config JSON from a URL. |
|
|
332
|
+
| `loadConfigFromFile(file)` | Read config from a `File` (e.g. file input). |
|
|
333
|
+
| `db.createTable(name, columns)` | Create a table. |
|
|
334
|
+
| `db.listTables()` | List table names. |
|
|
335
|
+
| `db.getTable(name)` | Get table structure and rows. |
|
|
336
|
+
| `db.insert(table, row)` | Insert a row (id auto if omitted). |
|
|
337
|
+
| `db.fetch(table, options?)` | Fetch rows (optional filter, sort, limit). |
|
|
338
|
+
| `db.query(table, query)` | Run JSON query; returns `{ rows, totalCount }`. |
|
|
339
|
+
| `db.update(table, id, data)` | Update a row by id. |
|
|
340
|
+
| `db.delete(table, id)` | Delete a row by id. |
|
|
341
|
+
| `db.deleteTable(name)` | Delete a table. |
|
|
342
|
+
| `db.exportConfig()` | Export DB as config-like object. |
|
|
343
|
+
| `db.subscribe(callback)` / `db.subscribe(table, callback)` / `db.subscribe(table, rowId, callback)` | Subscribe to change events; returns `unsubscribe()`. |
|
|
344
|
+
| `db.unsubscribe(id)` | Remove a subscription by id. |
|
|
345
|
+
| `db.setChangeBroadcaster(broadcaster)` | Optional: broadcast changes to another context. |
|
|
346
|
+
| `createChangeListener(transport, onChange)` | Listen for change events from another context via a custom transport. |
|
|
347
|
+
|
|
348
|
+
Full details: [API reference](docs/API.md).
|
|
349
|
+
|
|
350
|
+
---
|
|
294
351
|
|
|
295
|
-
##
|
|
352
|
+
## Links
|
|
296
353
|
|
|
297
|
-
|
|
354
|
+
| Resource | URL |
|
|
355
|
+
|----------|-----|
|
|
356
|
+
| **GitHub** | [https://github.com/storionjs/storion](https://github.com/storionjs/storion) |
|
|
357
|
+
| **npm** | [https://www.npmjs.com/package/@storion/storion](https://www.npmjs.com/package/@storion/storion) |
|
|
358
|
+
| **Issues** | [https://github.com/storionjs/storion/issues](https://github.com/storionjs/storion/issues) |
|
|
359
|
+
| **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.1",
|
|
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",
|