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.
Files changed (3) hide show
  1. package/NOTICE +26 -0
  2. package/README.md +43 -22
  3. 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
  [![npm](https://img.shields.io/npm/v/zerodrift.svg)](https://www.npmjs.com/package/zerodrift)
4
4
 
5
- A TypeScript local-first sync engine. Reads are synchronous from an in-memory pool, writes are optimistic, state stays current across tabs and clients via SSE, and everything persists locally so the app survives reloads and works offline. The same engine runs in Node so agents and background workers can hold a live model just like a browser tab.
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
- You bring the backend. The client speaks a small three-endpoint protocol that can be implemented in any language. A reference Go backend and Next.js demo live in this repo so you can run the whole loop locally.
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
- - **Local-first reads**: every read hits an in-memory `ObjectPool` first.
12
- - **Optimistic writes**: model changes update the UI immediately, then reconcile with server deltas.
13
- - **Realtime sync**: tabs and clients stay current over SSE, without polling.
14
- - **Offline persistence**: IndexedDB stores models and queued transactions in the browser.
15
- - **Two authoring paths**: decorator classes or schema-as-data via `defineSchema(...)`.
16
- - **React and headless runtimes**: use hooks in React, or run `StoreManager` directly in Node, CLIs, and agents.
17
- - **Bring your own backend**: implement bootstrap, transaction, and SSE endpoints in the stack you already use.
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 | Use it for |
37
- |---|---|
38
- | `zerodrift` | `StoreManager`, `BaseModel`, decorators, `MemoryAdapter`, relation field types (`RefCollection`/`BackRef`/`OwnedRefs`), and the config / error / sync types. The curated, stable surface. |
39
- | `zerodrift/schema` | `defineSchema`, `entityFromZod`, field builders, links, extensions, and typed `store.<entity>.*` APIs. |
40
- | `zerodrift/react` | `<SyncProvider>` and React hooks: `useRecord`, `useRecords`, `useRecordsByIndex`, `useRelation`, `useBatch`, `useUndoRedo`, `useBootstrapStatus`. |
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 | Purpose |
254
- |---|---|
255
- | `GET /api/bootstrap` | Fetch initial or partial model data. |
256
- | `POST /api/transactions` | Accept queued client mutations. |
257
- | `GET /api/events` | Stream delta packets over SSE. |
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 [`examples/`](examples/). See [examples/README.md](examples/README.md)
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.1",
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"