@korajs/sync 0.1.0 → 0.1.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/README.md +67 -0
- package/dist/index.cjs +14 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @korajs/sync
|
|
2
|
+
|
|
3
|
+
Sync protocol and transports for Kora.js. Handles version vector delta sync, causal ordering, Protobuf wire format, and automatic reconnection with operation queuing.
|
|
4
|
+
|
|
5
|
+
> Most developers don't install this directly. Use [`korajs`](https://www.npmjs.com/package/korajs) instead.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @korajs/sync
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### WebSocket Transport
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { SyncEngine, WebSocketTransport } from '@korajs/sync'
|
|
19
|
+
|
|
20
|
+
const transport = new WebSocketTransport({
|
|
21
|
+
url: 'wss://my-server.com/kora',
|
|
22
|
+
auth: async () => ({ token: await getAuthToken() }),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const sync = new SyncEngine({
|
|
26
|
+
transport,
|
|
27
|
+
mergeEngine,
|
|
28
|
+
operationLog,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
sync.start()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### HTTP Transport
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { HttpTransport } from '@korajs/sync'
|
|
38
|
+
|
|
39
|
+
const transport = new HttpTransport({
|
|
40
|
+
url: 'https://my-server.com/kora/sync',
|
|
41
|
+
pollInterval: 5000,
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Sync Events
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
sync.on('connected', () => console.log('Connected'))
|
|
49
|
+
sync.on('disconnected', (reason) => console.log('Disconnected:', reason))
|
|
50
|
+
sync.on('sent', (ops) => console.log('Sent', ops.length, 'operations'))
|
|
51
|
+
sync.on('received', (ops) => console.log('Received', ops.length, 'operations'))
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Protocol
|
|
55
|
+
|
|
56
|
+
1. **Handshake** -- exchange version vectors to determine what each side is missing
|
|
57
|
+
2. **Delta sync** -- send only the operations the other side doesn't have
|
|
58
|
+
3. **Real-time streaming** -- bidirectional operation flow after initial sync
|
|
59
|
+
4. **Resumable** -- reconnects pick up from the last acknowledged sequence number
|
|
60
|
+
|
|
61
|
+
Operations are always sent in causal order. The protocol is idempotent -- duplicate operations are detected via content-addressing and safely ignored.
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
MIT
|
|
66
|
+
|
|
67
|
+
See the [full documentation](https://github.com/ehoneahobed/kora) for guides, API reference, and examples.
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -102,7 +112,8 @@ function isErrorMessage(value) {
|
|
|
102
112
|
|
|
103
113
|
// src/protocol/serializer.ts
|
|
104
114
|
var import_core = require("@korajs/core");
|
|
105
|
-
var import_minimal = require("protobufjs/minimal");
|
|
115
|
+
var import_minimal = __toESM(require("protobufjs/minimal"), 1);
|
|
116
|
+
var { Reader, Writer } = import_minimal.default;
|
|
106
117
|
function versionVectorToWire(vector) {
|
|
107
118
|
const wire = {};
|
|
108
119
|
for (const [nodeId, seq] of vector) {
|
|
@@ -385,7 +396,7 @@ function toBytes(data) {
|
|
|
385
396
|
throw new import_core.SyncError("Unsupported sync payload type", { receivedType: typeof data });
|
|
386
397
|
}
|
|
387
398
|
function encodeEnvelope(envelope) {
|
|
388
|
-
const writer =
|
|
399
|
+
const writer = Writer.create();
|
|
389
400
|
if (envelope.type.length > 0) writer.uint32(10).string(envelope.type);
|
|
390
401
|
if (envelope.messageId.length > 0) writer.uint32(18).string(envelope.messageId);
|
|
391
402
|
if (envelope.nodeId && envelope.nodeId.length > 0) writer.uint32(26).string(envelope.nodeId);
|
|
@@ -424,7 +435,7 @@ function encodeEnvelope(envelope) {
|
|
|
424
435
|
return writer.finish();
|
|
425
436
|
}
|
|
426
437
|
function decodeEnvelope(bytes) {
|
|
427
|
-
const reader =
|
|
438
|
+
const reader = Reader.create(bytes);
|
|
428
439
|
const envelope = { type: "error", messageId: "" };
|
|
429
440
|
while (reader.pos < reader.len) {
|
|
430
441
|
const tag = reader.uint32();
|