anchordb 0.2.0
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/CHANGELOG.md +61 -0
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/cjs/conflict/strategies.d.ts +110 -0
- package/dist/cjs/conflict/strategies.d.ts.map +1 -0
- package/dist/cjs/conflict/strategies.js +298 -0
- package/dist/cjs/conflict/strategies.js.map +1 -0
- package/dist/cjs/conflict/types.d.ts +38 -0
- package/dist/cjs/conflict/types.d.ts.map +1 -0
- package/dist/cjs/conflict/types.js +3 -0
- package/dist/cjs/conflict/types.js.map +1 -0
- package/dist/cjs/core/anchor-db.d.ts +154 -0
- package/dist/cjs/core/anchor-db.d.ts.map +1 -0
- package/dist/cjs/core/anchor-db.js +273 -0
- package/dist/cjs/core/anchor-db.js.map +1 -0
- package/dist/cjs/core/errors.d.ts +125 -0
- package/dist/cjs/core/errors.d.ts.map +1 -0
- package/dist/cjs/core/errors.js +174 -0
- package/dist/cjs/core/errors.js.map +1 -0
- package/dist/cjs/core/hex.d.ts +4 -0
- package/dist/cjs/core/hex.d.ts.map +1 -0
- package/dist/cjs/core/hex.js +41 -0
- package/dist/cjs/core/hex.js.map +1 -0
- package/dist/cjs/core/hlc.d.ts +96 -0
- package/dist/cjs/core/hlc.d.ts.map +1 -0
- package/dist/cjs/core/hlc.js +161 -0
- package/dist/cjs/core/hlc.js.map +1 -0
- package/dist/cjs/core/object-id.d.ts +38 -0
- package/dist/cjs/core/object-id.d.ts.map +1 -0
- package/dist/cjs/core/object-id.js +167 -0
- package/dist/cjs/core/object-id.js.map +1 -0
- package/dist/cjs/core/random.d.ts +6 -0
- package/dist/cjs/core/random.d.ts.map +1 -0
- package/dist/cjs/core/random.js +39 -0
- package/dist/cjs/core/random.js.map +1 -0
- package/dist/cjs/core/runtime.d.ts +96 -0
- package/dist/cjs/core/runtime.d.ts.map +1 -0
- package/dist/cjs/core/runtime.js +3 -0
- package/dist/cjs/core/runtime.js.map +1 -0
- package/dist/cjs/core/uuid.d.ts +16 -0
- package/dist/cjs/core/uuid.d.ts.map +1 -0
- package/dist/cjs/core/uuid.js +37 -0
- package/dist/cjs/core/uuid.js.map +1 -0
- package/dist/cjs/decorators/index.d.ts +48 -0
- package/dist/cjs/decorators/index.d.ts.map +1 -0
- package/dist/cjs/decorators/index.js +295 -0
- package/dist/cjs/decorators/index.js.map +1 -0
- package/dist/cjs/events/emitter.d.ts +16 -0
- package/dist/cjs/events/emitter.d.ts.map +1 -0
- package/dist/cjs/events/emitter.js +56 -0
- package/dist/cjs/events/emitter.js.map +1 -0
- package/dist/cjs/index/keys.d.ts +79 -0
- package/dist/cjs/index/keys.d.ts.map +1 -0
- package/dist/cjs/index/keys.js +208 -0
- package/dist/cjs/index/keys.js.map +1 -0
- package/dist/cjs/index.d.ts +81 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +193 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/inspector/agent.d.ts +75 -0
- package/dist/cjs/inspector/agent.d.ts.map +1 -0
- package/dist/cjs/inspector/agent.js +520 -0
- package/dist/cjs/inspector/agent.js.map +1 -0
- package/dist/cjs/inspector/auth.d.ts +49 -0
- package/dist/cjs/inspector/auth.d.ts.map +1 -0
- package/dist/cjs/inspector/auth.js +234 -0
- package/dist/cjs/inspector/auth.js.map +1 -0
- package/dist/cjs/inspector/bridge.d.ts +141 -0
- package/dist/cjs/inspector/bridge.d.ts.map +1 -0
- package/dist/cjs/inspector/bridge.js +190 -0
- package/dist/cjs/inspector/bridge.js.map +1 -0
- package/dist/cjs/inspector/client.d.ts +111 -0
- package/dist/cjs/inspector/client.d.ts.map +1 -0
- package/dist/cjs/inspector/client.js +218 -0
- package/dist/cjs/inspector/client.js.map +1 -0
- package/dist/cjs/inspector/protocol.d.ts +160 -0
- package/dist/cjs/inspector/protocol.d.ts.map +1 -0
- package/dist/cjs/inspector/protocol.js +53 -0
- package/dist/cjs/inspector/protocol.js.map +1 -0
- package/dist/cjs/inspector/transports/in-process.d.ts +7 -0
- package/dist/cjs/inspector/transports/in-process.d.ts.map +1 -0
- package/dist/cjs/inspector/transports/in-process.js +58 -0
- package/dist/cjs/inspector/transports/in-process.js.map +1 -0
- package/dist/cjs/inspector/transports/websocket.d.ts +39 -0
- package/dist/cjs/inspector/transports/websocket.d.ts.map +1 -0
- package/dist/cjs/inspector/transports/websocket.js +60 -0
- package/dist/cjs/inspector/transports/websocket.js.map +1 -0
- package/dist/cjs/interop/csv.d.ts +53 -0
- package/dist/cjs/interop/csv.d.ts.map +1 -0
- package/dist/cjs/interop/csv.js +230 -0
- package/dist/cjs/interop/csv.js.map +1 -0
- package/dist/cjs/interop/ejson.d.ts +41 -0
- package/dist/cjs/interop/ejson.d.ts.map +1 -0
- package/dist/cjs/interop/ejson.js +182 -0
- package/dist/cjs/interop/ejson.js.map +1 -0
- package/dist/cjs/interop/export-import.d.ts +98 -0
- package/dist/cjs/interop/export-import.d.ts.map +1 -0
- package/dist/cjs/interop/export-import.js +222 -0
- package/dist/cjs/interop/export-import.js.map +1 -0
- package/dist/cjs/model/document.d.ts +66 -0
- package/dist/cjs/model/document.d.ts.map +1 -0
- package/dist/cjs/model/document.js +302 -0
- package/dist/cjs/model/document.js.map +1 -0
- package/dist/cjs/model/model.d.ts +178 -0
- package/dist/cjs/model/model.d.ts.map +1 -0
- package/dist/cjs/model/model.js +823 -0
- package/dist/cjs/model/model.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/query/aggregation/expressions.d.ts +34 -0
- package/dist/cjs/query/aggregation/expressions.d.ts.map +1 -0
- package/dist/cjs/query/aggregation/expressions.js +552 -0
- package/dist/cjs/query/aggregation/expressions.js.map +1 -0
- package/dist/cjs/query/aggregation/pipeline.d.ts +79 -0
- package/dist/cjs/query/aggregation/pipeline.d.ts.map +1 -0
- package/dist/cjs/query/aggregation/pipeline.js +597 -0
- package/dist/cjs/query/aggregation/pipeline.js.map +1 -0
- package/dist/cjs/query/aggregation/source.d.ts +35 -0
- package/dist/cjs/query/aggregation/source.d.ts.map +1 -0
- package/dist/cjs/query/aggregation/source.js +81 -0
- package/dist/cjs/query/aggregation/source.js.map +1 -0
- package/dist/cjs/query/builder/query.d.ts +113 -0
- package/dist/cjs/query/builder/query.d.ts.map +1 -0
- package/dist/cjs/query/builder/query.js +215 -0
- package/dist/cjs/query/builder/query.js.map +1 -0
- package/dist/cjs/query/filter.d.ts +50 -0
- package/dist/cjs/query/filter.d.ts.map +1 -0
- package/dist/cjs/query/filter.js +275 -0
- package/dist/cjs/query/filter.js.map +1 -0
- package/dist/cjs/query/path.d.ts +41 -0
- package/dist/cjs/query/path.d.ts.map +1 -0
- package/dist/cjs/query/path.js +294 -0
- package/dist/cjs/query/path.js.map +1 -0
- package/dist/cjs/query/update.d.ts +30 -0
- package/dist/cjs/query/update.d.ts.map +1 -0
- package/dist/cjs/query/update.js +205 -0
- package/dist/cjs/query/update.js.map +1 -0
- package/dist/cjs/reactive/live-query.d.ts +41 -0
- package/dist/cjs/reactive/live-query.d.ts.map +1 -0
- package/dist/cjs/reactive/live-query.js +88 -0
- package/dist/cjs/reactive/live-query.js.map +1 -0
- package/dist/cjs/schema/cast.d.ts +38 -0
- package/dist/cjs/schema/cast.d.ts.map +1 -0
- package/dist/cjs/schema/cast.js +280 -0
- package/dist/cjs/schema/cast.js.map +1 -0
- package/dist/cjs/schema/index.d.ts +5 -0
- package/dist/cjs/schema/index.d.ts.map +1 -0
- package/dist/cjs/schema/index.js +27 -0
- package/dist/cjs/schema/index.js.map +1 -0
- package/dist/cjs/schema/schema.d.ts +58 -0
- package/dist/cjs/schema/schema.d.ts.map +1 -0
- package/dist/cjs/schema/schema.js +363 -0
- package/dist/cjs/schema/schema.js.map +1 -0
- package/dist/cjs/schema/types.d.ts +144 -0
- package/dist/cjs/schema/types.d.ts.map +1 -0
- package/dist/cjs/schema/types.js +20 -0
- package/dist/cjs/schema/types.js.map +1 -0
- package/dist/cjs/schema/validate.d.ts +15 -0
- package/dist/cjs/schema/validate.d.ts.map +1 -0
- package/dist/cjs/schema/validate.js +101 -0
- package/dist/cjs/schema/validate.js.map +1 -0
- package/dist/cjs/storage/adapters/capacitor-sqlite.d.ts +67 -0
- package/dist/cjs/storage/adapters/capacitor-sqlite.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/capacitor-sqlite.js +69 -0
- package/dist/cjs/storage/adapters/capacitor-sqlite.js.map +1 -0
- package/dist/cjs/storage/adapters/expo-sqlite.d.ts +55 -0
- package/dist/cjs/storage/adapters/expo-sqlite.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/expo-sqlite.js +53 -0
- package/dist/cjs/storage/adapters/expo-sqlite.js.map +1 -0
- package/dist/cjs/storage/adapters/indexeddb.d.ts +55 -0
- package/dist/cjs/storage/adapters/indexeddb.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/indexeddb.js +393 -0
- package/dist/cjs/storage/adapters/indexeddb.js.map +1 -0
- package/dist/cjs/storage/adapters/memory.d.ts +44 -0
- package/dist/cjs/storage/adapters/memory.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/memory.js +286 -0
- package/dist/cjs/storage/adapters/memory.js.map +1 -0
- package/dist/cjs/storage/adapters/node-sqlite.d.ts +59 -0
- package/dist/cjs/storage/adapters/node-sqlite.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/node-sqlite.js +457 -0
- package/dist/cjs/storage/adapters/node-sqlite.js.map +1 -0
- package/dist/cjs/storage/adapters/sql-base.d.ts +84 -0
- package/dist/cjs/storage/adapters/sql-base.d.ts.map +1 -0
- package/dist/cjs/storage/adapters/sql-base.js +393 -0
- package/dist/cjs/storage/adapters/sql-base.js.map +1 -0
- package/dist/cjs/storage/types.d.ts +131 -0
- package/dist/cjs/storage/types.d.ts.map +1 -0
- package/dist/cjs/storage/types.js +3 -0
- package/dist/cjs/storage/types.js.map +1 -0
- package/dist/cjs/sync/adapters/rest.d.ts +31 -0
- package/dist/cjs/sync/adapters/rest.d.ts.map +1 -0
- package/dist/cjs/sync/adapters/rest.js +75 -0
- package/dist/cjs/sync/adapters/rest.js.map +1 -0
- package/dist/cjs/sync/attach.d.ts +30 -0
- package/dist/cjs/sync/attach.d.ts.map +1 -0
- package/dist/cjs/sync/attach.js +104 -0
- package/dist/cjs/sync/attach.js.map +1 -0
- package/dist/cjs/sync/engine.d.ts +96 -0
- package/dist/cjs/sync/engine.d.ts.map +1 -0
- package/dist/cjs/sync/engine.js +491 -0
- package/dist/cjs/sync/engine.js.map +1 -0
- package/dist/cjs/sync/protocol.d.ts +128 -0
- package/dist/cjs/sync/protocol.d.ts.map +1 -0
- package/dist/cjs/sync/protocol.js +38 -0
- package/dist/cjs/sync/protocol.js.map +1 -0
- package/dist/cjs/sync/queue.d.ts +77 -0
- package/dist/cjs/sync/queue.d.ts.map +1 -0
- package/dist/cjs/sync/queue.js +245 -0
- package/dist/cjs/sync/queue.js.map +1 -0
- package/dist/cjs/sync/server/memory-server.d.ts +65 -0
- package/dist/cjs/sync/server/memory-server.d.ts.map +1 -0
- package/dist/cjs/sync/server/memory-server.js +193 -0
- package/dist/cjs/sync/server/memory-server.js.map +1 -0
- package/dist/cjs/timestamps/index.d.ts +47 -0
- package/dist/cjs/timestamps/index.d.ts.map +1 -0
- package/dist/cjs/timestamps/index.js +88 -0
- package/dist/cjs/timestamps/index.js.map +1 -0
- package/dist/cjs/timestamps/timezone.d.ts +65 -0
- package/dist/cjs/timestamps/timezone.d.ts.map +1 -0
- package/dist/cjs/timestamps/timezone.js +208 -0
- package/dist/cjs/timestamps/timezone.js.map +1 -0
- package/dist/esm/conflict/strategies.d.ts +110 -0
- package/dist/esm/conflict/strategies.d.ts.map +1 -0
- package/dist/esm/conflict/strategies.js +289 -0
- package/dist/esm/conflict/strategies.js.map +1 -0
- package/dist/esm/conflict/types.d.ts +38 -0
- package/dist/esm/conflict/types.d.ts.map +1 -0
- package/dist/esm/conflict/types.js +2 -0
- package/dist/esm/conflict/types.js.map +1 -0
- package/dist/esm/core/anchor-db.d.ts +154 -0
- package/dist/esm/core/anchor-db.d.ts.map +1 -0
- package/dist/esm/core/anchor-db.js +269 -0
- package/dist/esm/core/anchor-db.js.map +1 -0
- package/dist/esm/core/errors.d.ts +125 -0
- package/dist/esm/core/errors.d.ts.map +1 -0
- package/dist/esm/core/errors.js +161 -0
- package/dist/esm/core/errors.js.map +1 -0
- package/dist/esm/core/hex.d.ts +4 -0
- package/dist/esm/core/hex.d.ts.map +1 -0
- package/dist/esm/core/hex.js +37 -0
- package/dist/esm/core/hex.js.map +1 -0
- package/dist/esm/core/hlc.d.ts +96 -0
- package/dist/esm/core/hlc.d.ts.map +1 -0
- package/dist/esm/core/hlc.js +153 -0
- package/dist/esm/core/hlc.js.map +1 -0
- package/dist/esm/core/object-id.d.ts +38 -0
- package/dist/esm/core/object-id.d.ts.map +1 -0
- package/dist/esm/core/object-id.js +163 -0
- package/dist/esm/core/object-id.js.map +1 -0
- package/dist/esm/core/random.d.ts +6 -0
- package/dist/esm/core/random.d.ts.map +1 -0
- package/dist/esm/core/random.js +34 -0
- package/dist/esm/core/random.js.map +1 -0
- package/dist/esm/core/runtime.d.ts +96 -0
- package/dist/esm/core/runtime.d.ts.map +1 -0
- package/dist/esm/core/runtime.js +2 -0
- package/dist/esm/core/runtime.js.map +1 -0
- package/dist/esm/core/uuid.d.ts +16 -0
- package/dist/esm/core/uuid.d.ts.map +1 -0
- package/dist/esm/core/uuid.js +33 -0
- package/dist/esm/core/uuid.js.map +1 -0
- package/dist/esm/decorators/index.d.ts +48 -0
- package/dist/esm/decorators/index.d.ts.map +1 -0
- package/dist/esm/decorators/index.js +286 -0
- package/dist/esm/decorators/index.js.map +1 -0
- package/dist/esm/events/emitter.d.ts +16 -0
- package/dist/esm/events/emitter.d.ts.map +1 -0
- package/dist/esm/events/emitter.js +52 -0
- package/dist/esm/events/emitter.js.map +1 -0
- package/dist/esm/index/keys.d.ts +79 -0
- package/dist/esm/index/keys.d.ts.map +1 -0
- package/dist/esm/index/keys.js +198 -0
- package/dist/esm/index/keys.js.map +1 -0
- package/dist/esm/index.d.ts +81 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +59 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/inspector/agent.d.ts +75 -0
- package/dist/esm/inspector/agent.d.ts.map +1 -0
- package/dist/esm/inspector/agent.js +482 -0
- package/dist/esm/inspector/agent.js.map +1 -0
- package/dist/esm/inspector/auth.d.ts +49 -0
- package/dist/esm/inspector/auth.d.ts.map +1 -0
- package/dist/esm/inspector/auth.js +228 -0
- package/dist/esm/inspector/auth.js.map +1 -0
- package/dist/esm/inspector/bridge.d.ts +141 -0
- package/dist/esm/inspector/bridge.d.ts.map +1 -0
- package/dist/esm/inspector/bridge.js +182 -0
- package/dist/esm/inspector/bridge.js.map +1 -0
- package/dist/esm/inspector/client.d.ts +111 -0
- package/dist/esm/inspector/client.d.ts.map +1 -0
- package/dist/esm/inspector/client.js +213 -0
- package/dist/esm/inspector/client.js.map +1 -0
- package/dist/esm/inspector/protocol.d.ts +160 -0
- package/dist/esm/inspector/protocol.d.ts.map +1 -0
- package/dist/esm/inspector/protocol.js +43 -0
- package/dist/esm/inspector/protocol.js.map +1 -0
- package/dist/esm/inspector/transports/in-process.d.ts +7 -0
- package/dist/esm/inspector/transports/in-process.d.ts.map +1 -0
- package/dist/esm/inspector/transports/in-process.js +55 -0
- package/dist/esm/inspector/transports/in-process.js.map +1 -0
- package/dist/esm/inspector/transports/websocket.d.ts +39 -0
- package/dist/esm/inspector/transports/websocket.d.ts.map +1 -0
- package/dist/esm/inspector/transports/websocket.js +56 -0
- package/dist/esm/inspector/transports/websocket.js.map +1 -0
- package/dist/esm/interop/csv.d.ts +53 -0
- package/dist/esm/interop/csv.d.ts.map +1 -0
- package/dist/esm/interop/csv.js +222 -0
- package/dist/esm/interop/csv.js.map +1 -0
- package/dist/esm/interop/ejson.d.ts +41 -0
- package/dist/esm/interop/ejson.d.ts.map +1 -0
- package/dist/esm/interop/ejson.js +176 -0
- package/dist/esm/interop/ejson.js.map +1 -0
- package/dist/esm/interop/export-import.d.ts +98 -0
- package/dist/esm/interop/export-import.d.ts.map +1 -0
- package/dist/esm/interop/export-import.js +210 -0
- package/dist/esm/interop/export-import.js.map +1 -0
- package/dist/esm/model/document.d.ts +66 -0
- package/dist/esm/model/document.d.ts.map +1 -0
- package/dist/esm/model/document.js +297 -0
- package/dist/esm/model/document.js.map +1 -0
- package/dist/esm/model/model.d.ts +178 -0
- package/dist/esm/model/model.d.ts.map +1 -0
- package/dist/esm/model/model.js +815 -0
- package/dist/esm/model/model.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/query/aggregation/expressions.d.ts +34 -0
- package/dist/esm/query/aggregation/expressions.d.ts.map +1 -0
- package/dist/esm/query/aggregation/expressions.js +545 -0
- package/dist/esm/query/aggregation/expressions.js.map +1 -0
- package/dist/esm/query/aggregation/pipeline.d.ts +79 -0
- package/dist/esm/query/aggregation/pipeline.d.ts.map +1 -0
- package/dist/esm/query/aggregation/pipeline.js +591 -0
- package/dist/esm/query/aggregation/pipeline.js.map +1 -0
- package/dist/esm/query/aggregation/source.d.ts +35 -0
- package/dist/esm/query/aggregation/source.d.ts.map +1 -0
- package/dist/esm/query/aggregation/source.js +77 -0
- package/dist/esm/query/aggregation/source.js.map +1 -0
- package/dist/esm/query/builder/query.d.ts +113 -0
- package/dist/esm/query/builder/query.d.ts.map +1 -0
- package/dist/esm/query/builder/query.js +209 -0
- package/dist/esm/query/builder/query.js.map +1 -0
- package/dist/esm/query/filter.d.ts +50 -0
- package/dist/esm/query/filter.d.ts.map +1 -0
- package/dist/esm/query/filter.js +267 -0
- package/dist/esm/query/filter.js.map +1 -0
- package/dist/esm/query/path.d.ts +41 -0
- package/dist/esm/query/path.d.ts.map +1 -0
- package/dist/esm/query/path.js +282 -0
- package/dist/esm/query/path.js.map +1 -0
- package/dist/esm/query/update.d.ts +30 -0
- package/dist/esm/query/update.d.ts.map +1 -0
- package/dist/esm/query/update.js +198 -0
- package/dist/esm/query/update.js.map +1 -0
- package/dist/esm/reactive/live-query.d.ts +41 -0
- package/dist/esm/reactive/live-query.d.ts.map +1 -0
- package/dist/esm/reactive/live-query.js +83 -0
- package/dist/esm/reactive/live-query.js.map +1 -0
- package/dist/esm/schema/cast.d.ts +38 -0
- package/dist/esm/schema/cast.d.ts.map +1 -0
- package/dist/esm/schema/cast.js +275 -0
- package/dist/esm/schema/cast.js.map +1 -0
- package/dist/esm/schema/index.d.ts +5 -0
- package/dist/esm/schema/index.d.ts.map +1 -0
- package/dist/esm/schema/index.js +5 -0
- package/dist/esm/schema/index.js.map +1 -0
- package/dist/esm/schema/schema.d.ts +58 -0
- package/dist/esm/schema/schema.d.ts.map +1 -0
- package/dist/esm/schema/schema.js +358 -0
- package/dist/esm/schema/schema.js.map +1 -0
- package/dist/esm/schema/types.d.ts +144 -0
- package/dist/esm/schema/types.d.ts.map +1 -0
- package/dist/esm/schema/types.js +17 -0
- package/dist/esm/schema/types.js.map +1 -0
- package/dist/esm/schema/validate.d.ts +15 -0
- package/dist/esm/schema/validate.d.ts.map +1 -0
- package/dist/esm/schema/validate.js +98 -0
- package/dist/esm/schema/validate.js.map +1 -0
- package/dist/esm/storage/adapters/capacitor-sqlite.d.ts +67 -0
- package/dist/esm/storage/adapters/capacitor-sqlite.d.ts.map +1 -0
- package/dist/esm/storage/adapters/capacitor-sqlite.js +65 -0
- package/dist/esm/storage/adapters/capacitor-sqlite.js.map +1 -0
- package/dist/esm/storage/adapters/expo-sqlite.d.ts +55 -0
- package/dist/esm/storage/adapters/expo-sqlite.d.ts.map +1 -0
- package/dist/esm/storage/adapters/expo-sqlite.js +49 -0
- package/dist/esm/storage/adapters/expo-sqlite.js.map +1 -0
- package/dist/esm/storage/adapters/indexeddb.d.ts +55 -0
- package/dist/esm/storage/adapters/indexeddb.d.ts.map +1 -0
- package/dist/esm/storage/adapters/indexeddb.js +389 -0
- package/dist/esm/storage/adapters/indexeddb.js.map +1 -0
- package/dist/esm/storage/adapters/memory.d.ts +44 -0
- package/dist/esm/storage/adapters/memory.d.ts.map +1 -0
- package/dist/esm/storage/adapters/memory.js +282 -0
- package/dist/esm/storage/adapters/memory.js.map +1 -0
- package/dist/esm/storage/adapters/node-sqlite.d.ts +59 -0
- package/dist/esm/storage/adapters/node-sqlite.d.ts.map +1 -0
- package/dist/esm/storage/adapters/node-sqlite.js +450 -0
- package/dist/esm/storage/adapters/node-sqlite.js.map +1 -0
- package/dist/esm/storage/adapters/sql-base.d.ts +84 -0
- package/dist/esm/storage/adapters/sql-base.d.ts.map +1 -0
- package/dist/esm/storage/adapters/sql-base.js +383 -0
- package/dist/esm/storage/adapters/sql-base.js.map +1 -0
- package/dist/esm/storage/types.d.ts +131 -0
- package/dist/esm/storage/types.d.ts.map +1 -0
- package/dist/esm/storage/types.js +2 -0
- package/dist/esm/storage/types.js.map +1 -0
- package/dist/esm/sync/adapters/rest.d.ts +31 -0
- package/dist/esm/sync/adapters/rest.d.ts.map +1 -0
- package/dist/esm/sync/adapters/rest.js +71 -0
- package/dist/esm/sync/adapters/rest.js.map +1 -0
- package/dist/esm/sync/attach.d.ts +30 -0
- package/dist/esm/sync/attach.d.ts.map +1 -0
- package/dist/esm/sync/attach.js +98 -0
- package/dist/esm/sync/attach.js.map +1 -0
- package/dist/esm/sync/engine.d.ts +96 -0
- package/dist/esm/sync/engine.d.ts.map +1 -0
- package/dist/esm/sync/engine.js +487 -0
- package/dist/esm/sync/engine.js.map +1 -0
- package/dist/esm/sync/protocol.d.ts +128 -0
- package/dist/esm/sync/protocol.d.ts.map +1 -0
- package/dist/esm/sync/protocol.js +33 -0
- package/dist/esm/sync/protocol.js.map +1 -0
- package/dist/esm/sync/queue.d.ts +77 -0
- package/dist/esm/sync/queue.d.ts.map +1 -0
- package/dist/esm/sync/queue.js +241 -0
- package/dist/esm/sync/queue.js.map +1 -0
- package/dist/esm/sync/server/memory-server.d.ts +65 -0
- package/dist/esm/sync/server/memory-server.d.ts.map +1 -0
- package/dist/esm/sync/server/memory-server.js +189 -0
- package/dist/esm/sync/server/memory-server.js.map +1 -0
- package/dist/esm/timestamps/index.d.ts +47 -0
- package/dist/esm/timestamps/index.d.ts.map +1 -0
- package/dist/esm/timestamps/index.js +70 -0
- package/dist/esm/timestamps/index.js.map +1 -0
- package/dist/esm/timestamps/timezone.d.ts +65 -0
- package/dist/esm/timestamps/timezone.d.ts.map +1 -0
- package/dist/esm/timestamps/timezone.js +196 -0
- package/dist/esm/timestamps/timezone.js.map +1 -0
- package/package.json +163 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SyncEngine = exports.SHADOW_COLLECTION = void 0;
|
|
4
|
+
const errors_ts_1 = require("../core/errors.js");
|
|
5
|
+
const path_ts_1 = require("../query/path.js");
|
|
6
|
+
const strategies_ts_1 = require("../conflict/strategies.js");
|
|
7
|
+
const protocol_ts_1 = require("./protocol.js");
|
|
8
|
+
/** Last server-confirmed document per id — the common ancestor a 3-way merge needs. */
|
|
9
|
+
exports.SHADOW_COLLECTION = "__anchor_shadow";
|
|
10
|
+
const CURSOR_KEY = "anchor:sync:cursor";
|
|
11
|
+
const OFFSET_KEY = "anchor:sync:clockOffset";
|
|
12
|
+
/**
|
|
13
|
+
* The sync engine.
|
|
14
|
+
*
|
|
15
|
+
* Responsibilities, in the order they run:
|
|
16
|
+
*
|
|
17
|
+
* recover -> push (with conflict resolution) -> pull -> apply remote -> persist cursor
|
|
18
|
+
*
|
|
19
|
+
* Deliberately serialised: a second `run()` while one is in flight returns the same promise rather
|
|
20
|
+
* than starting a concurrent pass, because two passes would both take from the queue and could push
|
|
21
|
+
* the same mutation twice.
|
|
22
|
+
*/
|
|
23
|
+
class SyncEngine {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.inFlight = null;
|
|
26
|
+
this.status = "idle";
|
|
27
|
+
this.clockOffsetMs = 0;
|
|
28
|
+
this.recovered = false;
|
|
29
|
+
this.opts = { batchSize: 50, maxConflictAttempts: 5, ...options };
|
|
30
|
+
this.strategies = new strategies_ts_1.ConflictStrategyRegistry(options.conflictResolution ?? {});
|
|
31
|
+
this.strategyName = options.conflictResolution?.strategy ?? "last-write-wins";
|
|
32
|
+
// Fail fast on a misconfigured strategy rather than at the first conflict, which could be days
|
|
33
|
+
// later and on a user's device.
|
|
34
|
+
this.strategies.get(this.strategyName);
|
|
35
|
+
}
|
|
36
|
+
getStatus() {
|
|
37
|
+
return this.status;
|
|
38
|
+
}
|
|
39
|
+
setStatus(status) {
|
|
40
|
+
this.status = status;
|
|
41
|
+
this.opts.onStatus?.(status);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @param options.immediate Bypass retry backoff. Set for user-initiated or
|
|
45
|
+
* connectivity-restored syncs, where waiting out a timer computed during the outage is pointless.
|
|
46
|
+
*/
|
|
47
|
+
async run(options = {}) {
|
|
48
|
+
if (this.inFlight)
|
|
49
|
+
return this.inFlight;
|
|
50
|
+
this.inFlight = this.runOnce(options).finally(() => {
|
|
51
|
+
this.inFlight = null;
|
|
52
|
+
});
|
|
53
|
+
return this.inFlight;
|
|
54
|
+
}
|
|
55
|
+
async runOnce(options = {}) {
|
|
56
|
+
const started = Date.now();
|
|
57
|
+
const result = { pushed: 0, pulled: 0, conflicts: 0, rejected: 0 };
|
|
58
|
+
if (!this.recovered) {
|
|
59
|
+
await this.opts.queue.recover();
|
|
60
|
+
const stored = await this.opts.adapter.getState(OFFSET_KEY);
|
|
61
|
+
if (stored)
|
|
62
|
+
this.clockOffsetMs = Number(stored);
|
|
63
|
+
this.recovered = true;
|
|
64
|
+
}
|
|
65
|
+
if (options.immediate)
|
|
66
|
+
await this.opts.queue.clearBackoff();
|
|
67
|
+
const counts = await this.opts.queue.counts();
|
|
68
|
+
this.setStatus("syncing");
|
|
69
|
+
this.opts.events.emit("sync:start", { pending: counts.pending });
|
|
70
|
+
try {
|
|
71
|
+
result.pushed = await this.pushAll(result);
|
|
72
|
+
const pulled = await this.pullAll();
|
|
73
|
+
result.pulled = pulled;
|
|
74
|
+
this.setStatus("idle");
|
|
75
|
+
this.opts.events.emit("sync:complete", {
|
|
76
|
+
pushed: result.pushed,
|
|
77
|
+
pulled: result.pulled,
|
|
78
|
+
conflicts: result.conflicts,
|
|
79
|
+
durationMs: Date.now() - started,
|
|
80
|
+
});
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (err instanceof protocol_ts_1.SyncAuthError) {
|
|
85
|
+
// Never discard queued work over an expired token — pause and let the app refresh it.
|
|
86
|
+
this.setStatus("paused");
|
|
87
|
+
this.opts.events.emit("auth:expired", { at: this.opts.time.now() });
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
this.setStatus(err instanceof protocol_ts_1.SyncTransportError ? "offline" : "error");
|
|
91
|
+
this.opts.events.emit("sync:error", {
|
|
92
|
+
error: err,
|
|
93
|
+
phase: "push",
|
|
94
|
+
});
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// ---- push ----------------------------------------------------------------
|
|
99
|
+
async pushAll(result) {
|
|
100
|
+
let pushed = 0;
|
|
101
|
+
for (;;) {
|
|
102
|
+
const batch = await this.opts.queue.take(this.opts.batchSize);
|
|
103
|
+
if (batch.length === 0)
|
|
104
|
+
break;
|
|
105
|
+
await this.opts.queue.markInflight(batch);
|
|
106
|
+
let response;
|
|
107
|
+
try {
|
|
108
|
+
response = await this.opts.transport.push({
|
|
109
|
+
protocolVersion: protocol_ts_1.PROTOCOL_VERSION,
|
|
110
|
+
clientId: this.opts.clientId,
|
|
111
|
+
sentAt: this.opts.time.now(),
|
|
112
|
+
changes: batch.map(toWireMutation),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
// Transport failure: return everything to pending with backoff. Nothing is lost.
|
|
117
|
+
for (const m of batch) {
|
|
118
|
+
await this.opts.queue.scheduleRetry(m, err.message);
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
this.absorbServerClock(response.serverTime, response.serverHlc);
|
|
123
|
+
const byId = new Map(batch.map((m) => [m.mutationId, m]));
|
|
124
|
+
for (const change of response.results) {
|
|
125
|
+
const mutation = byId.get(change.mutationId);
|
|
126
|
+
if (!mutation)
|
|
127
|
+
continue;
|
|
128
|
+
const handled = await this.applyPushResult(mutation, change, result);
|
|
129
|
+
if (handled === "accepted")
|
|
130
|
+
pushed++;
|
|
131
|
+
}
|
|
132
|
+
await this.emitQueueChanged();
|
|
133
|
+
if (batch.length < this.opts.batchSize)
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
return pushed;
|
|
137
|
+
}
|
|
138
|
+
async applyPushResult(mutation, change, result) {
|
|
139
|
+
if (change.status === "accepted") {
|
|
140
|
+
await this.markSynced(mutation, change);
|
|
141
|
+
await this.opts.queue.remove([mutation.mutationId]);
|
|
142
|
+
return "accepted";
|
|
143
|
+
}
|
|
144
|
+
if (change.status === "rejected") {
|
|
145
|
+
result.rejected++;
|
|
146
|
+
// A duplicate key cannot be fixed by retrying: two devices created a colliding document while
|
|
147
|
+
// offline and only the server can see it. Park it and surface it rather than spinning.
|
|
148
|
+
if (change.code === errors_ts_1.DUPLICATE_KEY_CODE) {
|
|
149
|
+
await this.opts.queue.markFatal(mutation, change.reason ?? "duplicate key");
|
|
150
|
+
this.opts.events.emit("duplicate-key", {
|
|
151
|
+
collection: mutation.collection,
|
|
152
|
+
documentId: mutation.documentId,
|
|
153
|
+
index: "unknown",
|
|
154
|
+
keyValue: (mutation.payload ?? {}),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
await this.opts.queue.markFatal(mutation, change.reason ?? "rejected by server");
|
|
159
|
+
this.opts.events.emit("sync:error", {
|
|
160
|
+
error: new Error(change.reason ?? "Change rejected by server"),
|
|
161
|
+
phase: "push",
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return "rejected";
|
|
165
|
+
}
|
|
166
|
+
// conflict
|
|
167
|
+
result.conflicts++;
|
|
168
|
+
await this.resolveConflict(mutation, change);
|
|
169
|
+
return "conflict";
|
|
170
|
+
}
|
|
171
|
+
async resolveConflict(mutation, change) {
|
|
172
|
+
const remote = (change.document ?? {});
|
|
173
|
+
const localRow = await this.opts.adapter.get(mutation.collection, mutation.documentId, true);
|
|
174
|
+
const local = (localRow?.doc ?? {});
|
|
175
|
+
const base = await this.readShadow(mutation.collection, mutation.documentId);
|
|
176
|
+
const ctx = {
|
|
177
|
+
local: local,
|
|
178
|
+
remote,
|
|
179
|
+
...(base ? { base } : {}),
|
|
180
|
+
collection: mutation.collection,
|
|
181
|
+
documentId: mutation.documentId,
|
|
182
|
+
localHlc: mutation.hlc,
|
|
183
|
+
remoteHlc: change.hlc ?? "",
|
|
184
|
+
localVersion: mutation.baseVersion,
|
|
185
|
+
remoteVersion: change.version ?? 0,
|
|
186
|
+
localTimestamp: Date.parse(String(local.updatedAt ?? mutation.createdAt)) || undefined,
|
|
187
|
+
remoteTimestamp: Date.parse(String(remote.updatedAt ?? "")) || undefined,
|
|
188
|
+
};
|
|
189
|
+
let resolution;
|
|
190
|
+
try {
|
|
191
|
+
resolution = await this.strategies.get(this.strategyName).resolve(ctx);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
// A throwing custom resolver must not wedge the whole queue.
|
|
195
|
+
await this.opts.queue.markFatal(mutation, `conflict resolver threw: ${err.message}`);
|
|
196
|
+
this.opts.events.emit("sync:error", { error: err, phase: "push" });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.opts.events.emit("conflict", {
|
|
200
|
+
collection: mutation.collection,
|
|
201
|
+
documentId: mutation.documentId,
|
|
202
|
+
strategy: this.strategyName,
|
|
203
|
+
winner: resolution.winner,
|
|
204
|
+
local,
|
|
205
|
+
remote,
|
|
206
|
+
...(base ? { base } : {}),
|
|
207
|
+
resolved: resolution.document,
|
|
208
|
+
});
|
|
209
|
+
const serverVersion = change.version ?? 0;
|
|
210
|
+
await this.writeResolved(mutation.collection, mutation.documentId, resolution.document, {
|
|
211
|
+
version: serverVersion,
|
|
212
|
+
dirty: resolution.pushBack,
|
|
213
|
+
});
|
|
214
|
+
if (!resolution.pushBack) {
|
|
215
|
+
await this.opts.queue.remove([mutation.mutationId]);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const attempts = mutation.conflictAttempts + 1;
|
|
219
|
+
if (attempts > this.opts.maxConflictAttempts) {
|
|
220
|
+
await this.opts.queue.markFatal(mutation, `unresolvable after ${attempts} conflict attempts`);
|
|
221
|
+
this.opts.events.emit("conflict:unresolvable", {
|
|
222
|
+
collection: mutation.collection,
|
|
223
|
+
documentId: mutation.documentId,
|
|
224
|
+
attempts,
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Re-push as a NEW mutation, not a mutated copy of the old one.
|
|
230
|
+
*
|
|
231
|
+
* Two mechanisms collide here. The server memoises verdicts by `(clientId, mutationId)` so a
|
|
232
|
+
* retry after a timeout cannot apply a write twice — correct, and required. But a
|
|
233
|
+
* conflict-resolved re-push is a *materially different change*: new payload, new baseVersion.
|
|
234
|
+
* Re-sending it under the original id makes the server replay its cached `conflict` verdict
|
|
235
|
+
* forever, and the mutation can never land no matter how many times sync runs.
|
|
236
|
+
*
|
|
237
|
+
* So the resolution gets a fresh id, with `resolvedFrom` preserving the lineage for debugging
|
|
238
|
+
* and for the Lens conflict viewer. `baseVersion` is the version we just observed, so the
|
|
239
|
+
* server's optimistic check now passes rather than conflicting again.
|
|
240
|
+
*/
|
|
241
|
+
await this.opts.queue.remove([mutation.mutationId]);
|
|
242
|
+
const [requeued] = await this.opts.queue.enqueue([
|
|
243
|
+
{
|
|
244
|
+
collection: mutation.collection,
|
|
245
|
+
documentId: mutation.documentId,
|
|
246
|
+
operation: "replace",
|
|
247
|
+
payload: resolution.document,
|
|
248
|
+
baseVersion: serverVersion,
|
|
249
|
+
hlc: this.opts.clock.tickStamp(),
|
|
250
|
+
resolvedFrom: mutation.resolvedFrom ?? mutation.mutationId,
|
|
251
|
+
},
|
|
252
|
+
]);
|
|
253
|
+
if (requeued) {
|
|
254
|
+
// Carry the attempt count across the new id, or the loop cap would reset every round.
|
|
255
|
+
requeued.conflictAttempts = attempts;
|
|
256
|
+
await this.opts.queue.update([requeued]);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// ---- pull ----------------------------------------------------------------
|
|
260
|
+
async pullAll() {
|
|
261
|
+
let pulled = 0;
|
|
262
|
+
let cursor = await this.opts.adapter.getState(CURSOR_KEY);
|
|
263
|
+
for (;;) {
|
|
264
|
+
const response = await this.opts.transport.pull({
|
|
265
|
+
protocolVersion: protocol_ts_1.PROTOCOL_VERSION,
|
|
266
|
+
clientId: this.opts.clientId,
|
|
267
|
+
cursor,
|
|
268
|
+
limit: this.opts.batchSize,
|
|
269
|
+
});
|
|
270
|
+
this.absorbServerClock(response.serverTime, response.serverHlc);
|
|
271
|
+
for (const change of response.changes) {
|
|
272
|
+
await this.applyRemoteChange(change);
|
|
273
|
+
pulled++;
|
|
274
|
+
}
|
|
275
|
+
// Persisted per page, so an interrupted pull resumes where it stopped rather than restarting.
|
|
276
|
+
cursor = response.nextCursor;
|
|
277
|
+
if (cursor !== null && cursor !== undefined)
|
|
278
|
+
await this.opts.adapter.setState(CURSOR_KEY, cursor);
|
|
279
|
+
this.opts.events.emit("sync:progress", { pushed: 0, pulled });
|
|
280
|
+
if (!response.hasMore)
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
return pulled;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Apply a server change locally.
|
|
287
|
+
*
|
|
288
|
+
* A document with unpushed local edits is left alone: overwriting it would silently discard the
|
|
289
|
+
* user's offline work. The pending mutation will conflict on its next push and go through the
|
|
290
|
+
* configured strategy, which is where that decision belongs.
|
|
291
|
+
*/
|
|
292
|
+
async applyRemoteChange(change) {
|
|
293
|
+
const existing = await this.opts.adapter.get(change.collection, change.documentId, true);
|
|
294
|
+
if (existing?.meta.dirty) {
|
|
295
|
+
await this.writeShadow(change.collection, change.documentId, change.document, change.version);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
await this.opts.adapter.ensureCollection(change.collection);
|
|
299
|
+
if (change.deleted || change.document === null) {
|
|
300
|
+
if (existing) {
|
|
301
|
+
await this.opts.adapter.write([
|
|
302
|
+
{ type: "hardDelete", collection: change.collection, _id: change.documentId },
|
|
303
|
+
]);
|
|
304
|
+
this.opts.events.emit("change", {
|
|
305
|
+
collection: change.collection,
|
|
306
|
+
modelName: change.collection,
|
|
307
|
+
operation: "delete",
|
|
308
|
+
documentId: change.documentId,
|
|
309
|
+
document: null,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
await this.clearShadow(change.collection, change.documentId);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const doc = { ...change.document, _id: change.documentId };
|
|
316
|
+
const row = {
|
|
317
|
+
doc: doc,
|
|
318
|
+
meta: {
|
|
319
|
+
version: change.version,
|
|
320
|
+
hlc: change.hlc ?? "",
|
|
321
|
+
dirty: false,
|
|
322
|
+
deleted: false,
|
|
323
|
+
createdAt: String(doc.createdAt ?? change.updatedAt),
|
|
324
|
+
updatedAt: change.updatedAt,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
await this.opts.adapter.write([
|
|
328
|
+
{ type: existing ? "update" : "insert", collection: change.collection, _id: change.documentId, row },
|
|
329
|
+
]);
|
|
330
|
+
await this.writeShadow(change.collection, change.documentId, change.document, change.version);
|
|
331
|
+
this.opts.events.emit("change", {
|
|
332
|
+
collection: change.collection,
|
|
333
|
+
modelName: change.collection,
|
|
334
|
+
operation: existing ? "update" : "insert",
|
|
335
|
+
documentId: change.documentId,
|
|
336
|
+
document: doc,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
// ---- helpers -------------------------------------------------------------
|
|
340
|
+
/**
|
|
341
|
+
* Estimate the client's clock offset from the server and feed it to the HLC.
|
|
342
|
+
*
|
|
343
|
+
* This is what stops a device with a badly wrong clock from ordering its writes incorrectly
|
|
344
|
+
* against everyone else's. The server stamp is treated as authoritative (`trusted: true`) —
|
|
345
|
+
* see the reasoning in HybridLogicalClock.update().
|
|
346
|
+
*/
|
|
347
|
+
absorbServerClock(serverTime, serverHlc) {
|
|
348
|
+
const server = Date.parse(serverTime);
|
|
349
|
+
if (!Number.isNaN(server)) {
|
|
350
|
+
const observed = server - Date.now();
|
|
351
|
+
// Exponential moving average smooths out per-request network jitter.
|
|
352
|
+
this.clockOffsetMs = this.clockOffsetMs === 0 ? observed : Math.round(this.clockOffsetMs * 0.7 + observed * 0.3);
|
|
353
|
+
void this.opts.adapter.setState(OFFSET_KEY, String(this.clockOffsetMs));
|
|
354
|
+
}
|
|
355
|
+
if (serverHlc)
|
|
356
|
+
this.opts.clock.update(serverHlc, { trusted: true });
|
|
357
|
+
}
|
|
358
|
+
async markSynced(mutation, change) {
|
|
359
|
+
const row = await this.opts.adapter.get(mutation.collection, mutation.documentId, true);
|
|
360
|
+
if (!row)
|
|
361
|
+
return;
|
|
362
|
+
if (row.meta.deleted) {
|
|
363
|
+
// The tombstone has served its purpose: the server knows about the delete.
|
|
364
|
+
await this.opts.adapter.write([
|
|
365
|
+
{ type: "hardDelete", collection: mutation.collection, _id: mutation.documentId },
|
|
366
|
+
]);
|
|
367
|
+
await this.clearShadow(mutation.collection, mutation.documentId);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const accepted = (change.document ?? row.doc);
|
|
371
|
+
await this.writeResolved(mutation.collection, mutation.documentId, accepted, {
|
|
372
|
+
version: change.version ?? row.meta.version + 1,
|
|
373
|
+
dirty: false,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
async writeResolved(collection, documentId, document, meta) {
|
|
377
|
+
const existing = await this.opts.adapter.get(collection, documentId, true);
|
|
378
|
+
const doc = { ...document, _id: documentId };
|
|
379
|
+
const row = {
|
|
380
|
+
doc,
|
|
381
|
+
meta: {
|
|
382
|
+
version: meta.version,
|
|
383
|
+
hlc: existing?.meta.hlc ?? this.opts.clock.peek().wall.toString(),
|
|
384
|
+
dirty: meta.dirty,
|
|
385
|
+
deleted: false,
|
|
386
|
+
createdAt: existing?.meta.createdAt ?? String(doc.createdAt ?? this.opts.time.now()),
|
|
387
|
+
updatedAt: String(doc.updatedAt ?? this.opts.time.now()),
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
await this.opts.adapter.write([
|
|
391
|
+
{ type: existing ? "update" : "insert", collection, _id: documentId, row },
|
|
392
|
+
]);
|
|
393
|
+
// The shadow tracks what the SERVER last confirmed, which is only this document when the
|
|
394
|
+
// resolution is not being pushed back.
|
|
395
|
+
if (!meta.dirty)
|
|
396
|
+
await this.writeShadow(collection, documentId, document, meta.version);
|
|
397
|
+
}
|
|
398
|
+
async writeShadow(collection, documentId, document, version) {
|
|
399
|
+
if (!document)
|
|
400
|
+
return;
|
|
401
|
+
await this.opts.adapter.ensureCollection(exports.SHADOW_COLLECTION);
|
|
402
|
+
const id = shadowId(collection, documentId);
|
|
403
|
+
const row = {
|
|
404
|
+
doc: { _id: id, collection, documentId, version, document: (0, path_ts_1.deepClone)(document) },
|
|
405
|
+
meta: {
|
|
406
|
+
version,
|
|
407
|
+
hlc: "",
|
|
408
|
+
dirty: false,
|
|
409
|
+
deleted: false,
|
|
410
|
+
createdAt: this.opts.time.now(),
|
|
411
|
+
updatedAt: this.opts.time.now(),
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
const existing = await this.opts.adapter.get(exports.SHADOW_COLLECTION, id, true);
|
|
415
|
+
await this.opts.adapter.write([
|
|
416
|
+
{ type: existing ? "update" : "insert", collection: exports.SHADOW_COLLECTION, _id: id, row },
|
|
417
|
+
]);
|
|
418
|
+
}
|
|
419
|
+
async readShadow(collection, documentId) {
|
|
420
|
+
const row = await this.opts.adapter.get(exports.SHADOW_COLLECTION, shadowId(collection, documentId), true);
|
|
421
|
+
return row ? row.doc.document : undefined;
|
|
422
|
+
}
|
|
423
|
+
async clearShadow(collection, documentId) {
|
|
424
|
+
await this.opts.adapter.write([
|
|
425
|
+
{ type: "hardDelete", collection: exports.SHADOW_COLLECTION, _id: shadowId(collection, documentId) },
|
|
426
|
+
]);
|
|
427
|
+
}
|
|
428
|
+
async emitQueueChanged() {
|
|
429
|
+
const counts = await this.opts.queue.counts();
|
|
430
|
+
this.opts.events.emit("queue:changed", { pending: counts.pending, failed: counts.failed });
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Adopt documents written before sync was enabled (§ "turning sync on later").
|
|
434
|
+
*
|
|
435
|
+
* Marks every existing document dirty at version 0 so the first sync pushes it. Without this,
|
|
436
|
+
* enabling sync on an existing app would leave all prior data stranded locally — the single most
|
|
437
|
+
* likely upgrade path, and the one a naive design silently breaks.
|
|
438
|
+
*/
|
|
439
|
+
async adoptExistingDocuments(collections) {
|
|
440
|
+
let adopted = 0;
|
|
441
|
+
for (const collection of collections) {
|
|
442
|
+
if (collection === exports.SHADOW_COLLECTION || collection.startsWith("__anchor"))
|
|
443
|
+
continue;
|
|
444
|
+
const ops = [];
|
|
445
|
+
const pending = [];
|
|
446
|
+
for await (const row of this.opts.adapter.scan(collection)) {
|
|
447
|
+
if (row.meta.dirty || row.meta.version > 0)
|
|
448
|
+
continue;
|
|
449
|
+
ops.push({
|
|
450
|
+
type: "update",
|
|
451
|
+
collection,
|
|
452
|
+
_id: row.doc._id,
|
|
453
|
+
row: { doc: row.doc, meta: { ...row.meta, dirty: true } },
|
|
454
|
+
});
|
|
455
|
+
pending.push({
|
|
456
|
+
collection,
|
|
457
|
+
documentId: row.doc._id,
|
|
458
|
+
operation: "insert",
|
|
459
|
+
payload: row.doc,
|
|
460
|
+
baseVersion: 0,
|
|
461
|
+
hlc: this.opts.clock.tickStamp(),
|
|
462
|
+
});
|
|
463
|
+
adopted++;
|
|
464
|
+
}
|
|
465
|
+
if (ops.length > 0) {
|
|
466
|
+
await this.opts.adapter.write(ops);
|
|
467
|
+
await this.opts.queue.enqueue(pending);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return adopted;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
exports.SyncEngine = SyncEngine;
|
|
474
|
+
function shadowId(collection, documentId) {
|
|
475
|
+
return `${collection}::${documentId}`;
|
|
476
|
+
}
|
|
477
|
+
function toWireMutation(m) {
|
|
478
|
+
return {
|
|
479
|
+
mutationId: m.mutationId,
|
|
480
|
+
collection: m.collection,
|
|
481
|
+
documentId: m.documentId,
|
|
482
|
+
operation: m.operation,
|
|
483
|
+
payload: m.payload,
|
|
484
|
+
clientId: m.clientId,
|
|
485
|
+
baseVersion: m.baseVersion,
|
|
486
|
+
hlc: m.hlc,
|
|
487
|
+
createdAt: m.createdAt,
|
|
488
|
+
...(m.resolvedFrom ? { resolvedFrom: m.resolvedFrom } : {}),
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/sync/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Anchor Sync Protocol, version 1.
|
|
3
|
+
*
|
|
4
|
+
* Design constraints that shaped this:
|
|
5
|
+
*
|
|
6
|
+
* - **Plain JSON, Mongoose-friendly.** Documents travel with `_id` as a 24-char hex string and
|
|
7
|
+
* timestamps as ISO-8601 UTC strings, because Mongoose casts both automatically. A backend can
|
|
8
|
+
* hand the payload straight to a model with no field mapping.
|
|
9
|
+
* - **Every change gets exactly one verdict.** `accepted | rejected | conflict`. A push that
|
|
10
|
+
* silently drops a change is indistinguishable from a lost mutation, so the response is
|
|
11
|
+
* positionally complete.
|
|
12
|
+
* - **Idempotent by construction.** The server memoises `(clientId, mutationId)`, so a retry after
|
|
13
|
+
* a timeout replays the original verdict rather than applying the write twice. This is what
|
|
14
|
+
* makes at-least-once delivery safe on a flaky mobile network.
|
|
15
|
+
*/
|
|
16
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
17
|
+
export type MutationOperation = "insert" | "update" | "replace" | "delete";
|
|
18
|
+
/** One durable local change. Persisted before the write is acknowledged, so a crash cannot lose it. */
|
|
19
|
+
export interface Mutation {
|
|
20
|
+
/** UUIDv7 — time-ordered, so the queue's natural key order is the apply order. */
|
|
21
|
+
mutationId: string;
|
|
22
|
+
collection: string;
|
|
23
|
+
documentId: string;
|
|
24
|
+
operation: MutationOperation;
|
|
25
|
+
/**
|
|
26
|
+
* For insert/replace: the full document. For update: the update operators actually applied.
|
|
27
|
+
* For delete: null.
|
|
28
|
+
*/
|
|
29
|
+
payload: Record<string, unknown> | null;
|
|
30
|
+
clientId: string;
|
|
31
|
+
/** Server version this change was made against. 0 means "never synced". */
|
|
32
|
+
baseVersion: number;
|
|
33
|
+
/** Hybrid logical clock stamp — the ordering authority (see SYNC_PROTOCOL.md). */
|
|
34
|
+
hlc: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
/** Set when this mutation is a re-push after resolving a conflict, for loop detection. */
|
|
37
|
+
resolvedFrom?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface QueuedMutation extends Mutation {
|
|
40
|
+
/** Monotonic local sequence, assigned on enqueue. Preserves ordering per document. */
|
|
41
|
+
seq: number;
|
|
42
|
+
status: "pending" | "inflight" | "failed";
|
|
43
|
+
attempts: number;
|
|
44
|
+
conflictAttempts: number;
|
|
45
|
+
lastError?: string;
|
|
46
|
+
/** Non-retryable failures (E11000, validation) park here rather than spinning forever. */
|
|
47
|
+
fatal?: boolean;
|
|
48
|
+
nextAttemptAt?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface PushRequest {
|
|
51
|
+
protocolVersion: number;
|
|
52
|
+
clientId: string;
|
|
53
|
+
sentAt: string;
|
|
54
|
+
changes: Mutation[];
|
|
55
|
+
}
|
|
56
|
+
export type ChangeStatus = "accepted" | "rejected" | "conflict";
|
|
57
|
+
export interface ChangeResult {
|
|
58
|
+
mutationId: string;
|
|
59
|
+
status: ChangeStatus;
|
|
60
|
+
/** Server version after applying, for accepted changes. */
|
|
61
|
+
version?: number;
|
|
62
|
+
/** The server's document — required for `conflict`, informative for `accepted`. */
|
|
63
|
+
document?: Record<string, unknown> | null;
|
|
64
|
+
/** Server HLC of the winning write, used to advance the client clock. */
|
|
65
|
+
hlc?: string;
|
|
66
|
+
/** Human-readable cause for `rejected`. */
|
|
67
|
+
reason?: string;
|
|
68
|
+
/** Machine-readable cause, e.g. 11000 for a duplicate key. */
|
|
69
|
+
code?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface PushResponse {
|
|
72
|
+
protocolVersion: number;
|
|
73
|
+
/** Server wall clock, used to estimate and correct client clock skew. */
|
|
74
|
+
serverTime: string;
|
|
75
|
+
serverHlc?: string;
|
|
76
|
+
results: ChangeResult[];
|
|
77
|
+
}
|
|
78
|
+
export interface PullRequest {
|
|
79
|
+
protocolVersion: number;
|
|
80
|
+
clientId: string;
|
|
81
|
+
/** Opaque cursor from the previous pull. Absent means "from the beginning". */
|
|
82
|
+
cursor?: string | null;
|
|
83
|
+
limit?: number;
|
|
84
|
+
collections?: string[];
|
|
85
|
+
}
|
|
86
|
+
export interface RemoteChange {
|
|
87
|
+
collection: string;
|
|
88
|
+
documentId: string;
|
|
89
|
+
/** null when the document was deleted on the server. */
|
|
90
|
+
document: Record<string, unknown> | null;
|
|
91
|
+
version: number;
|
|
92
|
+
deleted: boolean;
|
|
93
|
+
updatedAt: string;
|
|
94
|
+
hlc?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface PullResponse {
|
|
97
|
+
protocolVersion: number;
|
|
98
|
+
serverTime: string;
|
|
99
|
+
serverHlc?: string;
|
|
100
|
+
changes: RemoteChange[];
|
|
101
|
+
/** Pass back on the next pull. Incremental sync resumes exactly here. */
|
|
102
|
+
nextCursor: string | null;
|
|
103
|
+
hasMore: boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The backend abstraction (§13).
|
|
107
|
+
*
|
|
108
|
+
* Keeping the engine behind this means a WebSocket or GraphQL transport can be added later without
|
|
109
|
+
* touching queueing, conflict resolution or reliability logic.
|
|
110
|
+
*/
|
|
111
|
+
export interface SyncAdapter {
|
|
112
|
+
readonly name: string;
|
|
113
|
+
push(request: PushRequest): Promise<PushResponse>;
|
|
114
|
+
pull(request: PullRequest): Promise<PullResponse>;
|
|
115
|
+
}
|
|
116
|
+
/** Thrown for HTTP 401/403 so the engine can pause rather than discard queued work. */
|
|
117
|
+
export declare class SyncAuthError extends Error {
|
|
118
|
+
readonly name = "SyncAuthError";
|
|
119
|
+
readonly status: number;
|
|
120
|
+
constructor(status: number, message: string);
|
|
121
|
+
}
|
|
122
|
+
/** Thrown for transport failures — retryable, unlike an auth or validation error. */
|
|
123
|
+
export declare class SyncTransportError extends Error {
|
|
124
|
+
readonly name = "SyncTransportError";
|
|
125
|
+
readonly status: number | undefined;
|
|
126
|
+
constructor(message: string, status?: number);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/sync/protocol.ts"],"names":[],"mappings":"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"}
|