@korajs/core 1.0.0-beta.12 → 1.0.0-beta.14
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 +21 -13
- package/dist/bindings/index.d.cts +26 -6
- package/dist/bindings/index.d.ts +26 -6
- package/dist/{build-scope-map-CItP1gsz.d.cts → build-scope-map-C9zBTJ1R.d.cts} +1 -1
- package/dist/{build-scope-map-Cv5HfCQP.d.ts → build-scope-map-CZaMyZLV.d.ts} +1 -1
- package/dist/{chunk-5IICSH6H.js → chunk-QUD3DMSD.js} +668 -24
- package/dist/chunk-QUD3DMSD.js.map +1 -0
- package/dist/events-Da29Dt_3.d.cts +1737 -0
- package/dist/events-Da29Dt_3.d.ts +1737 -0
- package/dist/index.cjs +2548 -207
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +810 -220
- package/dist/index.d.ts +810 -220
- package/dist/index.js +2028 -334
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +857 -85
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +251 -21
- package/dist/internal.d.ts +251 -21
- package/dist/internal.js +447 -1
- package/dist/internal.js.map +1 -1
- package/dist/sql-gen-BOeuiyqu.d.cts +622 -0
- package/dist/sql-gen-CXTA6w-w.d.ts +622 -0
- package/package.json +2 -1
- package/dist/chunk-5IICSH6H.js.map +0 -1
- package/dist/events-D7JCtQSD.d.cts +0 -1010
- package/dist/events-D7JCtQSD.d.ts +0 -1010
- package/dist/operation-BX4ok7U4.d.ts +0 -164
- package/dist/operation-BXvJ6RiA.d.cts +0 -164
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @korajs/core
|
|
2
2
|
|
|
3
|
-
Schema definitions, operations,
|
|
3
|
+
Schema definitions, type inference, operations, the hybrid logical clock, version vectors and the record fold (the per-field merge every replica runs) for Kora.js. It is the foundation: every other package depends on it.
|
|
4
4
|
|
|
5
5
|
> Most developers don't install this directly. Use [`korajs`](https://www.npmjs.com/package/korajs) instead.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
pnpm add @korajs/core
|
|
10
|
+
pnpm add @korajs/core@beta
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
@@ -25,7 +25,7 @@ const schema = defineSchema({
|
|
|
25
25
|
title: t.string(),
|
|
26
26
|
completed: t.boolean().default(false),
|
|
27
27
|
tags: t.array(t.string()).default([]),
|
|
28
|
-
notes: t.richtext(),
|
|
28
|
+
notes: t.richtext().optional(),
|
|
29
29
|
priority: t.enum(['low', 'medium', 'high']).default('medium'),
|
|
30
30
|
createdAt: t.timestamp().auto(),
|
|
31
31
|
},
|
|
@@ -48,29 +48,37 @@ const ts2 = clock.now()
|
|
|
48
48
|
// Timestamps are always monotonically increasing
|
|
49
49
|
HybridLogicalClock.compare(ts1, ts2) // negative (ts1 < ts2)
|
|
50
50
|
|
|
51
|
-
// Merge
|
|
52
|
-
|
|
51
|
+
// Merge a remote timestamp (rejected, without changing the clock, if malformed or
|
|
52
|
+
// more than 5 minutes in the future)
|
|
53
|
+
const ts3 = clock.receive({ wallTime: ts2.wallTime + 5, logical: 0, nodeId: 'node-2' })
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
### Version Vectors
|
|
56
57
|
|
|
57
58
|
```typescript
|
|
58
|
-
import { mergeVectors,
|
|
59
|
+
import { computeDelta, mergeVectors, type Operation, type VersionVector } from '@korajs/core'
|
|
60
|
+
|
|
61
|
+
declare const localVector: VersionVector
|
|
62
|
+
declare const remoteVector: VersionVector
|
|
63
|
+
declare const log: { getRange(nodeId: string, from: number, to: number): Promise<Operation[]> }
|
|
59
64
|
|
|
60
65
|
const merged = mergeVectors(localVector, remoteVector)
|
|
61
|
-
const missing =
|
|
66
|
+
const missing = await computeDelta(localVector, remoteVector, log) // causal order
|
|
62
67
|
```
|
|
63
68
|
|
|
64
69
|
## What's Inside
|
|
65
70
|
|
|
66
|
-
- **Schema system
|
|
67
|
-
- **Operation type
|
|
68
|
-
- **Hybrid Logical Clock
|
|
69
|
-
- **Version vectors
|
|
70
|
-
- **
|
|
71
|
+
- **Schema system**: `defineSchema`, `t` field builders, full TypeScript type inference
|
|
72
|
+
- **Operation type**: immutable, content-addressed mutation records
|
|
73
|
+
- **Hybrid Logical Clock**: causal ordering without synchronized clocks
|
|
74
|
+
- **Version vectors**: delta computation for uploads
|
|
75
|
+
- **Record fold**: `foldRecord`, `mergeOp`, `materialize`, `joinStates`: one deterministic per-field CRDT
|
|
76
|
+
- **Atomic ops**: `op.increment`, `op.append` and friends
|
|
77
|
+
- **Migrations**: `migrate()` builders for schema versions
|
|
78
|
+
- **Error types**: structured `KoraError` base class with codes
|
|
71
79
|
|
|
72
80
|
## License
|
|
73
81
|
|
|
74
82
|
MIT
|
|
75
83
|
|
|
76
|
-
See the [
|
|
84
|
+
See the [Core API reference](https://korajs.dev/api/core) and the [guides](https://korajs.dev).
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as ScopeMap } from '../build-scope-map-
|
|
1
|
+
import { X as KoraEventEmitter } from '../events-Da29Dt_3.cjs';
|
|
2
|
+
import { S as ScopeMap } from '../build-scope-map-C9zBTJ1R.cjs';
|
|
3
3
|
|
|
4
4
|
/** Sync status shape consumed by framework binding hooks (matches {@link SyncStatusInfo} in `@korajs/sync`). */
|
|
5
5
|
interface KoraBindingSyncStatus {
|
|
6
|
-
status: 'connected' | 'reconnecting' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch' | 'clock-error' | 'auth-required';
|
|
6
|
+
status: 'connected' | 'reconnecting' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch' | 'clock-error' | 'auth-required' | 'encryption-locked';
|
|
7
7
|
reconnecting: boolean;
|
|
8
8
|
pendingOperations: number;
|
|
9
9
|
lastSyncedAt: number | null;
|
|
@@ -62,8 +62,14 @@ interface UseMutationResultBase<TData, TArgs extends unknown[]> {
|
|
|
62
62
|
* Created by `createKoraAuthSync()` in `@korajs/auth`.
|
|
63
63
|
*/
|
|
64
64
|
interface AuthSyncBinding {
|
|
65
|
-
/**
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Returns the access token for sync handshake (empty string when signed out).
|
|
67
|
+
* Called with `{ forceRefresh: true }` after the server ended the session with
|
|
68
|
+
* `AUTH_EXPIRED` / `AUTH_REVOKED`: refresh instead of returning the cached token.
|
|
69
|
+
*/
|
|
70
|
+
auth: (options?: {
|
|
71
|
+
forceRefresh?: boolean;
|
|
72
|
+
}) => Promise<{
|
|
67
73
|
token: string;
|
|
68
74
|
}>;
|
|
69
75
|
/** Resolve whether sync may currently open a transport. Tokens are never used as readiness signals. */
|
|
@@ -92,7 +98,21 @@ type AuthSyncState = {
|
|
|
92
98
|
} | {
|
|
93
99
|
state: 'authenticated';
|
|
94
100
|
userId: string;
|
|
95
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Fresh access token, or null while authenticated-offline: the identity
|
|
103
|
+
* is known from stored credentials but no fresh token can be minted now.
|
|
104
|
+
* The local store opens either way; a sync transport waits for a token.
|
|
105
|
+
*/
|
|
106
|
+
token: string | null;
|
|
107
|
+
/** Device id of the stored credentials, when known. */
|
|
108
|
+
deviceId?: string;
|
|
109
|
+
/** True while the session is authenticated-offline (or locked). */
|
|
110
|
+
offline?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* True when the offline grace period ran out or the device clock moved
|
|
113
|
+
* backwards. The UI should lock; local data is never wiped.
|
|
114
|
+
*/
|
|
115
|
+
locked?: boolean;
|
|
96
116
|
};
|
|
97
117
|
|
|
98
118
|
interface MutationControllerState {
|
package/dist/bindings/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as ScopeMap } from '../build-scope-map-
|
|
1
|
+
import { X as KoraEventEmitter } from '../events-Da29Dt_3.js';
|
|
2
|
+
import { S as ScopeMap } from '../build-scope-map-CZaMyZLV.js';
|
|
3
3
|
|
|
4
4
|
/** Sync status shape consumed by framework binding hooks (matches {@link SyncStatusInfo} in `@korajs/sync`). */
|
|
5
5
|
interface KoraBindingSyncStatus {
|
|
6
|
-
status: 'connected' | 'reconnecting' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch' | 'clock-error' | 'auth-required';
|
|
6
|
+
status: 'connected' | 'reconnecting' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch' | 'clock-error' | 'auth-required' | 'encryption-locked';
|
|
7
7
|
reconnecting: boolean;
|
|
8
8
|
pendingOperations: number;
|
|
9
9
|
lastSyncedAt: number | null;
|
|
@@ -62,8 +62,14 @@ interface UseMutationResultBase<TData, TArgs extends unknown[]> {
|
|
|
62
62
|
* Created by `createKoraAuthSync()` in `@korajs/auth`.
|
|
63
63
|
*/
|
|
64
64
|
interface AuthSyncBinding {
|
|
65
|
-
/**
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Returns the access token for sync handshake (empty string when signed out).
|
|
67
|
+
* Called with `{ forceRefresh: true }` after the server ended the session with
|
|
68
|
+
* `AUTH_EXPIRED` / `AUTH_REVOKED`: refresh instead of returning the cached token.
|
|
69
|
+
*/
|
|
70
|
+
auth: (options?: {
|
|
71
|
+
forceRefresh?: boolean;
|
|
72
|
+
}) => Promise<{
|
|
67
73
|
token: string;
|
|
68
74
|
}>;
|
|
69
75
|
/** Resolve whether sync may currently open a transport. Tokens are never used as readiness signals. */
|
|
@@ -92,7 +98,21 @@ type AuthSyncState = {
|
|
|
92
98
|
} | {
|
|
93
99
|
state: 'authenticated';
|
|
94
100
|
userId: string;
|
|
95
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Fresh access token, or null while authenticated-offline: the identity
|
|
103
|
+
* is known from stored credentials but no fresh token can be minted now.
|
|
104
|
+
* The local store opens either way; a sync transport waits for a token.
|
|
105
|
+
*/
|
|
106
|
+
token: string | null;
|
|
107
|
+
/** Device id of the stored credentials, when known. */
|
|
108
|
+
deviceId?: string;
|
|
109
|
+
/** True while the session is authenticated-offline (or locked). */
|
|
110
|
+
offline?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* True when the offline grace period ran out or the device clock moved
|
|
113
|
+
* backwards. The UI should lock; local data is never wiped.
|
|
114
|
+
*/
|
|
115
|
+
locked?: boolean;
|
|
96
116
|
};
|
|
97
117
|
|
|
98
118
|
interface MutationControllerState {
|