@korajs/core 0.3.1 → 0.4.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/{chunk-KQYXWUFV.js → chunk-CFP5YFXC.js} +26 -16
- package/dist/chunk-CFP5YFXC.js.map +1 -0
- package/dist/events-BMulupSB.d.cts +844 -0
- package/dist/events-BMulupSB.d.ts +844 -0
- package/dist/index.cjs +1050 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +385 -69
- package/dist/index.d.ts +385 -69
- package/dist/index.js +977 -22
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +19 -13
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KQYXWUFV.js.map +0 -1
- package/dist/events-7Fhdjxd2.d.cts +0 -327
- package/dist/events-7Fhdjxd2.d.ts +0 -327
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RandomSource,
|
|
2
|
-
export {
|
|
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';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Base error class for all Kora errors.
|
|
@@ -98,88 +98,117 @@ declare function extractTimestamp(uuid: string): number;
|
|
|
98
98
|
declare function isValidUUIDv7(uuid: string): boolean;
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
102
|
-
* Each builder is immutable — modifier methods return new builder instances.
|
|
101
|
+
* Atomic field operations for intent-preserving updates.
|
|
103
102
|
*
|
|
104
|
-
*
|
|
105
|
-
* - Kind: the field kind ('string', 'number', etc.)
|
|
106
|
-
* - Req: whether the field is required (true = required on insert)
|
|
107
|
-
* - Auto: whether the field is auto-populated (true = excluded from insert input)
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
103
|
+
* Instead of read-modify-write patterns, developers express intent:
|
|
110
104
|
* ```typescript
|
|
111
|
-
*
|
|
112
|
-
* t.string().optional() // optional string field
|
|
113
|
-
* t.string().default('hello') // string with default value
|
|
114
|
-
* t.timestamp().auto() // auto-populated timestamp
|
|
105
|
+
* await app.stock.update(id, { quantity: op.increment(-5) })
|
|
115
106
|
* ```
|
|
107
|
+
*
|
|
108
|
+
* The operation intent is preserved in the Operation for merge:
|
|
109
|
+
* concurrent increments compose (sum of deltas) instead of LWW.
|
|
116
110
|
*/
|
|
117
|
-
|
|
118
|
-
protected readonly _kind: Kind;
|
|
119
|
-
protected readonly _required: boolean;
|
|
120
|
-
protected readonly _defaultValue: unknown;
|
|
121
|
-
protected readonly _auto: boolean;
|
|
122
|
-
constructor(kind: Kind, required?: Req, defaultValue?: unknown, auto?: Auto);
|
|
123
|
-
/** Mark this field as optional (not required on insert) */
|
|
124
|
-
optional(): FieldBuilder<Kind, false, Auto>;
|
|
125
|
-
/** Set a default value for this field. Implicitly makes the field optional. */
|
|
126
|
-
default(value: unknown): FieldBuilder<Kind, false, Auto>;
|
|
127
|
-
/** Mark this field as auto-populated (e.g., createdAt timestamps). Developers cannot set auto fields. */
|
|
128
|
-
auto(): FieldBuilder<Kind, false, true>;
|
|
129
|
-
/** @internal Build the final FieldDescriptor. Used by defineSchema(). */
|
|
130
|
-
_build(): FieldDescriptor;
|
|
131
|
-
}
|
|
111
|
+
|
|
132
112
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
113
|
+
* Sentinel marker for detecting atomic op objects in update data.
|
|
114
|
+
* Uses Symbol.for() so the sentinel survives module boundary crossings.
|
|
135
115
|
*/
|
|
136
|
-
declare
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
optional(): EnumFieldBuilder<Values, false, Auto>;
|
|
140
|
-
default(value: Values[number]): EnumFieldBuilder<Values, false, Auto>;
|
|
141
|
-
auto(): EnumFieldBuilder<Values, false, true>;
|
|
142
|
-
_build(): FieldDescriptor;
|
|
143
|
-
}
|
|
116
|
+
declare const KORA_ATOMIC_OP: unique symbol;
|
|
117
|
+
/** String key used for the sentinel symbol — exported for internal use */
|
|
118
|
+
declare const KORA_ATOMIC_OP_KEY: typeof KORA_ATOMIC_OP;
|
|
144
119
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
120
|
+
* Sentinel object returned by op.* helpers.
|
|
121
|
+
* Detected by Collection.update() and resolved to concrete values.
|
|
147
122
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
default(value: unknown[]): ArrayFieldBuilder<ItemKind, false, Auto>;
|
|
153
|
-
auto(): ArrayFieldBuilder<ItemKind, false, true>;
|
|
154
|
-
_build(): FieldDescriptor;
|
|
123
|
+
interface AtomicOpSentinel {
|
|
124
|
+
readonly [KORA_ATOMIC_OP_KEY]: true;
|
|
125
|
+
readonly type: AtomicOpType;
|
|
126
|
+
readonly value: unknown;
|
|
155
127
|
}
|
|
156
128
|
/**
|
|
157
|
-
* Type
|
|
129
|
+
* Type guard: checks whether a value is an atomic op sentinel.
|
|
130
|
+
*
|
|
131
|
+
* @param value - Any value to check
|
|
132
|
+
* @returns true if the value is an AtomicOpSentinel
|
|
133
|
+
*/
|
|
134
|
+
declare function isAtomicOp(value: unknown): value is AtomicOpSentinel;
|
|
135
|
+
/**
|
|
136
|
+
* Resolve an atomic op sentinel against a current value to produce a concrete result.
|
|
137
|
+
*
|
|
138
|
+
* @param currentValue - The current value of the field in the database
|
|
139
|
+
* @param sentinel - The atomic op sentinel from the developer's update call
|
|
140
|
+
* @returns The resolved concrete value
|
|
141
|
+
*/
|
|
142
|
+
declare function resolveAtomicOp(currentValue: unknown, sentinel: AtomicOpSentinel): unknown;
|
|
143
|
+
/**
|
|
144
|
+
* Atomic operation helpers. Use these in collection.update() calls
|
|
145
|
+
* to express intent-preserving mutations.
|
|
158
146
|
*
|
|
159
147
|
* @example
|
|
160
148
|
* ```typescript
|
|
161
|
-
* import {
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* }
|
|
149
|
+
* import { op } from 'korajs'
|
|
150
|
+
*
|
|
151
|
+
* // Increment a counter (works correctly with concurrent updates)
|
|
152
|
+
* await app.stock.update(id, { quantity: op.increment(-5) })
|
|
153
|
+
*
|
|
154
|
+
* // Keep the maximum value
|
|
155
|
+
* await app.scores.update(id, { highScore: op.max(newScore) })
|
|
156
|
+
*
|
|
157
|
+
* // Append to an array
|
|
158
|
+
* await app.todos.update(id, { tags: op.append('urgent') })
|
|
172
159
|
* ```
|
|
173
160
|
*/
|
|
174
|
-
declare const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
161
|
+
declare const op: {
|
|
162
|
+
/**
|
|
163
|
+
* Increment a number field by the given amount.
|
|
164
|
+
* Concurrent increments compose: the sum of all deltas is applied to the base.
|
|
165
|
+
*
|
|
166
|
+
* @param n - The amount to increment (use negative values to decrement)
|
|
167
|
+
*/
|
|
168
|
+
increment(n: number): AtomicOpSentinel;
|
|
169
|
+
/**
|
|
170
|
+
* Decrement a number field by the given amount.
|
|
171
|
+
* Syntactic sugar for `op.increment(-n)`.
|
|
172
|
+
*
|
|
173
|
+
* @param n - The amount to decrement
|
|
174
|
+
*/
|
|
175
|
+
decrement(n: number): AtomicOpSentinel;
|
|
176
|
+
/**
|
|
177
|
+
* Set the field to the maximum of the current value and the given value.
|
|
178
|
+
* Concurrent max operations take the maximum of all values.
|
|
179
|
+
*
|
|
180
|
+
* @param n - The value to compare against the current value
|
|
181
|
+
*/
|
|
182
|
+
max(n: number): AtomicOpSentinel;
|
|
183
|
+
/**
|
|
184
|
+
* Set the field to the minimum of the current value and the given value.
|
|
185
|
+
* Concurrent min operations take the minimum of all values.
|
|
186
|
+
*
|
|
187
|
+
* @param n - The value to compare against the current value
|
|
188
|
+
*/
|
|
189
|
+
min(n: number): AtomicOpSentinel;
|
|
190
|
+
/**
|
|
191
|
+
* Append an item to an array field.
|
|
192
|
+
* Concurrent appends include all appended items.
|
|
193
|
+
*
|
|
194
|
+
* @param item - The item to append to the array
|
|
195
|
+
*/
|
|
196
|
+
append(item: unknown): AtomicOpSentinel;
|
|
197
|
+
/**
|
|
198
|
+
* Remove an item from an array field (by value equality).
|
|
199
|
+
* Concurrent removes of the same item are idempotent.
|
|
200
|
+
*
|
|
201
|
+
* @param item - The item to remove from the array
|
|
202
|
+
*/
|
|
203
|
+
remove(item: unknown): AtomicOpSentinel;
|
|
182
204
|
};
|
|
205
|
+
/**
|
|
206
|
+
* Extract the serializable AtomicOp from a sentinel (strips the Symbol marker).
|
|
207
|
+
*
|
|
208
|
+
* @param sentinel - The atomic op sentinel
|
|
209
|
+
* @returns A plain object suitable for JSON serialization
|
|
210
|
+
*/
|
|
211
|
+
declare function toAtomicOp(sentinel: AtomicOpSentinel): AtomicOp;
|
|
183
212
|
|
|
184
213
|
/**
|
|
185
214
|
* Input shape for defineSchema() — what the developer writes.
|
|
@@ -188,12 +217,26 @@ interface SchemaInput {
|
|
|
188
217
|
version: number;
|
|
189
218
|
collections: Record<string, CollectionInput>;
|
|
190
219
|
relations?: Record<string, RelationInput>;
|
|
220
|
+
/** Schema migrations keyed by target version number. */
|
|
221
|
+
migrations?: Record<number, MigrationDefinition>;
|
|
222
|
+
}
|
|
223
|
+
interface StateMachineInput {
|
|
224
|
+
/** The enum field this state machine controls */
|
|
225
|
+
field: string;
|
|
226
|
+
/** Map of state to allowed next states */
|
|
227
|
+
transitions: Record<string, string[]>;
|
|
228
|
+
/** What to do when an invalid transition is attempted */
|
|
229
|
+
onInvalidTransition: 'reject' | 'last-valid-state';
|
|
191
230
|
}
|
|
192
231
|
interface CollectionInput {
|
|
193
232
|
fields: Record<string, FieldBuilder<any, any, any>>;
|
|
194
233
|
indexes?: string[];
|
|
195
234
|
constraints?: ConstraintInput[];
|
|
196
235
|
resolve?: Record<string, CustomResolver>;
|
|
236
|
+
/** Scope fields for sync filtering. Only records matching the client's scope values are synced. */
|
|
237
|
+
scope?: string[];
|
|
238
|
+
/** State machine definition constraining transitions on an enum field */
|
|
239
|
+
stateMachine?: StateMachineInput;
|
|
197
240
|
}
|
|
198
241
|
interface ConstraintInput {
|
|
199
242
|
type: 'unique' | 'capacity' | 'referential';
|
|
@@ -398,4 +441,277 @@ declare function serializeVector(vector: VersionVector): string;
|
|
|
398
441
|
*/
|
|
399
442
|
declare function deserializeVector(s: string): VersionVector;
|
|
400
443
|
|
|
401
|
-
|
|
444
|
+
/**
|
|
445
|
+
* Per-collection scope map: `{ collectionName: { field: value, ... } }`
|
|
446
|
+
*
|
|
447
|
+
* Used to filter which operations a client should receive during sync.
|
|
448
|
+
*/
|
|
449
|
+
type ScopeMap = Record<string, Record<string, unknown>>;
|
|
450
|
+
/**
|
|
451
|
+
* Build a per-collection scope map from the schema's scope declarations
|
|
452
|
+
* and the client's flat scope values.
|
|
453
|
+
*
|
|
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).
|
|
457
|
+
*
|
|
458
|
+
* @param schema - The schema definition with scope declarations
|
|
459
|
+
* @param scopeValues - Flat key-value scope values from the client
|
|
460
|
+
* @returns A per-collection scope map
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* // Schema declares: sales.scope = ['orgId', 'storeId']
|
|
465
|
+
* // Client provides: { orgId: 'org-123', storeId: 'store-456' }
|
|
466
|
+
* // Result: { sales: { orgId: 'org-123', storeId: 'store-456' }, products: {} }
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
declare function buildScopeMap(schema: SchemaDefinition, scopeValues: Record<string, unknown>): ScopeMap;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Offline-safe sequence formatting.
|
|
473
|
+
*
|
|
474
|
+
* Format tokens:
|
|
475
|
+
* - `{date}` → YYYYMMDD (current date)
|
|
476
|
+
* - `{node4}` → first 4 characters of nodeId
|
|
477
|
+
* - `{node8}` → first 8 characters of nodeId
|
|
478
|
+
* - `{seq}` → zero-padded counter (default 4 digits)
|
|
479
|
+
* - `{seq:N}` → zero-padded counter with N digits
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```typescript
|
|
483
|
+
* formatSequenceValue('INV-{date}-{node4}-{seq}', 42, 'a1b2c3d4e5f6')
|
|
484
|
+
* // → "INV-20260508-a1b2-0042"
|
|
485
|
+
*
|
|
486
|
+
* formatSequenceValue('ORDER-{seq:6}', 7, 'node-id')
|
|
487
|
+
* // → "ORDER-000007"
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
declare function formatSequenceValue(template: string, counter: number, nodeId: string, now?: Date): string;
|
|
491
|
+
/**
|
|
492
|
+
* Default format when none is provided: `{name}-{seq:4}`.
|
|
493
|
+
*/
|
|
494
|
+
declare function defaultSequenceFormat(name: string): string;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Convert migration steps to SQL statements.
|
|
498
|
+
*
|
|
499
|
+
* Structural steps (addField, removeField, renameField, addIndex, removeIndex)
|
|
500
|
+
* produce SQL. Backfill steps are skipped (handled at the application layer
|
|
501
|
+
* by reading rows and applying the transform function).
|
|
502
|
+
*
|
|
503
|
+
* @param steps - The migration steps from a MigrationBuilder
|
|
504
|
+
* @returns Array of SQL statements for structural changes
|
|
505
|
+
*/
|
|
506
|
+
declare function migrationStepsToSQL(steps: readonly MigrationStep[]): string[];
|
|
507
|
+
/**
|
|
508
|
+
* Generate SQL statements to roll back a migration.
|
|
509
|
+
*
|
|
510
|
+
* Uses the migration's explicit rollback steps if available,
|
|
511
|
+
* otherwise auto-generates inverse steps from the forward steps.
|
|
512
|
+
*
|
|
513
|
+
* Backfill steps in the rollback are skipped (handled at the application layer).
|
|
514
|
+
*
|
|
515
|
+
* @param migration - The migration definition to generate rollback SQL for
|
|
516
|
+
* @returns Array of SQL statements that undo the migration's structural changes
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```typescript
|
|
520
|
+
* const migration = migrate()
|
|
521
|
+
* .addField('todos', 'priority', t.enum(['low', 'medium', 'high']).default('medium'))
|
|
522
|
+
* .addIndex('todos', 'priority')
|
|
523
|
+
*
|
|
524
|
+
* const rollbackSQL = rollbackStepsToSQL(migration)
|
|
525
|
+
* // ['DROP INDEX IF EXISTS idx_todos_priority',
|
|
526
|
+
* // 'ALTER TABLE todos DROP COLUMN priority']
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
declare function rollbackStepsToSQL(migration: MigrationDefinition): string[];
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* A migration that includes both forward (up) and backward (down) steps.
|
|
533
|
+
* Rollback steps are applied in reverse order of the forward steps.
|
|
534
|
+
*/
|
|
535
|
+
interface ReversibleMigration {
|
|
536
|
+
readonly up: readonly MigrationStep[];
|
|
537
|
+
readonly down: readonly MigrationStep[];
|
|
538
|
+
readonly fromVersion: number;
|
|
539
|
+
readonly toVersion: number;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Error thrown when a migration step cannot be automatically rolled back
|
|
543
|
+
* and no explicit down step has been provided.
|
|
544
|
+
*/
|
|
545
|
+
declare class MigrationRollbackError extends KoraError {
|
|
546
|
+
constructor(step: MigrationStep);
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Determines whether a migration step can be automatically rolled back
|
|
550
|
+
* without explicit developer-provided down steps.
|
|
551
|
+
*
|
|
552
|
+
* Auto-rollback is possible when the inverse operation is deterministic:
|
|
553
|
+
* - addField -> removeField (drop the added column)
|
|
554
|
+
* - addIndex -> removeIndex (drop the added index)
|
|
555
|
+
* - removeIndex -> addIndex (re-create the index)
|
|
556
|
+
* - renameField -> renameField (swap from/to names)
|
|
557
|
+
*
|
|
558
|
+
* Steps that CANNOT auto-rollback:
|
|
559
|
+
* - removeField: the field descriptor is lost (need it to re-create the column)
|
|
560
|
+
* - backfill: data transforms are not reversible
|
|
561
|
+
*
|
|
562
|
+
* @param step - The forward migration step to check
|
|
563
|
+
* @returns true if the step can be auto-rolled back
|
|
564
|
+
*/
|
|
565
|
+
declare function canAutoRollback(step: MigrationStep): boolean;
|
|
566
|
+
/**
|
|
567
|
+
* Generates rollback steps for a list of forward migration steps.
|
|
568
|
+
* Steps are reversed in order (last forward step becomes first rollback step).
|
|
569
|
+
*
|
|
570
|
+
* For steps that cannot be auto-rolled back, throws a MigrationRollbackError.
|
|
571
|
+
* Use canAutoRollback() to check before calling, or provide explicit down steps
|
|
572
|
+
* via the MigrationBuilder .down() API.
|
|
573
|
+
*
|
|
574
|
+
* @param forwardSteps - The forward migration steps to generate rollbacks for
|
|
575
|
+
* @returns Array of rollback steps in reverse execution order
|
|
576
|
+
* @throws MigrationRollbackError if any step cannot be auto-rolled back
|
|
577
|
+
*/
|
|
578
|
+
declare function generateRollbackSteps(forwardSteps: readonly MigrationStep[]): MigrationStep[];
|
|
579
|
+
/**
|
|
580
|
+
* Create a ReversibleMigration from forward steps, explicit down steps, and version info.
|
|
581
|
+
*
|
|
582
|
+
* If explicit down steps are provided, they are used as-is.
|
|
583
|
+
* If no explicit down steps are provided, auto-generation is attempted.
|
|
584
|
+
*
|
|
585
|
+
* @param upSteps - The forward migration steps
|
|
586
|
+
* @param downSteps - Optional explicit rollback steps (overrides auto-generation)
|
|
587
|
+
* @param fromVersion - The schema version before the migration
|
|
588
|
+
* @param toVersion - The schema version after the migration
|
|
589
|
+
* @returns A complete ReversibleMigration
|
|
590
|
+
* @throws MigrationRollbackError if auto-generation fails and no explicit down steps provided
|
|
591
|
+
*/
|
|
592
|
+
declare function createReversibleMigration(upSteps: readonly MigrationStep[], downSteps: readonly MigrationStep[] | null, fromVersion: number, toVersion: number): ReversibleMigration;
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Validates whether a transition from one state to another is allowed
|
|
596
|
+
* by the given state machine constraint.
|
|
597
|
+
*
|
|
598
|
+
* @param constraint - The state machine constraint defining allowed transitions
|
|
599
|
+
* @param fromValue - The current state value (before the transition)
|
|
600
|
+
* @param toValue - The target state value (after the transition)
|
|
601
|
+
* @returns A TransitionValidationResult describing whether the transition is valid
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```typescript
|
|
605
|
+
* const constraint: StateMachineConstraint = {
|
|
606
|
+
* field: 'status',
|
|
607
|
+
* collection: 'orders',
|
|
608
|
+
* transitions: {
|
|
609
|
+
* draft: ['submitted', 'cancelled'],
|
|
610
|
+
* submitted: ['approved'],
|
|
611
|
+
* approved: [],
|
|
612
|
+
* },
|
|
613
|
+
* }
|
|
614
|
+
*
|
|
615
|
+
* const result = validateTransition(constraint, 'draft', 'submitted')
|
|
616
|
+
* // { valid: true, from: 'draft', to: 'submitted', field: 'status',
|
|
617
|
+
* // collection: 'orders', allowedTargets: ['submitted', 'cancelled'] }
|
|
618
|
+
* ```
|
|
619
|
+
*/
|
|
620
|
+
declare function validateTransition(constraint: StateMachineConstraint, fromValue: unknown, toValue: unknown): TransitionValidationResult;
|
|
621
|
+
/**
|
|
622
|
+
* Extracts all state machine constraints from a schema definition.
|
|
623
|
+
* Scans every collection for enum fields that have transition rules declared
|
|
624
|
+
* via the `.transitions()` builder method.
|
|
625
|
+
*
|
|
626
|
+
* @param schema - The schema definition to extract constraints from
|
|
627
|
+
* @returns An array of StateMachineConstraint objects, one per enum field with transitions
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```typescript
|
|
631
|
+
* const schema = defineSchema({
|
|
632
|
+
* version: 1,
|
|
633
|
+
* collections: {
|
|
634
|
+
* orders: {
|
|
635
|
+
* fields: {
|
|
636
|
+
* status: t.enum(['draft', 'submitted']).transitions({
|
|
637
|
+
* draft: ['submitted'],
|
|
638
|
+
* submitted: [],
|
|
639
|
+
* }),
|
|
640
|
+
* },
|
|
641
|
+
* },
|
|
642
|
+
* },
|
|
643
|
+
* })
|
|
644
|
+
*
|
|
645
|
+
* const constraints = buildStateMachineConstraints(schema)
|
|
646
|
+
* // [{ field: 'status', collection: 'orders', transitions: { draft: ['submitted'], submitted: [] } }]
|
|
647
|
+
* ```
|
|
648
|
+
*/
|
|
649
|
+
declare function buildStateMachineConstraints(schema: SchemaDefinition): StateMachineConstraint[];
|
|
650
|
+
/**
|
|
651
|
+
* Finds the state machine constraint for a specific field in a specific collection,
|
|
652
|
+
* if one exists.
|
|
653
|
+
*
|
|
654
|
+
* @param schema - The schema definition to search
|
|
655
|
+
* @param collection - The collection name
|
|
656
|
+
* @param field - The field name
|
|
657
|
+
* @returns The TransitionMap if the field has transitions declared, or null otherwise
|
|
658
|
+
*/
|
|
659
|
+
declare function getTransitionMap(schema: SchemaDefinition, collection: string, field: string): TransitionMap | null;
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Output of the proto definition generator.
|
|
663
|
+
* Contains the .proto file text, a type mapping, and a JSON descriptor
|
|
664
|
+
* compatible with protobufjs's `Root.fromJSON()`.
|
|
665
|
+
*/
|
|
666
|
+
interface ProtoOutput {
|
|
667
|
+
/** The generated .proto file content as a string */
|
|
668
|
+
proto: string;
|
|
669
|
+
/** TypeScript type map: field name -> protobuf type */
|
|
670
|
+
typeMap: Map<string, string>;
|
|
671
|
+
/** JSON descriptor for dynamic protobufjs usage (no .proto file needed) */
|
|
672
|
+
jsonDescriptor: Record<string, unknown>;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Generates Protocol Buffer definitions from a Kora schema.
|
|
676
|
+
*
|
|
677
|
+
* Produces three outputs:
|
|
678
|
+
* 1. A `.proto` file string conforming to proto3 syntax
|
|
679
|
+
* 2. A type map linking Kora field paths to protobuf types
|
|
680
|
+
* 3. A JSON descriptor for runtime protobufjs usage via `Root.fromJSON()`
|
|
681
|
+
*
|
|
682
|
+
* The generated definitions include:
|
|
683
|
+
* - Per-collection record messages with proper type mappings
|
|
684
|
+
* - Nested enum types for enum fields
|
|
685
|
+
* - `KoraOperation` wrapper for the sync wire format
|
|
686
|
+
* - `OperationBatch` for batched sync transfers
|
|
687
|
+
* - `HandshakeMessage` / `HandshakeResponse` for sync session initiation
|
|
688
|
+
* - `Acknowledgment` for delivery confirmation
|
|
689
|
+
*
|
|
690
|
+
* @param schema - A validated SchemaDefinition from defineSchema()
|
|
691
|
+
* @returns ProtoOutput with proto text, type map, and JSON descriptor
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```typescript
|
|
695
|
+
* import { defineSchema, t, generateProtoDefinitions } from '@korajs/core'
|
|
696
|
+
*
|
|
697
|
+
* const schema = defineSchema({
|
|
698
|
+
* version: 1,
|
|
699
|
+
* collections: {
|
|
700
|
+
* todos: {
|
|
701
|
+
* fields: {
|
|
702
|
+
* title: t.string(),
|
|
703
|
+
* completed: t.boolean().default(false),
|
|
704
|
+
* }
|
|
705
|
+
* }
|
|
706
|
+
* }
|
|
707
|
+
* })
|
|
708
|
+
*
|
|
709
|
+
* const { proto, typeMap, jsonDescriptor } = generateProtoDefinitions(schema)
|
|
710
|
+
* // proto is a valid .proto file string
|
|
711
|
+
* // typeMap maps "todos.title" -> "string", "todos.completed" -> "bool"
|
|
712
|
+
* // jsonDescriptor can be loaded with protobuf.Root.fromJSON()
|
|
713
|
+
* ```
|
|
714
|
+
*/
|
|
715
|
+
declare function generateProtoDefinitions(schema: SchemaDefinition): ProtoOutput;
|
|
716
|
+
|
|
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 };
|