@markwasfy/loko 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +57 -51
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,51 +1,57 @@
1
- # loko
2
-
3
- **Add offline support to any TypeScript app in 5 minutes. Bring your own backend.**
4
-
5
- Offline storage + sync for SaaS CRUD apps. Framework agnostic. Backend agnostic. Zero dependencies.
6
-
7
- ```bash
8
- npm install loko
9
- ```
10
-
11
- ```ts
12
- import { createSync, indexedDBStorage, restAdapter } from "loko";
13
-
14
- const sync = createSync({
15
- name: "myapp",
16
- storage: indexedDBStorage(),
17
- adapter: restAdapter({ url: "/api/sync" }),
18
- });
19
-
20
- const todos = sync.collection("todos");
21
- await todos.put({ id: "1", text: "Buy milk", done: false }); // offline-first
22
- await sync.sync(); // push + pull
23
- ```
24
-
25
- ## API
26
-
27
- - `createSync(config)` → `Sync`
28
- - `config.storage` — `indexedDBStorage()` (default browser) or `memoryStorage()`
29
- - `config.adapter` `restAdapter({ url })` or your own `SyncAdapter` (omit for local-only)
30
- - `config.conflict` — a `ConflictResolver` (defaults to `lastWriteWins()`)
31
- - `config.autoSync` — `true` (default) | `false` | interval ms
32
- - `sync.defineCollection(name, { primaryKey, indexes })` — declare a collection
33
- - `sync.collection<T>(name)` `get` · `all` · `put` · `bulkPut` · `delete` · `subscribe` · `subscribeOne`
34
- - `sync.store(key, value)` / `sync.get(key)` key→value sugar over the reserved `_kv` collection
35
- - `sync.sync()` push local changes, then pull remote changes
36
- - `sync.status` and `sync.on("change" | "sync" | "status" | "error", cb)`
37
- - `sync.registerBackgroundSync()` — opt into Service Worker Background Sync
38
-
39
- ## Extension points
40
-
41
- - **`StorageAdapter`** — `indexedDBStorage()`, `memoryStorage()`, or your own
42
- - **`SyncAdapter`** `restAdapter()`, `memoryAdapter()` (in-memory server for tests), or your own
43
- - **`ConflictResolver`** — `lastWriteWins()` or a custom `(local, remote) => StoredDoc`
44
-
45
- Conflict **detection** is version-based (server-assigned), never clock-based. Resolution is **per record, not per field**.
46
-
47
- See the [monorepo README](../../README.md) for the full guide, comparison table, and roadmap.
48
-
49
- ## License
50
-
51
- MIT
1
+ # loko
2
+
3
+ **Add offline support to any TypeScript app in 5 minutes. Bring your own backend.**
4
+
5
+ Offline storage + sync for SaaS CRUD apps. Framework agnostic. Backend agnostic. Zero dependencies.
6
+
7
+ ```bash
8
+ npm install @markwasfy/loko
9
+ ```
10
+
11
+ ```ts
12
+ import { createSync, indexedDBStorage, restAdapter } from "@markwasfy/loko";
13
+
14
+ const sync = createSync({
15
+ name: "myapp",
16
+ storage: indexedDBStorage(),
17
+ adapter: restAdapter({ url: "/api/sync" }),
18
+ });
19
+
20
+ const todos = sync.collection("todos");
21
+ await todos.put({ id: "1", text: "Buy milk", done: false }); // offline-first
22
+ await sync.sync(); // push + pull
23
+ ```
24
+
25
+ ## How it works
26
+
27
+ ![How loko works: local-first writes to IndexedDB, reactive subscriptions, push/pull sync to your backend with version-based conflict resolution, and multi-tab coordination](https://raw.githubusercontent.com/MarkWasfy00/loko/main/public/diagram.png)
28
+
29
+ Writes go to local storage first and notify subscribers immediately. `sync()` then pushes dirty records and pulls remote changes from your backend, using server-assigned versions to detect conflicts — all coordinated across tabs.
30
+
31
+ ## API
32
+
33
+ - `createSync(config)` `Sync`
34
+ - `config.storage` `indexedDBStorage()` (default browser) or `memoryStorage()`
35
+ - `config.adapter` — `restAdapter({ url })` or your own `SyncAdapter` (omit for local-only)
36
+ - `config.conflict` a `ConflictResolver` (defaults to `lastWriteWins()`)
37
+ - `config.autoSync` — `true` (default) | `false` | interval ms
38
+ - `sync.defineCollection(name, { primaryKey, indexes })` — declare a collection
39
+ - `sync.collection<T>(name)` — `get` · `all` · `put` · `bulkPut` · `delete` · `subscribe` · `subscribeOne`
40
+ - `sync.store(key, value)` / `sync.get(key)` — key→value sugar over the reserved `_kv` collection
41
+ - `sync.sync()` push local changes, then pull remote changes
42
+ - `sync.status` and `sync.on("change" | "sync" | "status" | "error", cb)`
43
+ - `sync.registerBackgroundSync()` opt into Service Worker Background Sync
44
+
45
+ ## Extension points
46
+
47
+ - **`StorageAdapter`** `indexedDBStorage()`, `memoryStorage()`, or your own
48
+ - **`SyncAdapter`** — `restAdapter()`, `memoryAdapter()` (in-memory server for tests), or your own
49
+ - **`ConflictResolver`** — `lastWriteWins()` or a custom `(local, remote) => StoredDoc`
50
+
51
+ Conflict **detection** is version-based (server-assigned), never clock-based. Resolution is **per record, not per field**.
52
+
53
+ See the [monorepo README](../../README.md) for the full guide, comparison table, and roadmap.
54
+
55
+ ## License
56
+
57
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markwasfy/loko",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Add offline support to any TypeScript app in 5 minutes. Bring your own backend. Offline storage + sync for SaaS CRUD apps. Framework agnostic. Backend agnostic. Zero dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",