@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.
Files changed (2) hide show
  1. package/README.md +139 -75
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,17 +1,43 @@
1
- # storion
1
+ # Storion
2
2
 
3
- Framework-agnostic client-side database for the browser. Use it with **React**, **Vue**, **Angular**, or vanilla JS. No framework-specific code—just create databases, tables, save/fetch records, and run JSON queries on **localStorage**, **sessionStorage**, or **IndexedDB**.
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
+ [![npm](https://img.shields.io/npm/v/@storion/storion.svg)](https://www.npmjs.com/package/@storion/storion)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-storionjs%2Fstorion-blue?logo=github)](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
- - **Framework-agnostic** Works with any frontend (React, Vue, Angular, Svelte, etc.)
8
- - **Multiple stores** – Create databases in `localStorage`, `sessionStorage`, or `indexedDB`
9
- - **Tables** Define tables with columns (int, float, boolean, string) and optional foreign keys
10
- - **CRUD** Insert, fetch, update, and delete records
11
- - **Query engine** Run JSON queries (where, orderBy, limit, offset) directly on tables
12
- - **Config from file** Create a database from a config object or load config from a URL/file
13
- - **Change subscription** Subscribe to table or row changes so multiple components stay in sync when data is updated (no polling)
14
- - **Cross-context ready** Optional broadcaster + listener helpers so an extension, background script, or another tab can stream change events to your UI
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 in localStorage (or sessionStorage / indexedDB)
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
- ## Create database from config
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 and options are described in [docs/CONFIG_FORMAT.md](docs/CONFIG_FORMAT.md).
170
+ See [Config format](docs/CONFIG_FORMAT.md) for the full schema and options.
124
171
 
125
- ## Query language
172
+ ---
126
173
 
127
- Use `db.query(tableName, query)` with a JSON query:
174
+ ## Query language
128
175
 
129
- - **where** – Filter: `{ field, op, value }` or `{ and: [...] }` / `{ or: [...] }`
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
- Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `contains`, `startsWith`, `endsWith`, `in`, `notIn`, `isNull`, `isNotNull`.
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
- Example:
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: [docs/QUERY_LANGUAGE.md](docs/QUERY_LANGUAGE.md).
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 or react—without polling.
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
- // Or subscribe to all tables: db.subscribe((event) => { ... })
167
- // Or subscribe to one row: db.subscribe('todos', 1, (event) => { ... })
217
+ // Subscribe to all tables: db.subscribe((event) => { ... })
218
+ // Subscribe to one row: db.subscribe('todos', 1, (event) => { ... })
168
219
 
169
- // When done: unsubscribe();
220
+ // When done:
221
+ unsubscribe();
170
222
  ```
171
223
 
172
- Every matching subscriber receives the event (multiple components can subscribe to the same table or row). If no one subscribes, the database behaves as before. Full details: [docs/API.md#dbsubscribe](docs/API.md).
224
+ See [API db.subscribe](docs/API.md) for details.
173
225
 
174
- ## Cross-context sync (extension ↔ webapp)
226
+ ---
175
227
 
176
- Storion can also be used as the **source of truth in one context** (e.g. a Chrome extension or background script) and stream change events to another context (e.g. a webapp UI) using a broadcaster + listener pattern.
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 side (e.g. extension popup/background)
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 && chrome.tabs.query) {
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 && tabs[0];
191
- if (!tab || !tab.id) return;
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 side (e.g. webapp page or another tab)
251
+ // 2) Consumer (e.g. web app or another tab)
202
252
  const transport = {
203
253
  onMessage(handler) {
204
- function listener(ev) {
205
- if (!ev.data || ev.data.source !== 'storion-change') return;
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
- The same `StorionChangeEvent` payload is delivered to **local subscribers** and to the **broadcaster**, and `createChangeListener` normalizes incoming messages on the receiving side. See [docs/API.md#createChangeListenertransport-onchange](docs/API.md) for details and Chrome-extension-specific wiring in the Storion Studio README.
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
- Full API: [docs/API.md](docs/API.md).
271
+ ---
247
272
 
248
273
  ## Storage backends
249
274
 
250
- - **localStorage** Persists across sessions; same origin; ~5MB typical.
251
- - **sessionStorage** – Cleared when the tab/window closes; same origin.
252
- - **indexedDB** Async; larger quota; good for bigger datasets.
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 that `db.subscribe()` keeps all components in sync when data changes. Example with React:
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—just call the async API and set state as needed.
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
- ## License
354
+ ## Links
296
355
 
297
- MIT
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.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",