@korajs/core 0.4.0 → 0.5.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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RandomSource, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, C as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, b as CollectionDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, d as ArrayFieldBuilder, e as Operation, V as VersionVector, f as MigrationStep, g as StateMachineConstraint, T as TransitionMap, h as TransitionValidationResult } from './events-BMulupSB.cjs';
2
- export { i as CONNECTION_QUALITIES, j as ConnectionQuality, k as Constraint, l as FieldDescriptor, m as FieldKind, n as FieldMergeStrategy, H as HLCTimestamp, o as HybridLogicalClock, K as KoraEvent, p as KoraEventByType, q as KoraEventEmitter, r as KoraEventListener, s as KoraEventType, t as MERGE_STRATEGIES, u as MergeStrategy, v as MergeTrace, w as MigrationBuilder, x as OnDeleteAction, y as OperationInput, z as RelationType, B as RollbackBuilder, D as SequenceConfig, G as StateMachineDefinition, I as SyncDiagnosticsSnapshot, J as TimeSource, L as createOperation, N as isValidOperation, P as migrate, Q as t, U as verifyOperationIntegrity } from './events-BMulupSB.cjs';
1
+ import { R as RandomSource, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, C as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, b as CollectionDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, d as ArrayFieldBuilder, e as FieldKind, f as Operation, V as VersionVector, g as MigrationStep, h as StateMachineConstraint, T as TransitionMap, i as TransitionValidationResult } from './events-BeIEDJBW.cjs';
2
+ export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, o as HybridLogicalClock, K as KoraEvent, p as KoraEventByType, q as KoraEventEmitter, r as KoraEventListener, s as KoraEventType, t as MERGE_STRATEGIES, u as MergeStrategy, v as MergeTrace, w as MigrationBuilder, x as OnDeleteAction, y as OperationInput, z as RelationType, B as RollbackBuilder, D as SequenceConfig, G as StateMachineDefinition, I as SyncDiagnosticsSnapshot, J as SyncRuleDefinition, L as TimeSource, N as createOperation, P as isValidOperation, Q as migrate, U as t, W as verifyOperationIntegrity } from './events-BeIEDJBW.cjs';
3
3
 
4
4
  /**
5
5
  * Base error class for all Kora errors.
@@ -9,6 +9,10 @@ declare class KoraError extends Error {
9
9
  readonly code: string;
10
10
  readonly context?: Record<string, unknown> | undefined;
11
11
  constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
12
+ /**
13
+ * Actionable hint for resolving this error (from registry or error context).
14
+ */
15
+ get fix(): string | undefined;
12
16
  }
13
17
  /**
14
18
  * Thrown when schema validation fails during defineSchema() or at app initialization.
@@ -65,6 +69,41 @@ declare class ClockDriftError extends KoraError {
65
69
  constructor(currentHlcTime: number, physicalTime: number);
66
70
  }
67
71
 
72
+ /**
73
+ * Human-readable remediation hints keyed by {@link KoraError} `code`.
74
+ */
75
+ declare const KORA_ERROR_FIX_SUGGESTIONS: Record<string, string>;
76
+ /**
77
+ * Returns a suggested fix for a Kora error code, if one is known.
78
+ */
79
+ declare function getKoraErrorFix(code: string): string | undefined;
80
+
81
+ /**
82
+ * Tracks the latest operation per collection and within an open transaction
83
+ * to populate {@link Operation.causalDeps} for local mutations.
84
+ */
85
+ declare class CausalTracker {
86
+ private readonly lastOpIdByCollection;
87
+ private lastTransactionOpId;
88
+ /**
89
+ * Start a new transaction boundary. Clears in-transaction op ids.
90
+ */
91
+ beginTransaction(): void;
92
+ /**
93
+ * Clear the transaction boundary without recording ops (after rollback).
94
+ */
95
+ clearTransaction(): void;
96
+ /**
97
+ * Compute causal dependencies for the next operation in a collection.
98
+ * Uses direct parents only: collection head and the previous op in the open transaction.
99
+ */
100
+ nextCausalDeps(collection: string, inTransaction: boolean): string[];
101
+ /**
102
+ * Record an operation after it has been created and assigned an id.
103
+ */
104
+ afterOperation(collection: string, operationId: string, inTransaction: boolean): void;
105
+ }
106
+
68
107
  /**
69
108
  * Generates a UUID v7 per RFC 9562.
70
109
  * UUID v7 encodes a Unix timestamp in milliseconds in the most significant 48 bits,
@@ -97,6 +136,38 @@ declare function extractTimestamp(uuid: string): number;
97
136
  */
98
137
  declare function isValidUUIDv7(uuid: string): boolean;
99
138
 
139
+ /**
140
+ * Outcome of applying a single operation to materialized storage (local or remote).
141
+ */
142
+ declare const APPLY_RESULTS: readonly ["applied", "duplicate", "skipped", "rejected", "deferred"];
143
+ type ApplyResult = (typeof APPLY_RESULTS)[number];
144
+ /**
145
+ * Structured failure metadata when apply returns `skipped`, `rejected`, or `deferred`.
146
+ */
147
+ interface ApplyFailureReason {
148
+ code: string;
149
+ message: string;
150
+ retriable: boolean;
151
+ }
152
+ /** Well-known apply failure codes for DevTools and `sync:apply-failed` events. */
153
+ declare const APPLY_FAILURE_CODES: {
154
+ readonly APPLY_FAILED: "APPLY_FAILED";
155
+ readonly APPLY_SKIPPED: "APPLY_SKIPPED";
156
+ readonly APPLY_REJECTED: "APPLY_REJECTED";
157
+ readonly APPLY_DEFERRED: "APPLY_DEFERRED";
158
+ readonly CLOCK_DRIFT: "CLOCK_DRIFT";
159
+ readonly REFERENTIAL_INTEGRITY: "REFERENTIAL_INTEGRITY";
160
+ readonly SCHEMA_MISMATCH: "SCHEMA_MISMATCH";
161
+ };
162
+ /**
163
+ * Returns true when the apply outcome should surface as a failure to the developer.
164
+ */
165
+ declare function isApplyFailure(result: ApplyResult): boolean;
166
+ /**
167
+ * Default failure metadata when the store does not attach a specific reason.
168
+ */
169
+ declare function defaultApplyFailureReason(result: Exclude<ApplyResult, 'applied' | 'duplicate'>, overrides?: Partial<ApplyFailureReason>): ApplyFailureReason;
170
+
100
171
  /**
101
172
  * Atomic field operations for intent-preserving updates.
102
173
  *
@@ -219,6 +290,29 @@ interface SchemaInput {
219
290
  relations?: Record<string, RelationInput>;
220
291
  /** Schema migrations keyed by target version number. */
221
292
  migrations?: Record<number, MigrationDefinition>;
293
+ /**
294
+ * Declarative partial-sync rules.
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * sync: {
299
+ * todos: { where: { userId: true, orgId: true } },
300
+ * projects: { where: { orgId: true } },
301
+ * }
302
+ * ```
303
+ */
304
+ sync?: Record<string, SyncRuleInput>;
305
+ }
306
+ /**
307
+ * Developer input for a collection sync rule.
308
+ */
309
+ interface SyncRuleInput {
310
+ /**
311
+ * Field filters bound to scope values.
312
+ * Use `true` to bind a field to a scope value with the same name.
313
+ * Use a string to bind to a different scope value key.
314
+ */
315
+ where: Record<string, boolean | string>;
222
316
  }
223
317
  interface StateMachineInput {
224
318
  /** The enum field this state machine controls */
@@ -335,15 +429,23 @@ interface FieldKindToType {
335
429
  number: number;
336
430
  boolean: boolean;
337
431
  timestamp: number;
338
- richtext: Uint8Array;
432
+ richtext: string;
339
433
  enum: string;
340
434
  array: unknown[];
341
435
  }
342
436
  /**
343
- * Infers the TypeScript type for a single FieldBuilder.
344
- * Handles base fields, enums (with literal union), and arrays (with typed items).
437
+ * Infers the TypeScript type for a single field descriptor or builder.
438
+ * Supports both FieldBuilder (class instances) and FieldDescriptor (compiled objects).
345
439
  */
346
- type InferFieldType<F> = F extends EnumFieldBuilder<infer V, infer _Req, infer _Auto> ? V[number] : F extends ArrayFieldBuilder<infer K, infer _Req, infer _Auto> ? FieldKindToType[K][] : F extends FieldBuilder<infer K, infer _Req, infer _Auto> ? FieldKindToType[K] : unknown;
440
+ type InferFieldType<F> = F extends EnumFieldBuilder<infer V, any, any> ? V[number] : F extends ArrayFieldBuilder<infer K, any, any> ? FieldKindToType[K][] : F extends FieldBuilder<infer K, any, any> ? K extends keyof FieldKindToType ? FieldKindToType[K] : unknown : F extends {
441
+ kind: 'enum';
442
+ enumValues: infer V;
443
+ } ? V extends readonly (infer S)[] ? S : string : F extends {
444
+ kind: 'array';
445
+ itemKind: infer K extends FieldKind;
446
+ } ? FieldKindToType[K][] : F extends {
447
+ kind: infer K extends FieldKind;
448
+ } ? FieldKindToType[K] : unknown;
347
449
  /**
348
450
  * Infers the full record type returned from queries.
349
451
  * Includes `id`, `createdAt`, `updatedAt` metadata fields.
@@ -357,40 +459,22 @@ type InferRecord<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
357
459
  readonly [K in keyof Fields]: Fields[K] extends FieldBuilder<any, true, any> ? InferFieldType<Fields[K]> : InferFieldType<Fields[K]> | null;
358
460
  };
359
461
  /**
360
- * Helper: extract keys where the field is required and not auto.
361
- */
362
- type RequiredInsertKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
363
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? K : never;
364
- }[keyof Fields];
365
- /**
366
- * Helper: extract keys where the field is optional (not required) and not auto.
367
- */
368
- type OptionalInsertKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
369
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? never : K;
370
- }[keyof Fields];
371
- /**
372
- * Infers the insert input type.
462
+ * Infers the insert input type using inline key remapping.
373
463
  * - Required non-auto fields are required keys
374
464
  * - Optional/defaulted non-auto fields are optional keys
375
465
  * - Auto fields are excluded entirely
376
466
  */
377
467
  type InferInsertInput<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
378
- [K in RequiredInsertKeys<Fields> & string]: InferFieldType<Fields[K]>;
468
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? K : never]: InferFieldType<Fields[K]>;
379
469
  } & {
380
- [K in OptionalInsertKeys<Fields> & string]?: InferFieldType<Fields[K]>;
470
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? never : K]?: InferFieldType<Fields[K]>;
381
471
  };
382
472
  /**
383
- * Helper: extract keys where the field is not auto.
384
- */
385
- type NonAutoKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
386
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : K;
387
- }[keyof Fields];
388
- /**
389
- * Infers the update input type.
473
+ * Infers the update input type using inline key remapping.
390
474
  * All non-auto fields are optional (partial update semantics).
391
475
  */
392
476
  type InferUpdateInput<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
393
- [K in NonAutoKeys<Fields> & string]?: InferFieldType<Fields[K]>;
477
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : K]?: InferFieldType<Fields[K]>;
394
478
  };
395
479
 
396
480
  /**
@@ -418,9 +502,10 @@ declare function dominates(a: VersionVector, b: VersionVector): boolean;
418
502
  declare function vectorsEqual(a: VersionVector, b: VersionVector): boolean;
419
503
  /**
420
504
  * Operation log interface for computing deltas.
505
+ * getRange may be async (for DB-backed implementations) or sync (for in-memory).
421
506
  */
422
507
  interface OperationLog {
423
- getRange(nodeId: string, fromSeq: number, toSeq: number): Operation[];
508
+ getRange(nodeId: string, fromSeq: number, toSeq: number): Operation[] | Promise<Operation[]>;
424
509
  }
425
510
  /**
426
511
  * Compute the operations that `local` has but `remote` does not.
@@ -431,7 +516,7 @@ interface OperationLog {
431
516
  * @param operationLog - The operation log to fetch operations from
432
517
  * @returns Operations sorted in causal order
433
518
  */
434
- declare function computeDelta(localVector: VersionVector, remoteVector: VersionVector, operationLog: OperationLog): Operation[];
519
+ declare function computeDelta(localVector: VersionVector, remoteVector: VersionVector, operationLog: OperationLog): Promise<Operation[]>;
435
520
  /**
436
521
  * Serialize a version vector to a JSON-compatible string.
437
522
  */
@@ -441,6 +526,26 @@ declare function serializeVector(vector: VersionVector): string;
441
526
  */
442
527
  declare function deserializeVector(s: string): VersionVector;
443
528
 
529
+ /**
530
+ * Returns true when the schema declares partial sync rules at the root level.
531
+ */
532
+ declare function hasSchemaSyncRules(schema: SchemaDefinition): boolean;
533
+ /**
534
+ * Resolve field → scope-value-key bindings for a collection.
535
+ *
536
+ * Sync rules take precedence over legacy `collection.scope` arrays.
537
+ * Returns `null` when the collection has no sync filtering configured.
538
+ */
539
+ declare function getCollectionScopeBindings(schema: SchemaDefinition, collectionName: string): Record<string, string> | null;
540
+ /**
541
+ * Returns whether a collection participates in sync filtering for this schema.
542
+ */
543
+ declare function isCollectionSyncScoped(schema: SchemaDefinition, collectionName: string): boolean;
544
+ /**
545
+ * Collect unique scope value keys referenced by sync rules and legacy scope fields.
546
+ */
547
+ declare function collectSchemaScopeValueKeys(schema: SchemaDefinition): string[];
548
+
444
549
  /**
445
550
  * Per-collection scope map: `{ collectionName: { field: value, ... } }`
446
551
  *
@@ -451,9 +556,12 @@ type ScopeMap = Record<string, Record<string, unknown>>;
451
556
  * Build a per-collection scope map from the schema's scope declarations
452
557
  * and the client's flat scope values.
453
558
  *
454
- * For each collection:
455
- * - If it declares scope fields, build a filter from the matching flat values.
456
- * - If it declares no scope fields, include it with an empty filter (no restriction).
559
+ * Supports both legacy `collection.scope` arrays and declarative `schema.sync`
560
+ * rules (`sync: { todos: { where: { userId: true } } }`).
561
+ *
562
+ * When `schema.sync` is present, only collections with sync rules or legacy
563
+ * scope fields are included in the result. Other collections are omitted so
564
+ * sync engines treat them as out of scope (partial sync).
457
565
  *
458
566
  * @param schema - The schema definition with scope declarations
459
567
  * @param scopeValues - Flat key-value scope values from the client
@@ -468,6 +576,26 @@ type ScopeMap = Record<string, Record<string, unknown>>;
468
576
  */
469
577
  declare function buildScopeMap(schema: SchemaDefinition, scopeValues: Record<string, unknown>): ScopeMap;
470
578
 
579
+ /**
580
+ * Collect every unique scope field name declared across all collections.
581
+ *
582
+ * @deprecated Use {@link collectSchemaScopeValueKeys} instead.
583
+ */
584
+ declare function collectSchemaScopeFields(schema: SchemaDefinition): string[];
585
+ /**
586
+ * Extract flat scope values from JWT (or auth) claims using schema scope field names.
587
+ *
588
+ * Resolution order for each scope field:
589
+ * 1. Top-level claim with the same name
590
+ * 2. Nested `claims.scope[field]` object
591
+ * 3. `userId` falls back to the standard JWT `sub` claim
592
+ *
593
+ * @param schema - Schema with per-collection scope declarations
594
+ * @param claims - Decoded JWT claims (unverified; client-side scope hints only)
595
+ * @returns Flat key-value map suitable for {@link buildScopeMap}
596
+ */
597
+ declare function extractScopeValuesFromClaims(schema: SchemaDefinition, claims: Record<string, unknown>): Record<string, unknown>;
598
+
471
599
  /**
472
600
  * Offline-safe sequence formatting.
473
601
  *
@@ -493,6 +621,28 @@ declare function formatSequenceValue(template: string, counter: number, nodeId:
493
621
  */
494
622
  declare function defaultSequenceFormat(name: string): string;
495
623
 
624
+ /**
625
+ * Transforms operations created under an older schema version so they are valid
626
+ * after a schema upgrade. Used during sync when client and server schema versions differ
627
+ * but remain within the server's supported range.
628
+ */
629
+ interface OperationTransform {
630
+ /** Schema version the operation was authored against */
631
+ readonly fromVersion: number;
632
+ /** Target schema version after transformation */
633
+ readonly toVersion: number;
634
+ /**
635
+ * Transform a single operation. Return `null` to drop operations that cannot be migrated.
636
+ */
637
+ transform(operation: Operation): Operation | null;
638
+ }
639
+
640
+ /**
641
+ * Apply registered transforms until the operation matches `targetSchemaVersion`.
642
+ * Returns null when a transform drops the operation or no path exists.
643
+ */
644
+ declare function applyOperationTransforms(operation: Operation, targetSchemaVersion: number, transforms: readonly OperationTransform[]): Operation | null;
645
+
496
646
  /**
497
647
  * Convert migration steps to SQL statements.
498
648
  *
@@ -714,4 +864,4 @@ interface ProtoOutput {
714
864
  */
715
865
  declare function generateProtoDefinitions(schema: SchemaDefinition): ProtoOutput;
716
866
 
717
- export { ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, Operation, OperationError, type OperationLog, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type ScopeMap, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, buildScopeMap, buildStateMachineConstraints, canAutoRollback, computeDelta, createReversibleMigration, createVersionVector, defaultSequenceFormat, defineSchema, deserializeVector, dominates, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getTransitionMap, isAtomicOp, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, resolveAtomicOp, rollbackStepsToSQL, serializeVector, toAtomicOp, validateRecord, validateTransition, vectorsEqual };
867
+ export { APPLY_FAILURE_CODES, APPLY_RESULTS, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, KORA_ERROR_FIX_SUGGESTIONS, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type ScopeMap, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyOperationTransforms, buildScopeMap, buildStateMachineConstraints, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createReversibleMigration, createVersionVector, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, isApplyFailure, isAtomicOp, isCollectionSyncScoped, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, resolveAtomicOp, rollbackStepsToSQL, serializeVector, toAtomicOp, validateRecord, validateTransition, vectorsEqual };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RandomSource, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, C as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, b as CollectionDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, d as ArrayFieldBuilder, e as Operation, V as VersionVector, f as MigrationStep, g as StateMachineConstraint, T as TransitionMap, h as TransitionValidationResult } from './events-BMulupSB.js';
2
- export { i as CONNECTION_QUALITIES, j as ConnectionQuality, k as Constraint, l as FieldDescriptor, m as FieldKind, n as FieldMergeStrategy, H as HLCTimestamp, o as HybridLogicalClock, K as KoraEvent, p as KoraEventByType, q as KoraEventEmitter, r as KoraEventListener, s as KoraEventType, t as MERGE_STRATEGIES, u as MergeStrategy, v as MergeTrace, w as MigrationBuilder, x as OnDeleteAction, y as OperationInput, z as RelationType, B as RollbackBuilder, D as SequenceConfig, G as StateMachineDefinition, I as SyncDiagnosticsSnapshot, J as TimeSource, L as createOperation, N as isValidOperation, P as migrate, Q as t, U as verifyOperationIntegrity } from './events-BMulupSB.js';
1
+ import { R as RandomSource, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, C as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, b as CollectionDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, d as ArrayFieldBuilder, e as FieldKind, f as Operation, V as VersionVector, g as MigrationStep, h as StateMachineConstraint, T as TransitionMap, i as TransitionValidationResult } from './events-BeIEDJBW.js';
2
+ export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, o as HybridLogicalClock, K as KoraEvent, p as KoraEventByType, q as KoraEventEmitter, r as KoraEventListener, s as KoraEventType, t as MERGE_STRATEGIES, u as MergeStrategy, v as MergeTrace, w as MigrationBuilder, x as OnDeleteAction, y as OperationInput, z as RelationType, B as RollbackBuilder, D as SequenceConfig, G as StateMachineDefinition, I as SyncDiagnosticsSnapshot, J as SyncRuleDefinition, L as TimeSource, N as createOperation, P as isValidOperation, Q as migrate, U as t, W as verifyOperationIntegrity } from './events-BeIEDJBW.js';
3
3
 
4
4
  /**
5
5
  * Base error class for all Kora errors.
@@ -9,6 +9,10 @@ declare class KoraError extends Error {
9
9
  readonly code: string;
10
10
  readonly context?: Record<string, unknown> | undefined;
11
11
  constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
12
+ /**
13
+ * Actionable hint for resolving this error (from registry or error context).
14
+ */
15
+ get fix(): string | undefined;
12
16
  }
13
17
  /**
14
18
  * Thrown when schema validation fails during defineSchema() or at app initialization.
@@ -65,6 +69,41 @@ declare class ClockDriftError extends KoraError {
65
69
  constructor(currentHlcTime: number, physicalTime: number);
66
70
  }
67
71
 
72
+ /**
73
+ * Human-readable remediation hints keyed by {@link KoraError} `code`.
74
+ */
75
+ declare const KORA_ERROR_FIX_SUGGESTIONS: Record<string, string>;
76
+ /**
77
+ * Returns a suggested fix for a Kora error code, if one is known.
78
+ */
79
+ declare function getKoraErrorFix(code: string): string | undefined;
80
+
81
+ /**
82
+ * Tracks the latest operation per collection and within an open transaction
83
+ * to populate {@link Operation.causalDeps} for local mutations.
84
+ */
85
+ declare class CausalTracker {
86
+ private readonly lastOpIdByCollection;
87
+ private lastTransactionOpId;
88
+ /**
89
+ * Start a new transaction boundary. Clears in-transaction op ids.
90
+ */
91
+ beginTransaction(): void;
92
+ /**
93
+ * Clear the transaction boundary without recording ops (after rollback).
94
+ */
95
+ clearTransaction(): void;
96
+ /**
97
+ * Compute causal dependencies for the next operation in a collection.
98
+ * Uses direct parents only: collection head and the previous op in the open transaction.
99
+ */
100
+ nextCausalDeps(collection: string, inTransaction: boolean): string[];
101
+ /**
102
+ * Record an operation after it has been created and assigned an id.
103
+ */
104
+ afterOperation(collection: string, operationId: string, inTransaction: boolean): void;
105
+ }
106
+
68
107
  /**
69
108
  * Generates a UUID v7 per RFC 9562.
70
109
  * UUID v7 encodes a Unix timestamp in milliseconds in the most significant 48 bits,
@@ -97,6 +136,38 @@ declare function extractTimestamp(uuid: string): number;
97
136
  */
98
137
  declare function isValidUUIDv7(uuid: string): boolean;
99
138
 
139
+ /**
140
+ * Outcome of applying a single operation to materialized storage (local or remote).
141
+ */
142
+ declare const APPLY_RESULTS: readonly ["applied", "duplicate", "skipped", "rejected", "deferred"];
143
+ type ApplyResult = (typeof APPLY_RESULTS)[number];
144
+ /**
145
+ * Structured failure metadata when apply returns `skipped`, `rejected`, or `deferred`.
146
+ */
147
+ interface ApplyFailureReason {
148
+ code: string;
149
+ message: string;
150
+ retriable: boolean;
151
+ }
152
+ /** Well-known apply failure codes for DevTools and `sync:apply-failed` events. */
153
+ declare const APPLY_FAILURE_CODES: {
154
+ readonly APPLY_FAILED: "APPLY_FAILED";
155
+ readonly APPLY_SKIPPED: "APPLY_SKIPPED";
156
+ readonly APPLY_REJECTED: "APPLY_REJECTED";
157
+ readonly APPLY_DEFERRED: "APPLY_DEFERRED";
158
+ readonly CLOCK_DRIFT: "CLOCK_DRIFT";
159
+ readonly REFERENTIAL_INTEGRITY: "REFERENTIAL_INTEGRITY";
160
+ readonly SCHEMA_MISMATCH: "SCHEMA_MISMATCH";
161
+ };
162
+ /**
163
+ * Returns true when the apply outcome should surface as a failure to the developer.
164
+ */
165
+ declare function isApplyFailure(result: ApplyResult): boolean;
166
+ /**
167
+ * Default failure metadata when the store does not attach a specific reason.
168
+ */
169
+ declare function defaultApplyFailureReason(result: Exclude<ApplyResult, 'applied' | 'duplicate'>, overrides?: Partial<ApplyFailureReason>): ApplyFailureReason;
170
+
100
171
  /**
101
172
  * Atomic field operations for intent-preserving updates.
102
173
  *
@@ -219,6 +290,29 @@ interface SchemaInput {
219
290
  relations?: Record<string, RelationInput>;
220
291
  /** Schema migrations keyed by target version number. */
221
292
  migrations?: Record<number, MigrationDefinition>;
293
+ /**
294
+ * Declarative partial-sync rules.
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * sync: {
299
+ * todos: { where: { userId: true, orgId: true } },
300
+ * projects: { where: { orgId: true } },
301
+ * }
302
+ * ```
303
+ */
304
+ sync?: Record<string, SyncRuleInput>;
305
+ }
306
+ /**
307
+ * Developer input for a collection sync rule.
308
+ */
309
+ interface SyncRuleInput {
310
+ /**
311
+ * Field filters bound to scope values.
312
+ * Use `true` to bind a field to a scope value with the same name.
313
+ * Use a string to bind to a different scope value key.
314
+ */
315
+ where: Record<string, boolean | string>;
222
316
  }
223
317
  interface StateMachineInput {
224
318
  /** The enum field this state machine controls */
@@ -335,15 +429,23 @@ interface FieldKindToType {
335
429
  number: number;
336
430
  boolean: boolean;
337
431
  timestamp: number;
338
- richtext: Uint8Array;
432
+ richtext: string;
339
433
  enum: string;
340
434
  array: unknown[];
341
435
  }
342
436
  /**
343
- * Infers the TypeScript type for a single FieldBuilder.
344
- * Handles base fields, enums (with literal union), and arrays (with typed items).
437
+ * Infers the TypeScript type for a single field descriptor or builder.
438
+ * Supports both FieldBuilder (class instances) and FieldDescriptor (compiled objects).
345
439
  */
346
- type InferFieldType<F> = F extends EnumFieldBuilder<infer V, infer _Req, infer _Auto> ? V[number] : F extends ArrayFieldBuilder<infer K, infer _Req, infer _Auto> ? FieldKindToType[K][] : F extends FieldBuilder<infer K, infer _Req, infer _Auto> ? FieldKindToType[K] : unknown;
440
+ type InferFieldType<F> = F extends EnumFieldBuilder<infer V, any, any> ? V[number] : F extends ArrayFieldBuilder<infer K, any, any> ? FieldKindToType[K][] : F extends FieldBuilder<infer K, any, any> ? K extends keyof FieldKindToType ? FieldKindToType[K] : unknown : F extends {
441
+ kind: 'enum';
442
+ enumValues: infer V;
443
+ } ? V extends readonly (infer S)[] ? S : string : F extends {
444
+ kind: 'array';
445
+ itemKind: infer K extends FieldKind;
446
+ } ? FieldKindToType[K][] : F extends {
447
+ kind: infer K extends FieldKind;
448
+ } ? FieldKindToType[K] : unknown;
347
449
  /**
348
450
  * Infers the full record type returned from queries.
349
451
  * Includes `id`, `createdAt`, `updatedAt` metadata fields.
@@ -357,40 +459,22 @@ type InferRecord<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
357
459
  readonly [K in keyof Fields]: Fields[K] extends FieldBuilder<any, true, any> ? InferFieldType<Fields[K]> : InferFieldType<Fields[K]> | null;
358
460
  };
359
461
  /**
360
- * Helper: extract keys where the field is required and not auto.
361
- */
362
- type RequiredInsertKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
363
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? K : never;
364
- }[keyof Fields];
365
- /**
366
- * Helper: extract keys where the field is optional (not required) and not auto.
367
- */
368
- type OptionalInsertKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
369
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? never : K;
370
- }[keyof Fields];
371
- /**
372
- * Infers the insert input type.
462
+ * Infers the insert input type using inline key remapping.
373
463
  * - Required non-auto fields are required keys
374
464
  * - Optional/defaulted non-auto fields are optional keys
375
465
  * - Auto fields are excluded entirely
376
466
  */
377
467
  type InferInsertInput<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
378
- [K in RequiredInsertKeys<Fields> & string]: InferFieldType<Fields[K]>;
468
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? K : never]: InferFieldType<Fields[K]>;
379
469
  } & {
380
- [K in OptionalInsertKeys<Fields> & string]?: InferFieldType<Fields[K]>;
470
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : Fields[K] extends FieldBuilder<any, true, false> ? never : K]?: InferFieldType<Fields[K]>;
381
471
  };
382
472
  /**
383
- * Helper: extract keys where the field is not auto.
384
- */
385
- type NonAutoKeys<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
386
- [K in keyof Fields]: Fields[K] extends FieldBuilder<any, any, true> ? never : K;
387
- }[keyof Fields];
388
- /**
389
- * Infers the update input type.
473
+ * Infers the update input type using inline key remapping.
390
474
  * All non-auto fields are optional (partial update semantics).
391
475
  */
392
476
  type InferUpdateInput<Fields extends Record<string, FieldBuilder<any, any, any>>> = {
393
- [K in NonAutoKeys<Fields> & string]?: InferFieldType<Fields[K]>;
477
+ [K in keyof Fields as Fields[K] extends FieldBuilder<any, any, true> ? never : K]?: InferFieldType<Fields[K]>;
394
478
  };
395
479
 
396
480
  /**
@@ -418,9 +502,10 @@ declare function dominates(a: VersionVector, b: VersionVector): boolean;
418
502
  declare function vectorsEqual(a: VersionVector, b: VersionVector): boolean;
419
503
  /**
420
504
  * Operation log interface for computing deltas.
505
+ * getRange may be async (for DB-backed implementations) or sync (for in-memory).
421
506
  */
422
507
  interface OperationLog {
423
- getRange(nodeId: string, fromSeq: number, toSeq: number): Operation[];
508
+ getRange(nodeId: string, fromSeq: number, toSeq: number): Operation[] | Promise<Operation[]>;
424
509
  }
425
510
  /**
426
511
  * Compute the operations that `local` has but `remote` does not.
@@ -431,7 +516,7 @@ interface OperationLog {
431
516
  * @param operationLog - The operation log to fetch operations from
432
517
  * @returns Operations sorted in causal order
433
518
  */
434
- declare function computeDelta(localVector: VersionVector, remoteVector: VersionVector, operationLog: OperationLog): Operation[];
519
+ declare function computeDelta(localVector: VersionVector, remoteVector: VersionVector, operationLog: OperationLog): Promise<Operation[]>;
435
520
  /**
436
521
  * Serialize a version vector to a JSON-compatible string.
437
522
  */
@@ -441,6 +526,26 @@ declare function serializeVector(vector: VersionVector): string;
441
526
  */
442
527
  declare function deserializeVector(s: string): VersionVector;
443
528
 
529
+ /**
530
+ * Returns true when the schema declares partial sync rules at the root level.
531
+ */
532
+ declare function hasSchemaSyncRules(schema: SchemaDefinition): boolean;
533
+ /**
534
+ * Resolve field → scope-value-key bindings for a collection.
535
+ *
536
+ * Sync rules take precedence over legacy `collection.scope` arrays.
537
+ * Returns `null` when the collection has no sync filtering configured.
538
+ */
539
+ declare function getCollectionScopeBindings(schema: SchemaDefinition, collectionName: string): Record<string, string> | null;
540
+ /**
541
+ * Returns whether a collection participates in sync filtering for this schema.
542
+ */
543
+ declare function isCollectionSyncScoped(schema: SchemaDefinition, collectionName: string): boolean;
544
+ /**
545
+ * Collect unique scope value keys referenced by sync rules and legacy scope fields.
546
+ */
547
+ declare function collectSchemaScopeValueKeys(schema: SchemaDefinition): string[];
548
+
444
549
  /**
445
550
  * Per-collection scope map: `{ collectionName: { field: value, ... } }`
446
551
  *
@@ -451,9 +556,12 @@ type ScopeMap = Record<string, Record<string, unknown>>;
451
556
  * Build a per-collection scope map from the schema's scope declarations
452
557
  * and the client's flat scope values.
453
558
  *
454
- * For each collection:
455
- * - If it declares scope fields, build a filter from the matching flat values.
456
- * - If it declares no scope fields, include it with an empty filter (no restriction).
559
+ * Supports both legacy `collection.scope` arrays and declarative `schema.sync`
560
+ * rules (`sync: { todos: { where: { userId: true } } }`).
561
+ *
562
+ * When `schema.sync` is present, only collections with sync rules or legacy
563
+ * scope fields are included in the result. Other collections are omitted so
564
+ * sync engines treat them as out of scope (partial sync).
457
565
  *
458
566
  * @param schema - The schema definition with scope declarations
459
567
  * @param scopeValues - Flat key-value scope values from the client
@@ -468,6 +576,26 @@ type ScopeMap = Record<string, Record<string, unknown>>;
468
576
  */
469
577
  declare function buildScopeMap(schema: SchemaDefinition, scopeValues: Record<string, unknown>): ScopeMap;
470
578
 
579
+ /**
580
+ * Collect every unique scope field name declared across all collections.
581
+ *
582
+ * @deprecated Use {@link collectSchemaScopeValueKeys} instead.
583
+ */
584
+ declare function collectSchemaScopeFields(schema: SchemaDefinition): string[];
585
+ /**
586
+ * Extract flat scope values from JWT (or auth) claims using schema scope field names.
587
+ *
588
+ * Resolution order for each scope field:
589
+ * 1. Top-level claim with the same name
590
+ * 2. Nested `claims.scope[field]` object
591
+ * 3. `userId` falls back to the standard JWT `sub` claim
592
+ *
593
+ * @param schema - Schema with per-collection scope declarations
594
+ * @param claims - Decoded JWT claims (unverified; client-side scope hints only)
595
+ * @returns Flat key-value map suitable for {@link buildScopeMap}
596
+ */
597
+ declare function extractScopeValuesFromClaims(schema: SchemaDefinition, claims: Record<string, unknown>): Record<string, unknown>;
598
+
471
599
  /**
472
600
  * Offline-safe sequence formatting.
473
601
  *
@@ -493,6 +621,28 @@ declare function formatSequenceValue(template: string, counter: number, nodeId:
493
621
  */
494
622
  declare function defaultSequenceFormat(name: string): string;
495
623
 
624
+ /**
625
+ * Transforms operations created under an older schema version so they are valid
626
+ * after a schema upgrade. Used during sync when client and server schema versions differ
627
+ * but remain within the server's supported range.
628
+ */
629
+ interface OperationTransform {
630
+ /** Schema version the operation was authored against */
631
+ readonly fromVersion: number;
632
+ /** Target schema version after transformation */
633
+ readonly toVersion: number;
634
+ /**
635
+ * Transform a single operation. Return `null` to drop operations that cannot be migrated.
636
+ */
637
+ transform(operation: Operation): Operation | null;
638
+ }
639
+
640
+ /**
641
+ * Apply registered transforms until the operation matches `targetSchemaVersion`.
642
+ * Returns null when a transform drops the operation or no path exists.
643
+ */
644
+ declare function applyOperationTransforms(operation: Operation, targetSchemaVersion: number, transforms: readonly OperationTransform[]): Operation | null;
645
+
496
646
  /**
497
647
  * Convert migration steps to SQL statements.
498
648
  *
@@ -714,4 +864,4 @@ interface ProtoOutput {
714
864
  */
715
865
  declare function generateProtoDefinitions(schema: SchemaDefinition): ProtoOutput;
716
866
 
717
- export { ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, Operation, OperationError, type OperationLog, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type ScopeMap, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, buildScopeMap, buildStateMachineConstraints, canAutoRollback, computeDelta, createReversibleMigration, createVersionVector, defaultSequenceFormat, defineSchema, deserializeVector, dominates, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getTransitionMap, isAtomicOp, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, resolveAtomicOp, rollbackStepsToSQL, serializeVector, toAtomicOp, validateRecord, validateTransition, vectorsEqual };
867
+ export { APPLY_FAILURE_CODES, APPLY_RESULTS, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, KORA_ERROR_FIX_SUGGESTIONS, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type ScopeMap, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyOperationTransforms, buildScopeMap, buildStateMachineConstraints, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createReversibleMigration, createVersionVector, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, isApplyFailure, isAtomicOp, isCollectionSyncScoped, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, resolveAtomicOp, rollbackStepsToSQL, serializeVector, toAtomicOp, validateRecord, validateTransition, vectorsEqual };