@rljson/rljson 0.0.76 → 0.0.78
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.architecture.md +26 -0
- package/README.public.md +26 -0
- package/dist/README.architecture.md +26 -0
- package/dist/README.public.md +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/sync/conflict.d.ts +39 -0
- package/package.json +1 -1
package/README.architecture.md
CHANGED
|
@@ -678,6 +678,32 @@ ephemeral Connector `origin` (which changes on every instantiation), a
|
|
|
678
678
|
|
|
679
679
|
Format: `"client_"` + 12-character nanoid (e.g. `"client_V1StGXR8_Z5j"`).
|
|
680
680
|
|
|
681
|
+
### Conflict Detection Types
|
|
682
|
+
|
|
683
|
+
The sync protocol includes types for detecting DAG branch conflicts in the
|
|
684
|
+
InsertHistory. A **DAG branch** occurs when two or more InsertHistory rows
|
|
685
|
+
share the same predecessor, creating divergent branches from concurrent
|
|
686
|
+
writes by different clients.
|
|
687
|
+
|
|
688
|
+
| Type | Description |
|
|
689
|
+
| ------------------ | --------------------------------------------------------------------- |
|
|
690
|
+
| `ConflictType` | String literal union — currently `'dagBranch'` |
|
|
691
|
+
| `Conflict` | Interface describing a detected conflict: table, type, time, branches |
|
|
692
|
+
| `ConflictCallback` | `(conflict: Conflict) => void` — callback type for observers |
|
|
693
|
+
|
|
694
|
+
**Conflict interface fields:**
|
|
695
|
+
|
|
696
|
+
| Field | Type | Description |
|
|
697
|
+
| ------------ | ----------------------- | ----------------------------------------------------- |
|
|
698
|
+
| `table` | `string` | Table where the conflict was detected (no suffix) |
|
|
699
|
+
| `type` | `ConflictType` | `'dagBranch'` |
|
|
700
|
+
| `detectedAt` | `number` | Timestamp (ms since epoch) of detection |
|
|
701
|
+
| `branches` | `InsertHistoryTimeId[]` | Tip timeIds forming the DAG fork (always ≥ 2 entries) |
|
|
702
|
+
|
|
703
|
+
Detection is protocol-level only — no resolution logic. Upper layers
|
|
704
|
+
(application code or `@rljson/db`) use these types to signal and react
|
|
705
|
+
to conflicts.
|
|
706
|
+
|
|
681
707
|
## Package Structure
|
|
682
708
|
|
|
683
709
|
```
|
package/README.public.md
CHANGED
|
@@ -360,6 +360,32 @@ isClientId(id); // true
|
|
|
360
360
|
isClientId('not-a-client-id'); // false
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
### Conflict Detection Types
|
|
364
|
+
|
|
365
|
+
Protocol-level types for DAG branch conflict detection. A conflict occurs when the InsertHistory for a table has diverged into multiple branches (multiple "tips" that are not ancestors of each other), indicating concurrent writes from different clients.
|
|
366
|
+
|
|
367
|
+
Detection only — no resolution: these types signal that a conflict exists. Resolution logic is left to upper layers (application code).
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import type { Conflict, ConflictCallback, ConflictType } from '@rljson/rljson';
|
|
371
|
+
|
|
372
|
+
// ConflictType — currently only 'dagBranch'
|
|
373
|
+
const type: ConflictType = 'dagBranch';
|
|
374
|
+
|
|
375
|
+
// Conflict — describes a detected fork in InsertHistory
|
|
376
|
+
const conflict: Conflict = {
|
|
377
|
+
table: 'cars', // Table where the conflict was detected
|
|
378
|
+
type: 'dagBranch', // Type of conflict
|
|
379
|
+
detectedAt: Date.now(), // Detection timestamp (ms since epoch)
|
|
380
|
+
branches: ['17000…:AbCd', '17000…:EfGh'] // InsertHistory tip timeIds forming the fork
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
// ConflictCallback — fires when a conflict is detected
|
|
384
|
+
const onConflict: ConflictCallback = (conflict: Conflict) => {
|
|
385
|
+
console.log(`Conflict in ${conflict.table}:`, conflict.branches);
|
|
386
|
+
};
|
|
387
|
+
```
|
|
388
|
+
|
|
363
389
|
## Utilities
|
|
364
390
|
|
|
365
391
|
### TimeId
|
|
@@ -678,6 +678,32 @@ ephemeral Connector `origin` (which changes on every instantiation), a
|
|
|
678
678
|
|
|
679
679
|
Format: `"client_"` + 12-character nanoid (e.g. `"client_V1StGXR8_Z5j"`).
|
|
680
680
|
|
|
681
|
+
### Conflict Detection Types
|
|
682
|
+
|
|
683
|
+
The sync protocol includes types for detecting DAG branch conflicts in the
|
|
684
|
+
InsertHistory. A **DAG branch** occurs when two or more InsertHistory rows
|
|
685
|
+
share the same predecessor, creating divergent branches from concurrent
|
|
686
|
+
writes by different clients.
|
|
687
|
+
|
|
688
|
+
| Type | Description |
|
|
689
|
+
| ------------------ | --------------------------------------------------------------------- |
|
|
690
|
+
| `ConflictType` | String literal union — currently `'dagBranch'` |
|
|
691
|
+
| `Conflict` | Interface describing a detected conflict: table, type, time, branches |
|
|
692
|
+
| `ConflictCallback` | `(conflict: Conflict) => void` — callback type for observers |
|
|
693
|
+
|
|
694
|
+
**Conflict interface fields:**
|
|
695
|
+
|
|
696
|
+
| Field | Type | Description |
|
|
697
|
+
| ------------ | ----------------------- | ----------------------------------------------------- |
|
|
698
|
+
| `table` | `string` | Table where the conflict was detected (no suffix) |
|
|
699
|
+
| `type` | `ConflictType` | `'dagBranch'` |
|
|
700
|
+
| `detectedAt` | `number` | Timestamp (ms since epoch) of detection |
|
|
701
|
+
| `branches` | `InsertHistoryTimeId[]` | Tip timeIds forming the DAG fork (always ≥ 2 entries) |
|
|
702
|
+
|
|
703
|
+
Detection is protocol-level only — no resolution logic. Upper layers
|
|
704
|
+
(application code or `@rljson/db`) use these types to signal and react
|
|
705
|
+
to conflicts.
|
|
706
|
+
|
|
681
707
|
## Package Structure
|
|
682
708
|
|
|
683
709
|
```
|
package/dist/README.public.md
CHANGED
|
@@ -360,6 +360,32 @@ isClientId(id); // true
|
|
|
360
360
|
isClientId('not-a-client-id'); // false
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
### Conflict Detection Types
|
|
364
|
+
|
|
365
|
+
Protocol-level types for DAG branch conflict detection. A conflict occurs when the InsertHistory for a table has diverged into multiple branches (multiple "tips" that are not ancestors of each other), indicating concurrent writes from different clients.
|
|
366
|
+
|
|
367
|
+
Detection only — no resolution: these types signal that a conflict exists. Resolution logic is left to upper layers (application code).
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import type { Conflict, ConflictCallback, ConflictType } from '@rljson/rljson';
|
|
371
|
+
|
|
372
|
+
// ConflictType — currently only 'dagBranch'
|
|
373
|
+
const type: ConflictType = 'dagBranch';
|
|
374
|
+
|
|
375
|
+
// Conflict — describes a detected fork in InsertHistory
|
|
376
|
+
const conflict: Conflict = {
|
|
377
|
+
table: 'cars', // Table where the conflict was detected
|
|
378
|
+
type: 'dagBranch', // Type of conflict
|
|
379
|
+
detectedAt: Date.now(), // Detection timestamp (ms since epoch)
|
|
380
|
+
branches: ['17000…:AbCd', '17000…:EfGh'] // InsertHistory tip timeIds forming the fork
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
// ConflictCallback — fires when a conflict is detected
|
|
384
|
+
const onConflict: ConflictCallback = (conflict: Conflict) => {
|
|
385
|
+
console.log(`Conflict in ${conflict.table}:`, conflict.branches);
|
|
386
|
+
};
|
|
387
|
+
```
|
|
388
|
+
|
|
363
389
|
## Utilities
|
|
364
390
|
|
|
365
391
|
### TimeId
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export * from './rljson.ts';
|
|
|
18
18
|
export * from './route/route.ts';
|
|
19
19
|
export * from './sync/ack-payload.ts';
|
|
20
20
|
export * from './sync/client-id.ts';
|
|
21
|
+
export * from './sync/conflict.ts';
|
|
21
22
|
export * from './sync/connector-payload.ts';
|
|
22
23
|
export * from './sync/gap-fill.ts';
|
|
23
24
|
export * from './sync/sync-config.ts';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { InsertHistoryTimeId } from '../insertHistory/insertHistory.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The type of conflict detected in the InsertHistory DAG.
|
|
4
|
+
*
|
|
5
|
+
* - `'dagBranch'` — Two or more InsertHistory rows share the same
|
|
6
|
+
* predecessor, creating divergent branches. This indicates concurrent
|
|
7
|
+
* writes from different clients that have not yet been merged.
|
|
8
|
+
*/
|
|
9
|
+
export type ConflictType = 'dagBranch';
|
|
10
|
+
/**
|
|
11
|
+
* Represents a detected conflict in the InsertHistory DAG.
|
|
12
|
+
*
|
|
13
|
+
* A `Conflict` is emitted when the system detects that the InsertHistory
|
|
14
|
+
* for a table has diverged into multiple branches (multiple "tips" that
|
|
15
|
+
* are not ancestors of each other).
|
|
16
|
+
* Detection only — no resolution: this type signals that a conflict
|
|
17
|
+
* exists. Resolution logic is left to upper layers (application code).
|
|
18
|
+
*/
|
|
19
|
+
export interface Conflict {
|
|
20
|
+
/** The table where the conflict was detected (without InsertHistory suffix). */
|
|
21
|
+
table: string;
|
|
22
|
+
/** The type of conflict. */
|
|
23
|
+
type: ConflictType;
|
|
24
|
+
/** Timestamp (ms since epoch) when the conflict was detected. */
|
|
25
|
+
detectedAt: number;
|
|
26
|
+
/**
|
|
27
|
+
* The InsertHistory tip timeIds that form the branches.
|
|
28
|
+
*
|
|
29
|
+
* A "tip" is a timeId that is not referenced as `previous` by any other
|
|
30
|
+
* InsertHistory row. Multiple tips indicate a DAG fork.
|
|
31
|
+
*
|
|
32
|
+
* Always contains at least two entries when `type === 'dagBranch'`.
|
|
33
|
+
*/
|
|
34
|
+
branches: InsertHistoryTimeId[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Callback invoked when a conflict is detected.
|
|
38
|
+
*/
|
|
39
|
+
export type ConflictCallback = (conflict: Conflict) => void;
|