@g9tm/syncdata-lynx

中文文档
1.5.23发布于 2026/11/15MITTypeScriptES Module零依赖近 30 天下载 3906

Lynx support for the G9SyncData TypeScript client: a Brotli native module (Android org.brotli decoder, iOS Compression framework, Lynxtron/Node zlib) for the sync frames, and the transport over @g9tm/signalr-supernetcore-lynx.

原始使用文档
文档目录5 节
  1. Install
  2. Use
  3. Native contract
  4. Tests
  5. License

@g9tm/syncdata-lynx

Lynx support for @g9tm/syncdata, the TypeScript twin of the G9SyncData client:

  • G9SyncDataLynxModule — a native module (Lynx Autolink) that decodes the server's Brotli frames off the JS thread: Android with Google's org.brotli:dec, iOS 15+ with Apple's Compression framework, Lynxtron with node:zlib (@g9tm/syncdata-lynx/lynxtron).
  • createLynxSyncTransport() — the sync transport over the G9 native WebSocket of @g9tm/signalr-supernetcore-lynx (Lynx release builds have no WebSocket), MessagePack by default, no negotiate round trip.
  • useLynxBrotli() — makes the native decoder the default for every frame the store and the engine read.
  • lynxSnapshotFileSink(databasePath) — the device side of snapshot files (ADR-0072): a site's first download arrives as a SQLite file in 1 MiB segments, and each segment is decompressed, checked against its SHA-256 and written into the staged file by the native module. The file's bytes never come back into JavaScript; the store copies its tables in SQL (ATTACH + one INSERT … SELECT per table).

Version 1.2.2, released with @g9tm/syncdata and the .NET packages.

Install

npm install @g9tm/syncdata @g9tm/syncdata-lynx @g9tm/signalr-supernetcore-lynx @g9tm/signalr-supernetcore-client @microsoft/signalr @microsoft/signalr-protocol-msgpack @msgpack/msgpack

Autolink picks up the native modules of @g9tm/syncdata-lynx and @g9tm/signalr-supernetcore-lynx (lynx.lib.json). iOS: the pods g9tm-syncdata-lynx and g9tm-signalr-lynx (Lynx 4.0.3 registers iOS modules explicitly: [config registerModule:G9SyncDataLynxModule.class]).

Use

import { G9SyncEngine } from '@g9tm/syncdata';
import { G9SqliteSyncStore } from '@g9tm/syncdata/sqlite';
import { createLynxSyncTransport, lynxSnapshotFileSink, useLynxBrotli } from '@g9tm/syncdata-lynx';
import { createNativeSqliteDriver } from '@g9lynx/native'; // G9LynxControls

useLynxBrotli();
const store = new G9SqliteSyncStore({
  driver: createNativeSqliteDriver(),
  databasePath,
  // null on a platform that cannot take files (an older module): the device then receives rows, as before.
  snapshotFiles: await lynxSnapshotFileSink(databasePath),
});
const transport = createLynxSyncTransport({ url: 'https://sync.example.com/g9sync', accessTokenFactory: () => token });
const engine = new G9SyncEngine(store, transport, model);
await engine.initialize();

The store accepts any driver with the G9SqliteDriver shape (@g9tm/syncdata/sqlite); G9LynxControls' native driver (androidx.sqlite bundled on Android, system SQLite on iOS) is the intended one. A database written by the .NET client (MAUI) is the same file format, tables and metadata: the Lynx app opens it and continues.

Staged snapshot files go to <the app's cache directory>/g9sync-files/<database name>-<hash of its path>: one folder per database (two users' databases never sweep each other's files), app-private and outside Android Auto Backup and the iOS backup. Pass { directory } to choose another place; the store deletes each file after its tables are copied and sweeps leftovers it wrote itself at the next start - nothing else in that folder is touched.

Native contract

MethodReply ({ ok, value } / { ok: false, error: { code, message } })
capabilities(callback){ version, platform, brotli, snapshotFiles, cacheDirectory }
brotliDecompress(data: ArrayBuffer, expectedLength: number, callback)an ArrayBuffer of exactly expectedLength bytes; errors G9SYNC-BROTLI-ARG, G9SYNC-BROTLI-INVALID, G9SYNC-BROTLI-UNAVAILABLE
snapshotFileCreate(path, size, callback)null; creates the directory too, truncates an existing file
snapshotFileWriteSegment(path, offset, data: ArrayBuffer, length, sha256, sync, callback)null; decompresses, checks the length and the SHA-256, THEN writes at offset (sync: flushed to stable storage first - F_FULLFSYNC on iOS); G9SYNC-FILE-INVALID writes nothing
snapshotFileSize(path, callback)the size, or null
snapshotFileHead(path, length, callback)an ArrayBuffer of the first length bytes
snapshotFileRemove(path, callback)null; a missing file is not an error
snapshotFileList(directory, callback)the sorted full paths of the directory's files

File errors: G9SYNC-FILE-ARG, G9SYNC-FILE-INVALID, G9SYNC-FILE-IO (with the system's reason), and on the JS side G9SYNC-FILE-UNAVAILABLE for a module without the methods. Segment work runs on its own native thread (Android) or serial queue (iOS), so it never waits behind a frame decode and the writes of one file land in order.

What is proven where, and what still needs a device: Native-Validation-Pending.md.

Tests

npm test                    # the JS wrapper over fake native modules
npm run test:lynxsim        # the whole sync against the real .NET sample server, in a Lynx-shaped sandbox (needs the disposable PostgreSQL)
npm run test:android-jvm    # the Kotlin core on a JVM
npm run check:android-module # compiles the module against Lynx 4.1.0, checks the Autolink provider
npm run test:ios-core       # the iOS cores (Brotli + snapshot files): Apple clang + Compression on macOS, GNUstep + libbrotlidec on Linux/WSL

License

MIT.

版本与发布记录

@g9tm/syncdata-lynx 共发布 30 个版本,首次发布于 2026/10/06;过去 12 个月发布了 30 个版本。

版本发布日期距今
1.5.23latest2026/11/15今天
1.5.222026/11/15今天
1.5.212026/11/132 天前
1.5.202026/11/115 天前
1.5.192026/11/106 天前
1.5.182026/11/106 天前

关于 @g9tm/syncdata-lynx 的常见问题

@g9tm/syncdata-lynx 是什么?

Lynx support for the G9SyncData TypeScript client: a Brotli native module (Android org.brotli decoder, iOS Compression framework, Lynxtron/Node zlib) for the sync frames, and the transport over @g9tm/signalr-supernetcore-lynx.

如何安装 @g9tm/syncdata-lynx?

在项目目录运行 npm install @g9tm/syncdata-lynx,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@g9tm/syncdata(1.5.23)、@microsoft/signalr(^10.0.0)、@g9tm/signalr-supernetcore-lynx(^2.11.0)、@g9tm/signalr-supernetcore-client(^2.11.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@g9tm/syncdata-lynx 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@g9tm/syncdata-lynx 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@g9tm/syncdata-lynx 可以商用吗?

@g9tm/syncdata-lynx 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@g9tm/syncdata-lynx 的下载量有多少?

根据 npm 官方下载统计,@g9tm/syncdata-lynx 在 2026/10/16 – 2026/11/14 这 30 天内被下载 3,906 次,日均约 130 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@g9tm/syncdata-lynx 还在维护吗?

最新版本 1.5.23 发布于 2026/11/15(今天);至今共发布 30 个版本,其中过去 12 个月发布了 30 个;首次发布于 2026/10/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。