zerodrift 1.0.1 → 1.0.3
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/NOTICE +26 -0
- package/README.md +43 -22
- package/package.json +3 -2
package/NOTICE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
zerodrift
|
|
2
|
+
Copyright (c) 2026 selasijean
|
|
3
|
+
|
|
4
|
+
This product is licensed under the MIT License. See the LICENSE file.
|
|
5
|
+
|
|
6
|
+
Inspiration and attribution
|
|
7
|
+
---------------------------
|
|
8
|
+
|
|
9
|
+
zerodrift was shaped by public writing and talks about local-first sync engine
|
|
10
|
+
design, especially:
|
|
11
|
+
|
|
12
|
+
- Wenzhao Hu, "Reverse Engineering Linear's Sync Engine: A Detailed
|
|
13
|
+
Study" (https://github.com/wzhudev/reverse-linear-sync-engine)
|
|
14
|
+
- Tuomas Artman's React Helsinki talk on Linear's realtime sync
|
|
15
|
+
(https://www.youtube.com/watch?v=WxK11RsLqp4)
|
|
16
|
+
|
|
17
|
+
Wenzhao Hu's writeup is © 2025 Wenzhao Hu and licensed under the Creative
|
|
18
|
+
Commons Attribution 4.0 International License:
|
|
19
|
+
https://creativecommons.org/licenses/by/4.0/
|
|
20
|
+
|
|
21
|
+
zerodrift is an independent TypeScript implementation. It defines its own small
|
|
22
|
+
three-endpoint sync protocol and ships its own client/server reference code. It
|
|
23
|
+
contains no Linear or other third-party source code.
|
|
24
|
+
|
|
25
|
+
Linear is a trademark of its respective owner. zerodrift is not affiliated
|
|
26
|
+
with, endorsed by, or sponsored by Linear.
|
package/README.md
CHANGED
|
@@ -2,19 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/zerodrift)
|
|
4
4
|
|
|
5
|
-
A TypeScript
|
|
5
|
+
**A TypeScript sync engine with an intuitive model API that hides the hard parts of local reads, optimistic writes, offline recovery, and realtime convergence.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
zerodrift lets you work with synced data like normal application state. Components and headless workers read records synchronously, mutate model fields directly, call `save()`, and subscribe with typed React hooks or store APIs. Under that simple surface, the engine does the synchronization work that would otherwise spread across your codebase.
|
|
8
|
+
|
|
9
|
+
The backend stays yours. Implement bootstrap, transaction, and event-stream endpoints in any stack, or start from the included Go backend and Next.js demo. In the browser, zerodrift persists models and queued writes to IndexedDB; in Node, it can run against memory or a custom storage adapter.
|
|
10
|
+
|
|
11
|
+
The result is less sync code in every feature. Define models with decorators or schema-as-data, wire the three transport functions, and build against a small, predictable API while browser tabs, clients, and Node processes converge in the background.
|
|
12
|
+
|
|
13
|
+
The design is inspired by Linear's sync engine; see [Acknowledgments](#acknowledgments) for prior art and attribution.
|
|
8
14
|
|
|
9
15
|
## What you get
|
|
10
16
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
17
|
+
- **A small API for synced data**: read records synchronously, mutate model fields directly, call `save()`, or use typed store namespaces generated from a schema.
|
|
18
|
+
- **App logic without cache choreography**: fetching, invalidation, optimistic updates, reconnects, offline replay, and conflict rebasing live in the engine instead of every screen.
|
|
19
|
+
- **Optimistic writes with real recovery**: local changes update immediately, batch into transaction POSTs, persist through reloads, and reconcile when matching server deltas arrive.
|
|
20
|
+
- **Relationships that stay live**: references, inverse collections, owned collections, and indexed lookups update as records hydrate, load lazily, or arrive over SSE.
|
|
21
|
+
- **Schema or class models**: use decorators (`@ClientModel`, `@Property`, `@Reference`) or schema-as-data (`defineSchema(...)`, `entityFromZod(...)`) without `reflect-metadata`.
|
|
22
|
+
- **Memory you can shape**: choose per-model `LoadStrategy` values for eager data, lazy tables, partial index-backed loading, local-only records, or ephemeral SSE-fed state.
|
|
23
|
+
- **Undo/redo built into the transaction layer**: track field-level changes, group atomic multi-model edits, and include custom remote actions in the same undo stack.
|
|
24
|
+
- **React, browser, or headless Node**: use `<SyncProvider>` and typed hooks in React, or run `StoreManager` directly in agents, workers, CLIs, and tests.
|
|
25
|
+
- **Your backend, your stack**: implement three HTTP endpoints in any language, with a reference Go backend and Next.js demo included.
|
|
18
26
|
|
|
19
27
|
## Install
|
|
20
28
|
|
|
@@ -33,12 +41,12 @@ Decorator path: enable `experimentalDecorators` in your `tsconfig.json` (or the
|
|
|
33
41
|
|
|
34
42
|
## Import paths
|
|
35
43
|
|
|
36
|
-
| Import
|
|
37
|
-
|
|
38
|
-
| `zerodrift`
|
|
39
|
-
| `zerodrift/schema`
|
|
40
|
-
| `zerodrift/react`
|
|
41
|
-
| `zerodrift/internal` | Engine machinery (`ObjectPool`, `TransactionQueue`, `SyncConnection`, `ModelRegistry`, …) for tooling/tests. **No stability promise** — may change between releases.
|
|
44
|
+
| Import | Use it for |
|
|
45
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
46
|
+
| `zerodrift` | `StoreManager`, `BaseModel`, decorators, `MemoryAdapter`, relation field types (`RefCollection`/`BackRef`/`OwnedRefs`), and the config / error / sync types. The curated, stable surface. |
|
|
47
|
+
| `zerodrift/schema` | `defineSchema`, `entityFromZod`, field builders, links, extensions, and typed `store.<entity>.*` APIs. |
|
|
48
|
+
| `zerodrift/react` | `<SyncProvider>` and React hooks: `useRecord`, `useRecords`, `useRecordsByIndex`, `useRelation`, `useBatch`, `useUndoRedo`, `useBootstrapStatus`. |
|
|
49
|
+
| `zerodrift/internal` | Engine machinery (`ObjectPool`, `TransactionQueue`, `SyncConnection`, `ModelRegistry`, …) for tooling/tests. **No stability promise** — may change between releases. |
|
|
42
50
|
|
|
43
51
|
## Define your models
|
|
44
52
|
|
|
@@ -250,11 +258,11 @@ See [agent-docs/09-headless-and-agents.md](agent-docs/09-headless-and-agents.md)
|
|
|
250
258
|
|
|
251
259
|
The client needs three endpoints:
|
|
252
260
|
|
|
253
|
-
| Endpoint
|
|
254
|
-
|
|
255
|
-
| `GET /api/bootstrap`
|
|
256
|
-
| `POST /api/transactions` | Accept queued client mutations.
|
|
257
|
-
| `GET /api/events`
|
|
261
|
+
| Endpoint | Purpose |
|
|
262
|
+
| ------------------------ | ------------------------------------ |
|
|
263
|
+
| `GET /api/bootstrap` | Fetch initial or partial model data. |
|
|
264
|
+
| `POST /api/transactions` | Accept queued client mutations. |
|
|
265
|
+
| `GET /api/events` | Stream delta packets over SSE. |
|
|
258
266
|
|
|
259
267
|
Bootstrap returns records grouped by model name:
|
|
260
268
|
|
|
@@ -317,7 +325,7 @@ The client reconnects with `?lastSyncId=<id>` so the server can replay missed ev
|
|
|
317
325
|
## Run the demo
|
|
318
326
|
|
|
319
327
|
A reference Go backend + Next.js app that exercises the full sync loop
|
|
320
|
-
locally live in [
|
|
328
|
+
locally live in [examples/](examples/). See [examples/README.md](examples/README.md)
|
|
321
329
|
for the one-command-each setup:
|
|
322
330
|
|
|
323
331
|
```bash
|
|
@@ -360,6 +368,19 @@ Deeper material lives in [agent-docs/](agent-docs/):
|
|
|
360
368
|
- **Reference server**: Go, Gin, Bun ORM, Postgres (LISTEN/NOTIFY), pgx
|
|
361
369
|
- **Protocol**: append-only changelog, monotonic sync id, sync group filtering
|
|
362
370
|
|
|
371
|
+
## Acknowledgments
|
|
372
|
+
|
|
373
|
+
zerodrift was informed by public writing and talks on local-first sync
|
|
374
|
+
engines. Two especially helpful references were Wenzhao Hu's "Reverse
|
|
375
|
+
Engineering Linear's Sync Engine: A Detailed Study"
|
|
376
|
+
([wzhudev/reverse-linear-sync-engine](https://github.com/wzhudev/reverse-linear-sync-engine))
|
|
377
|
+
and Tuomas Artman's React Helsinki talk on
|
|
378
|
+
[Linear's realtime sync](https://www.youtube.com/watch?v=WxK11RsLqp4).
|
|
379
|
+
|
|
380
|
+
This project is an independent TypeScript implementation and is not affiliated
|
|
381
|
+
with Linear.
|
|
382
|
+
|
|
363
383
|
## License
|
|
364
384
|
|
|
365
|
-
MIT — see [LICENSE](LICENSE).
|
|
385
|
+
MIT — see [LICENSE](LICENSE). The MIT grant covers zerodrift's own code.
|
|
386
|
+
See [NOTICE](NOTICE) for inspiration and attribution notes.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zerodrift",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A TypeScript local-first sync engine: synchronous in-memory reads, optimistic writes, realtime SSE sync, offline IndexedDB persistence. Runs in the browser and in Node.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"./package.json": "./package.json"
|
|
50
50
|
},
|
|
51
51
|
"files": [
|
|
52
|
-
"dist"
|
|
52
|
+
"dist",
|
|
53
|
+
"NOTICE"
|
|
53
54
|
],
|
|
54
55
|
"engines": {
|
|
55
56
|
"node": ">=18"
|