@korajs/core 0.6.0 → 1.0.0-beta.1

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.
@@ -89,6 +89,56 @@ declare class ArrayFieldBuilder<ItemKind extends FieldKind = FieldKind, Req exte
89
89
  merge(strategy: FieldMergeStrategy): ArrayFieldBuilder<ItemKind, Req, Auto>;
90
90
  _build(): FieldDescriptor;
91
91
  }
92
+ /**
93
+ * Field builder for structured object fields with a nested field schema.
94
+ *
95
+ * Each nested key merges by its own declared kind (scalars via LWW, nested
96
+ * arrays via add-wins, nested objects recursively), so two devices editing
97
+ * different keys of the same object offline both converge on reconnect instead
98
+ * of one clobbering the other.
99
+ */
100
+ declare class ObjectFieldBuilder<Req extends boolean = true, Auto extends boolean = false> extends FieldBuilder<'object', Req, Auto> {
101
+ private readonly _fields;
102
+ constructor(fields: Record<string, FieldBuilder>, required?: Req, defaultValue?: unknown, auto?: Auto, mergeStrategy?: FieldMergeStrategy | null);
103
+ optional(): ObjectFieldBuilder<false, Auto>;
104
+ default(value: Record<string, unknown>): ObjectFieldBuilder<false, Auto>;
105
+ auto(): ObjectFieldBuilder<false, true>;
106
+ merge(strategy: FieldMergeStrategy): ObjectFieldBuilder<Req, Auto>;
107
+ _build(): FieldDescriptor;
108
+ }
109
+ /**
110
+ * Field builder for dynamic-key JSON values. Carries a compile-time shape `T`
111
+ * for inference while merging structurally as a convergent CRDT: a plain-object
112
+ * value recurses as a map, an array merges add-wins, any other value is a scalar
113
+ * leaf under last-write-wins.
114
+ */
115
+ declare class JsonFieldBuilder<T = unknown, Req extends boolean = true, Auto extends boolean = false> extends FieldBuilder<'json', Req, Auto> {
116
+ optional(): JsonFieldBuilder<T, false, Auto>;
117
+ default(value: T): JsonFieldBuilder<T, false, Auto>;
118
+ auto(): JsonFieldBuilder<T, false, true>;
119
+ merge(strategy: FieldMergeStrategy): JsonFieldBuilder<T, Req, Auto>;
120
+ _build(): FieldDescriptor;
121
+ }
122
+ /**
123
+ * Field builder for secret fields (passwords, tokens, API keys).
124
+ *
125
+ * A secret field's value is never exposed in merge traces, DevTools, or logs
126
+ * (it is redacted at the point traces are built). Its at-rest protection is
127
+ * chosen with `.hashed()` (one-way, for passwords) or `.encrypted()` (reversible,
128
+ * for tokens); the default is `encrypted`.
129
+ */
130
+ declare class SecretFieldBuilder<Req extends boolean = true, Auto extends boolean = false> extends FieldBuilder<'secret', Req, Auto> {
131
+ private readonly _secretMode;
132
+ constructor(secretMode?: SecretMode, required?: Req, defaultValue?: unknown, auto?: Auto, mergeStrategy?: FieldMergeStrategy | null);
133
+ /** Store this secret as a one-way salted hash (passwords: verify, never read back). */
134
+ hashed(): SecretFieldBuilder<Req, Auto>;
135
+ /** Store this secret as reversible ciphertext (tokens/keys: decrypt to use). */
136
+ encrypted(): SecretFieldBuilder<Req, Auto>;
137
+ optional(): SecretFieldBuilder<false, Auto>;
138
+ auto(): SecretFieldBuilder<false, true>;
139
+ merge(strategy: FieldMergeStrategy): SecretFieldBuilder<Req, Auto>;
140
+ _build(): FieldDescriptor;
141
+ }
92
142
  /**
93
143
  * Type builder namespace. The developer's primary interface for defining field types.
94
144
  *
@@ -103,6 +153,8 @@ declare class ArrayFieldBuilder<ItemKind extends FieldKind = FieldKind, Req exte
103
153
  * notes: t.richtext(),
104
154
  * tags: t.array(t.string()).default([]),
105
155
  * priority: t.enum(['low', 'medium', 'high']).default('medium'),
156
+ * settings: t.object({ theme: t.string(), fontSize: t.number() }),
157
+ * metadata: t.json<{ source: string }>(),
106
158
  * createdAt: t.timestamp().auto(),
107
159
  * }
108
160
  * ```
@@ -115,6 +167,10 @@ declare const t: {
115
167
  richtext(): FieldBuilder<"richtext", true, false>;
116
168
  enum<const V extends readonly string[]>(values: V): EnumFieldBuilder<V, true, false>;
117
169
  array<K extends FieldKind>(itemBuilder: FieldBuilder<K>): ArrayFieldBuilder<K, true, false>;
170
+ object(fields: Record<string, FieldBuilder>): ObjectFieldBuilder<true, false>;
171
+ json<T = unknown>(): JsonFieldBuilder<T, true, false>;
172
+ blob(): FieldBuilder<"blob", true, false>;
173
+ secret(): SecretFieldBuilder<true, false>;
118
174
  };
119
175
 
120
176
  /**
@@ -390,7 +446,39 @@ interface OperationInput {
390
446
  /** Version vector: maps nodeId to the max sequence number seen from that node */
391
447
  type VersionVector = Map<string, number>;
392
448
  /** Field kinds supported by the schema system */
393
- type FieldKind = 'string' | 'number' | 'boolean' | 'timestamp' | 'richtext' | 'enum' | 'array';
449
+ type FieldKind = 'string' | 'number' | 'boolean' | 'timestamp' | 'richtext' | 'enum' | 'array' | 'object' | 'json' | 'blob' | 'secret';
450
+ /**
451
+ * How a `secret` field's value is protected at rest.
452
+ * - `hashed`: one-way (passwords). Stored as a salted hash; never read back.
453
+ * - `encrypted`: reversible (tokens, keys). Stored as ciphertext; decrypted to use.
454
+ */
455
+ type SecretMode = 'hashed' | 'encrypted';
456
+ /**
457
+ * A content-addressed reference to binary data stored out of band.
458
+ *
459
+ * A `blob` field never carries the bytes in the operation log; it carries this
460
+ * small reference. The bytes live in a content-addressed blob store, keyed by
461
+ * `hash`, so identical content is stored once and never re-synced to a peer that
462
+ * already has that hash.
463
+ */
464
+ interface BlobRef {
465
+ /** Hex-encoded SHA-256 hash of the bytes. The content address. */
466
+ hash: string;
467
+ /** Size of the bytes in bytes. */
468
+ size: number;
469
+ /** Optional MIME type (for example "image/png"). */
470
+ mimeType?: string;
471
+ /** Optional original filename. */
472
+ filename?: string;
473
+ /**
474
+ * Hex-encoded SHA-256 hash of this blob's manifest — the small chunk index a
475
+ * peer fetches first to learn how to pull the bytes out of band. Present when
476
+ * the blob was stored for transfer; absent for a bare reference created without
477
+ * chunking. Because it is a content address like `hash`, the manifest is fetched
478
+ * and integrity-verified over the same channel as the chunks.
479
+ */
480
+ manifestHash?: string;
481
+ }
394
482
  /**
395
483
  * Comprehensive sync diagnostics snapshot.
396
484
  * Provides connection, latency, throughput, queue, and error metrics
@@ -398,7 +486,7 @@ type FieldKind = 'string' | 'number' | 'boolean' | 'timestamp' | 'richtext' | 'e
398
486
  */
399
487
  interface SyncDiagnosticsSnapshot {
400
488
  /** Current developer-facing sync status */
401
- status: 'connected' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch';
489
+ status: 'connected' | 'syncing' | 'synced' | 'offline' | 'error' | 'schema-mismatch' | 'clock-error';
402
490
  /** Timestamp when the current connection was established, or null if disconnected */
403
491
  connectedAt: number | null;
404
492
  /** Timestamp when the last disconnection occurred, or null if never disconnected */
@@ -490,6 +578,17 @@ interface FieldDescriptor {
490
578
  mergeStrategy: FieldMergeStrategy | null;
491
579
  /** State machine transition map for enum fields. Null if no transitions declared. */
492
580
  transitions: TransitionMap | null;
581
+ /**
582
+ * Nested field descriptors for `object` fields (each key merges by its own
583
+ * kind). Null for `json` fields (dynamic keys, resolved structurally) and for
584
+ * all non-structured kinds.
585
+ */
586
+ nestedFields?: Record<string, FieldDescriptor> | null;
587
+ /**
588
+ * At-rest protection mode for `secret` fields (`hashed` or `encrypted`).
589
+ * Null/absent for every other kind.
590
+ */
591
+ secretMode?: SecretMode | null;
493
592
  }
494
593
  /**
495
594
  * Defines a state machine on an enum field, constraining valid state transitions.
@@ -696,6 +795,18 @@ type KoraEvent = {
696
795
  } | {
697
796
  type: 'sync:auth-failed';
698
797
  reason: string;
798
+ } | {
799
+ type: 'sync:clock-skew';
800
+ /** serverTime - localTime in ms. Negative = this device's clock is fast. */
801
+ skewMs: number;
802
+ severity: 'info' | 'slow-warning' | 'fast-blocked';
803
+ source: 'handshake' | 'server-reject';
804
+ } | {
805
+ type: 'sync:clock-rebase';
806
+ /** Number of unsynced operations that were re-stamped. */
807
+ rebasedCount: number;
808
+ /** How far ahead of server time the most future queued operation was, in ms. */
809
+ maxSkewMs: number;
699
810
  } | {
700
811
  type: 'sync:sent';
701
812
  operations: Operation[];
@@ -793,4 +904,4 @@ interface KoraEventEmitter {
793
904
  emit<T extends KoraEventType>(event: KoraEventByType<T>): void;
794
905
  }
795
906
 
796
- export { type AtomicOpType as A, type SequenceConfig as B, type CustomResolver as C, type StateMachineDefinition as D, EnumFieldBuilder as E, FieldBuilder as F, type SyncDiagnosticsSnapshot as G, type HLCTimestamp as H, type SyncRuleDefinition as I, type TimeSource as J, type KoraEvent as K, migrate as L, type MigrationDefinition as M, t as N, type OperationType as O, type RandomSource as R, type SchemaDefinition as S, type TransitionMap as T, type VersionVector as V, type AtomicOp as a, type CollectionDefinition as b, type RelationDefinition as c, ArrayFieldBuilder as d, type FieldKind as e, type Operation as f, type MigrationStep as g, type StateMachineConstraint as h, type TransitionValidationResult as i, CONNECTION_QUALITIES as j, type ConnectionQuality as k, type Constraint as l, type FieldDescriptor as m, type FieldMergeStrategy as n, type KoraEventByType as o, type KoraEventEmitter as p, type KoraEventListener as q, type KoraEventType as r, MERGE_STRATEGIES as s, type MergeStrategy as t, type MergeTrace as u, MigrationBuilder as v, type OnDeleteAction as w, type OperationInput as x, type RelationType as y, RollbackBuilder as z };
907
+ export { type AtomicOpType as A, type BlobRef as B, type CollectionDefinition as C, type SecretMode as D, EnumFieldBuilder as E, FieldBuilder as F, type SequenceConfig as G, type HLCTimestamp as H, type StateMachineDefinition as I, JsonFieldBuilder as J, type KoraEvent as K, type SyncDiagnosticsSnapshot as L, type MigrationDefinition as M, type SyncRuleDefinition as N, type OperationType as O, type TimeSource as P, migrate as Q, type RandomSource as R, type SchemaDefinition as S, type TransitionMap as T, t as U, type VersionVector as V, type AtomicOp as a, type CustomResolver as b, type RelationDefinition as c, ArrayFieldBuilder as d, type FieldKind as e, type Operation as f, type MigrationStep as g, type StateMachineConstraint as h, type TransitionValidationResult as i, CONNECTION_QUALITIES as j, type ConnectionQuality as k, type Constraint as l, type FieldDescriptor as m, type FieldMergeStrategy as n, type KoraEventByType as o, type KoraEventEmitter as p, type KoraEventListener as q, type KoraEventType as r, MERGE_STRATEGIES as s, type MergeStrategy as t, type MergeTrace as u, MigrationBuilder as v, type OnDeleteAction as w, type OperationInput as x, type RelationType as y, RollbackBuilder as z };