@korajs/core 1.0.0-beta.4 → 1.0.0-beta.6
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/bindings/index.d.cts +2 -2
- package/dist/bindings/index.d.ts +2 -2
- package/dist/{build-scope-map-K25AyQXb.d.cts → build-scope-map-Bm6Lqo9F.d.cts} +1 -1
- package/dist/{build-scope-map-BvdTzmm4.d.ts → build-scope-map-C60lT-4I.d.ts} +1 -1
- package/dist/{events-DhblJN4r.d.cts → events-CT9y24ht.d.cts} +12 -0
- package/dist/{events-DhblJN4r.d.ts → events-CT9y24ht.d.ts} +12 -0
- package/dist/index.cjs +91 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -5
- package/dist/index.d.ts +53 -5
- package/dist/index.js +89 -16
- package/dist/index.js.map +1 -1
- package/dist/internal.d.cts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/{operation-D-pemjcf.d.cts → operation-BxQjKMvK.d.cts} +1 -1
- package/dist/{operation-CC7O3-wf.d.ts → operation-C9BEVSX4.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as RandomSource, B as BlobRef, C as CollectionDefinition, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, b as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, J as JsonFieldBuilder, 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-
|
|
2
|
-
export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, K as KoraEvent, o as KoraEventByType, p as KoraEventEmitter, q as KoraEventListener, r as KoraEventType, s as MERGE_STRATEGIES, t as MergeStrategy, u as MergeTrace, v as MigrationBuilder, w as OnDeleteAction, x as OperationInput, y as RelationType, z as RollbackBuilder, D as SecretMode, G as SequenceConfig, I as StateMachineDefinition, L as SyncDiagnosticsSnapshot, N as SyncRuleDefinition, P as TimeSource, Q as migrate, U as t } from './events-
|
|
3
|
-
export { H as HybridLogicalClock, M as MAX_LOGICAL, c as createOperation, i as isValidOperation, v as verifyOperationIntegrity } from './operation-
|
|
4
|
-
export { S as ScopeMap, b as buildScopeMap } from './build-scope-map-
|
|
1
|
+
import { R as RandomSource, B as BlobRef, C as CollectionDefinition, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, b as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, J as JsonFieldBuilder, 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-CT9y24ht.cjs';
|
|
2
|
+
export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, K as KoraEvent, o as KoraEventByType, p as KoraEventEmitter, q as KoraEventListener, r as KoraEventType, s as MERGE_STRATEGIES, t as MergeStrategy, u as MergeTrace, v as MigrationBuilder, w as OnDeleteAction, x as OperationInput, y as RelationType, z as RollbackBuilder, D as SecretMode, G as SequenceConfig, I as StateMachineDefinition, L as SyncDiagnosticsSnapshot, N as SyncRuleDefinition, P as TimeSource, Q as migrate, U as t } from './events-CT9y24ht.cjs';
|
|
3
|
+
export { H as HybridLogicalClock, M as MAX_LOGICAL, c as createOperation, i as isValidOperation, v as verifyOperationIntegrity } from './operation-BxQjKMvK.cjs';
|
|
4
|
+
export { S as ScopeMap, b as buildScopeMap } from './build-scope-map-Bm6Lqo9F.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Base error class for all Kora errors.
|
|
@@ -359,6 +359,20 @@ interface AtomicOpSentinel {
|
|
|
359
359
|
* @returns true if the value is an AtomicOpSentinel
|
|
360
360
|
*/
|
|
361
361
|
declare function isAtomicOp(value: unknown): value is AtomicOpSentinel;
|
|
362
|
+
/**
|
|
363
|
+
* Apply a plain atomic op (`{ type, value }`) to a current value, producing the
|
|
364
|
+
* concrete result. This is the single source of truth for atomic-op semantics:
|
|
365
|
+
* {@link resolveAtomicOp} (sentinel form, used on the write path) delegates here,
|
|
366
|
+
* and the server's materialization replays stored atomic ops through it, so the
|
|
367
|
+
* server's materialized view composes concurrent atomic writes identically to the
|
|
368
|
+
* client. Folding this over a field's writes in HLC order yields, for a same-type
|
|
369
|
+
* atomic chain, exactly the composed intent (sum of increments, max of maxes, ...).
|
|
370
|
+
*
|
|
371
|
+
* @param currentValue - The current value of the field
|
|
372
|
+
* @param atomicOp - The atomic op to apply (type + operand)
|
|
373
|
+
* @returns The resulting concrete value
|
|
374
|
+
*/
|
|
375
|
+
declare function applyAtomicOp(currentValue: unknown, atomicOp: AtomicOp): unknown;
|
|
362
376
|
/**
|
|
363
377
|
* Resolve an atomic op sentinel against a current value to produce a concrete result.
|
|
364
378
|
*
|
|
@@ -437,6 +451,40 @@ declare const op: {
|
|
|
437
451
|
*/
|
|
438
452
|
declare function toAtomicOp(sentinel: AtomicOpSentinel): AtomicOp;
|
|
439
453
|
|
|
454
|
+
/** One operation's contribution to a record's materialized state. */
|
|
455
|
+
interface ReplayOperation {
|
|
456
|
+
type: string;
|
|
457
|
+
data: Record<string, unknown> | null;
|
|
458
|
+
/**
|
|
459
|
+
* Atomic-op intents carried by this operation, per field. When present, a field
|
|
460
|
+
* is composed (rather than overwritten) if the previous writer on that field was
|
|
461
|
+
* an atomic op of the same type. Absent means every field resolves by
|
|
462
|
+
* last-write-wins.
|
|
463
|
+
*/
|
|
464
|
+
atomicOps?: Record<string, AtomicOp> | null;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Replay a list of operations (MUST be pre-sorted in HLC total order —
|
|
468
|
+
* wallTime, then logical, then nodeId) to produce the current state of a single
|
|
469
|
+
* record, composing atomic-op intents.
|
|
470
|
+
*
|
|
471
|
+
* Per field, an atomic op composes onto the running value only when the field's
|
|
472
|
+
* previous writer was an atomic op of the SAME type (a same-type atomic chain:
|
|
473
|
+
* concurrent increments sum, maxes take the max, appends accumulate); any other
|
|
474
|
+
* write, including the first atomic write after a plain set, resolves by
|
|
475
|
+
* last-write-wins on the resolved value. Because operations are folded in HLC order,
|
|
476
|
+
* the current op always wins that last-write-wins comparison, so the result is
|
|
477
|
+
* deterministic and identical on every replica that folds the same operation set.
|
|
478
|
+
*
|
|
479
|
+
* This is the single definition of atomic materialization shared by the client
|
|
480
|
+
* (`@korajs/store` apply pipeline) and the server (`@korajs/server` materialization),
|
|
481
|
+
* so both converge to the same value for any number of concurrent atomic writers.
|
|
482
|
+
*
|
|
483
|
+
* Returns the record field data (without `id`) or null if the record was deleted
|
|
484
|
+
* or never inserted.
|
|
485
|
+
*/
|
|
486
|
+
declare function replayOperationsForRecord(ops: ReplayOperation[]): Record<string, unknown> | null;
|
|
487
|
+
|
|
440
488
|
/**
|
|
441
489
|
* Canonical JSON-safe encoding of binary bytes stored inside `op.data` /
|
|
442
490
|
* `op.previousData` (currently richtext field values). A raw Uint8Array
|
|
@@ -1077,4 +1125,4 @@ interface ProtoOutput {
|
|
|
1077
1125
|
*/
|
|
1078
1126
|
declare function generateProtoDefinitions(schema: SchemaDefinition): ProtoOutput;
|
|
1079
1127
|
|
|
1080
|
-
export { APPLY_FAILURE_CODES, APPLY_RESULTS, AppNotReadyError, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, BlobRef, type BlobRefMetadata, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, InvalidTimestampError, KORA_ERROR_FIX_SUGGESTIONS, type KoraBytesValue, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, MissingSecretKeyError, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, RemoteClockDriftError, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type SecretKeyProvider, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyOperationTransforms, base64ToBytes, buildStateMachineConstraints, bytesToBase64, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createBlobRef, createReversibleMigration, createVersionVector, decodeBytesFromOpData, decryptSecret, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, encodeBytesForOpData, encryptSecret, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, hashBlob, hashSecret, isApplyFailure, isAtomicOp, isBlobRef, isCollectionSyncScoped, isKoraBytesValue, isLegacyNumericByteObject, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, quoteIdent, resolveAtomicOp, revealSecret, rollbackStepsToSQL, serializeVector, toAtomicOp, transformSecretFieldsForWrite, validateRecord, validateTransition, vectorsEqual, verifySecret, verifySecretValue };
|
|
1128
|
+
export { APPLY_FAILURE_CODES, APPLY_RESULTS, AppNotReadyError, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, BlobRef, type BlobRefMetadata, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, InvalidTimestampError, KORA_ERROR_FIX_SUGGESTIONS, type KoraBytesValue, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, MissingSecretKeyError, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, RemoteClockDriftError, type ReplayOperation, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type SecretKeyProvider, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyAtomicOp, applyOperationTransforms, base64ToBytes, buildStateMachineConstraints, bytesToBase64, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createBlobRef, createReversibleMigration, createVersionVector, decodeBytesFromOpData, decryptSecret, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, encodeBytesForOpData, encryptSecret, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, hashBlob, hashSecret, isApplyFailure, isAtomicOp, isBlobRef, isCollectionSyncScoped, isKoraBytesValue, isLegacyNumericByteObject, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, quoteIdent, replayOperationsForRecord, resolveAtomicOp, revealSecret, rollbackStepsToSQL, serializeVector, toAtomicOp, transformSecretFieldsForWrite, validateRecord, validateTransition, vectorsEqual, verifySecret, verifySecretValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as RandomSource, B as BlobRef, C as CollectionDefinition, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, b as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, J as JsonFieldBuilder, 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-
|
|
2
|
-
export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, K as KoraEvent, o as KoraEventByType, p as KoraEventEmitter, q as KoraEventListener, r as KoraEventType, s as MERGE_STRATEGIES, t as MergeStrategy, u as MergeTrace, v as MigrationBuilder, w as OnDeleteAction, x as OperationInput, y as RelationType, z as RollbackBuilder, D as SecretMode, G as SequenceConfig, I as StateMachineDefinition, L as SyncDiagnosticsSnapshot, N as SyncRuleDefinition, P as TimeSource, Q as migrate, U as t } from './events-
|
|
3
|
-
export { H as HybridLogicalClock, M as MAX_LOGICAL, c as createOperation, i as isValidOperation, v as verifyOperationIntegrity } from './operation-
|
|
4
|
-
export { S as ScopeMap, b as buildScopeMap } from './build-scope-map-
|
|
1
|
+
import { R as RandomSource, B as BlobRef, C as CollectionDefinition, A as AtomicOpType, a as AtomicOp, F as FieldBuilder, b as CustomResolver, M as MigrationDefinition, S as SchemaDefinition, c as RelationDefinition, O as OperationType, E as EnumFieldBuilder, J as JsonFieldBuilder, 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-CT9y24ht.js';
|
|
2
|
+
export { j as CONNECTION_QUALITIES, k as ConnectionQuality, l as Constraint, m as FieldDescriptor, n as FieldMergeStrategy, H as HLCTimestamp, K as KoraEvent, o as KoraEventByType, p as KoraEventEmitter, q as KoraEventListener, r as KoraEventType, s as MERGE_STRATEGIES, t as MergeStrategy, u as MergeTrace, v as MigrationBuilder, w as OnDeleteAction, x as OperationInput, y as RelationType, z as RollbackBuilder, D as SecretMode, G as SequenceConfig, I as StateMachineDefinition, L as SyncDiagnosticsSnapshot, N as SyncRuleDefinition, P as TimeSource, Q as migrate, U as t } from './events-CT9y24ht.js';
|
|
3
|
+
export { H as HybridLogicalClock, M as MAX_LOGICAL, c as createOperation, i as isValidOperation, v as verifyOperationIntegrity } from './operation-C9BEVSX4.js';
|
|
4
|
+
export { S as ScopeMap, b as buildScopeMap } from './build-scope-map-C60lT-4I.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Base error class for all Kora errors.
|
|
@@ -359,6 +359,20 @@ interface AtomicOpSentinel {
|
|
|
359
359
|
* @returns true if the value is an AtomicOpSentinel
|
|
360
360
|
*/
|
|
361
361
|
declare function isAtomicOp(value: unknown): value is AtomicOpSentinel;
|
|
362
|
+
/**
|
|
363
|
+
* Apply a plain atomic op (`{ type, value }`) to a current value, producing the
|
|
364
|
+
* concrete result. This is the single source of truth for atomic-op semantics:
|
|
365
|
+
* {@link resolveAtomicOp} (sentinel form, used on the write path) delegates here,
|
|
366
|
+
* and the server's materialization replays stored atomic ops through it, so the
|
|
367
|
+
* server's materialized view composes concurrent atomic writes identically to the
|
|
368
|
+
* client. Folding this over a field's writes in HLC order yields, for a same-type
|
|
369
|
+
* atomic chain, exactly the composed intent (sum of increments, max of maxes, ...).
|
|
370
|
+
*
|
|
371
|
+
* @param currentValue - The current value of the field
|
|
372
|
+
* @param atomicOp - The atomic op to apply (type + operand)
|
|
373
|
+
* @returns The resulting concrete value
|
|
374
|
+
*/
|
|
375
|
+
declare function applyAtomicOp(currentValue: unknown, atomicOp: AtomicOp): unknown;
|
|
362
376
|
/**
|
|
363
377
|
* Resolve an atomic op sentinel against a current value to produce a concrete result.
|
|
364
378
|
*
|
|
@@ -437,6 +451,40 @@ declare const op: {
|
|
|
437
451
|
*/
|
|
438
452
|
declare function toAtomicOp(sentinel: AtomicOpSentinel): AtomicOp;
|
|
439
453
|
|
|
454
|
+
/** One operation's contribution to a record's materialized state. */
|
|
455
|
+
interface ReplayOperation {
|
|
456
|
+
type: string;
|
|
457
|
+
data: Record<string, unknown> | null;
|
|
458
|
+
/**
|
|
459
|
+
* Atomic-op intents carried by this operation, per field. When present, a field
|
|
460
|
+
* is composed (rather than overwritten) if the previous writer on that field was
|
|
461
|
+
* an atomic op of the same type. Absent means every field resolves by
|
|
462
|
+
* last-write-wins.
|
|
463
|
+
*/
|
|
464
|
+
atomicOps?: Record<string, AtomicOp> | null;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Replay a list of operations (MUST be pre-sorted in HLC total order —
|
|
468
|
+
* wallTime, then logical, then nodeId) to produce the current state of a single
|
|
469
|
+
* record, composing atomic-op intents.
|
|
470
|
+
*
|
|
471
|
+
* Per field, an atomic op composes onto the running value only when the field's
|
|
472
|
+
* previous writer was an atomic op of the SAME type (a same-type atomic chain:
|
|
473
|
+
* concurrent increments sum, maxes take the max, appends accumulate); any other
|
|
474
|
+
* write, including the first atomic write after a plain set, resolves by
|
|
475
|
+
* last-write-wins on the resolved value. Because operations are folded in HLC order,
|
|
476
|
+
* the current op always wins that last-write-wins comparison, so the result is
|
|
477
|
+
* deterministic and identical on every replica that folds the same operation set.
|
|
478
|
+
*
|
|
479
|
+
* This is the single definition of atomic materialization shared by the client
|
|
480
|
+
* (`@korajs/store` apply pipeline) and the server (`@korajs/server` materialization),
|
|
481
|
+
* so both converge to the same value for any number of concurrent atomic writers.
|
|
482
|
+
*
|
|
483
|
+
* Returns the record field data (without `id`) or null if the record was deleted
|
|
484
|
+
* or never inserted.
|
|
485
|
+
*/
|
|
486
|
+
declare function replayOperationsForRecord(ops: ReplayOperation[]): Record<string, unknown> | null;
|
|
487
|
+
|
|
440
488
|
/**
|
|
441
489
|
* Canonical JSON-safe encoding of binary bytes stored inside `op.data` /
|
|
442
490
|
* `op.previousData` (currently richtext field values). A raw Uint8Array
|
|
@@ -1077,4 +1125,4 @@ interface ProtoOutput {
|
|
|
1077
1125
|
*/
|
|
1078
1126
|
declare function generateProtoDefinitions(schema: SchemaDefinition): ProtoOutput;
|
|
1079
1127
|
|
|
1080
|
-
export { APPLY_FAILURE_CODES, APPLY_RESULTS, AppNotReadyError, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, BlobRef, type BlobRefMetadata, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, InvalidTimestampError, KORA_ERROR_FIX_SUGGESTIONS, type KoraBytesValue, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, MissingSecretKeyError, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, RemoteClockDriftError, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type SecretKeyProvider, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyOperationTransforms, base64ToBytes, buildStateMachineConstraints, bytesToBase64, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createBlobRef, createReversibleMigration, createVersionVector, decodeBytesFromOpData, decryptSecret, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, encodeBytesForOpData, encryptSecret, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, hashBlob, hashSecret, isApplyFailure, isAtomicOp, isBlobRef, isCollectionSyncScoped, isKoraBytesValue, isLegacyNumericByteObject, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, quoteIdent, resolveAtomicOp, revealSecret, rollbackStepsToSQL, serializeVector, toAtomicOp, transformSecretFieldsForWrite, validateRecord, validateTransition, vectorsEqual, verifySecret, verifySecretValue };
|
|
1128
|
+
export { APPLY_FAILURE_CODES, APPLY_RESULTS, AppNotReadyError, type ApplyFailureReason, type ApplyResult, ArrayFieldBuilder, AtomicOp, type AtomicOpSentinel, AtomicOpType, BlobRef, type BlobRefMetadata, CausalTracker, ClockDriftError, CollectionDefinition, type CollectionInput, type ConstraintInput, CustomResolver, EnumFieldBuilder, FieldBuilder, FieldKind, type FieldKindToType, type InferFieldType, type InferInsertInput, type InferRecord, type InferUpdateInput, InvalidTimestampError, KORA_ERROR_FIX_SUGGESTIONS, type KoraBytesValue, KoraError, MergeConflictError, MigrationDefinition, MigrationRollbackError, MigrationStep, MissingSecretKeyError, Operation, OperationError, type OperationLog, type OperationTransform, OperationType, type ProtoOutput, RandomSource, RelationDefinition, type RelationInput, RemoteClockDriftError, type ReplayOperation, type ReversibleMigration, SchemaDefinition, type SchemaInput, SchemaValidationError, type SecretKeyProvider, StateMachineConstraint, type StateMachineInput, StorageError, SyncError, TransitionMap, TransitionValidationResult, type TypedSchemaDefinition, VersionVector, advanceVector, applyAtomicOp, applyOperationTransforms, base64ToBytes, buildStateMachineConstraints, bytesToBase64, canAutoRollback, collectSchemaScopeFields, collectSchemaScopeValueKeys, computeDelta, createBlobRef, createReversibleMigration, createVersionVector, decodeBytesFromOpData, decryptSecret, defaultApplyFailureReason, defaultSequenceFormat, defineSchema, deserializeVector, dominates, encodeBytesForOpData, encryptSecret, extractScopeValuesFromClaims, extractTimestamp, formatSequenceValue, generateFullDDL, generateProtoDefinitions, generateRollbackSteps, generateSQL, generateUUIDv7, getCollectionScopeBindings, getKoraErrorFix, getTransitionMap, hasSchemaSyncRules, hashBlob, hashSecret, isApplyFailure, isAtomicOp, isBlobRef, isCollectionSyncScoped, isKoraBytesValue, isLegacyNumericByteObject, isValidUUIDv7, mergeVectors, migrationStepsToSQL, op, quoteIdent, replayOperationsForRecord, resolveAtomicOp, revealSecret, rollbackStepsToSQL, serializeVector, toAtomicOp, transformSecretFieldsForWrite, validateRecord, validateTransition, vectorsEqual, verifySecret, verifySecretValue };
|
package/dist/index.js
CHANGED
|
@@ -365,32 +365,36 @@ var KORA_ATOMIC_OP = /* @__PURE__ */ Symbol.for("kora.atomic_op");
|
|
|
365
365
|
function isAtomicOp(value) {
|
|
366
366
|
return typeof value === "object" && value !== null && KORA_ATOMIC_OP in value && value[KORA_ATOMIC_OP] === true;
|
|
367
367
|
}
|
|
368
|
-
function
|
|
369
|
-
switch (
|
|
368
|
+
function applyAtomicOp(currentValue, atomicOp) {
|
|
369
|
+
switch (atomicOp.type) {
|
|
370
370
|
case "increment": {
|
|
371
371
|
const current = typeof currentValue === "number" ? currentValue : 0;
|
|
372
|
-
const operand =
|
|
372
|
+
const operand = atomicOp.value;
|
|
373
373
|
return current + operand;
|
|
374
374
|
}
|
|
375
375
|
case "max": {
|
|
376
376
|
const current = typeof currentValue === "number" ? currentValue : Number.NEGATIVE_INFINITY;
|
|
377
|
-
return Math.max(current,
|
|
377
|
+
return Math.max(current, atomicOp.value);
|
|
378
378
|
}
|
|
379
379
|
case "min": {
|
|
380
380
|
const current = typeof currentValue === "number" ? currentValue : Number.POSITIVE_INFINITY;
|
|
381
|
-
return Math.min(current,
|
|
381
|
+
return Math.min(current, atomicOp.value);
|
|
382
382
|
}
|
|
383
383
|
case "append": {
|
|
384
384
|
const current = Array.isArray(currentValue) ? [...currentValue] : [];
|
|
385
|
-
current.push(
|
|
385
|
+
current.push(atomicOp.value);
|
|
386
386
|
return current;
|
|
387
387
|
}
|
|
388
388
|
case "remove": {
|
|
389
389
|
if (!Array.isArray(currentValue)) return [];
|
|
390
|
-
|
|
390
|
+
const target = JSON.stringify(atomicOp.value);
|
|
391
|
+
return currentValue.filter((item) => JSON.stringify(item) !== target);
|
|
391
392
|
}
|
|
392
393
|
}
|
|
393
394
|
}
|
|
395
|
+
function resolveAtomicOp(currentValue, sentinel) {
|
|
396
|
+
return applyAtomicOp(currentValue, { type: sentinel.type, value: sentinel.value });
|
|
397
|
+
}
|
|
394
398
|
function createSentinel(type, value) {
|
|
395
399
|
return Object.freeze({
|
|
396
400
|
[KORA_ATOMIC_OP]: true,
|
|
@@ -458,6 +462,46 @@ function toAtomicOp(sentinel) {
|
|
|
458
462
|
return { type: sentinel.type, value: sentinel.value };
|
|
459
463
|
}
|
|
460
464
|
|
|
465
|
+
// src/operations/replay-record.ts
|
|
466
|
+
function replayOperationsForRecord(ops) {
|
|
467
|
+
let record = null;
|
|
468
|
+
let deleted = false;
|
|
469
|
+
const lastWriterKind = {};
|
|
470
|
+
for (const op2 of ops) {
|
|
471
|
+
switch (op2.type) {
|
|
472
|
+
case "insert":
|
|
473
|
+
if (op2.data) {
|
|
474
|
+
record = { ...op2.data };
|
|
475
|
+
deleted = false;
|
|
476
|
+
for (const field of Object.keys(op2.data)) {
|
|
477
|
+
lastWriterKind[field] = "lww";
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
481
|
+
case "update":
|
|
482
|
+
if (op2.data) {
|
|
483
|
+
const next = { ...record ?? {} };
|
|
484
|
+
for (const [field, value] of Object.entries(op2.data)) {
|
|
485
|
+
const atomicOp = op2.atomicOps?.[field];
|
|
486
|
+
if (atomicOp && lastWriterKind[field] === `atomic:${atomicOp.type}`) {
|
|
487
|
+
next[field] = applyAtomicOp(next[field], atomicOp);
|
|
488
|
+
} else {
|
|
489
|
+
next[field] = value;
|
|
490
|
+
}
|
|
491
|
+
lastWriterKind[field] = atomicOp ? `atomic:${atomicOp.type}` : "lww";
|
|
492
|
+
}
|
|
493
|
+
record = next;
|
|
494
|
+
deleted = false;
|
|
495
|
+
}
|
|
496
|
+
break;
|
|
497
|
+
case "delete":
|
|
498
|
+
deleted = true;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return deleted ? null : record;
|
|
503
|
+
}
|
|
504
|
+
|
|
461
505
|
// src/operations/op-data-binary.ts
|
|
462
506
|
function isKoraBytesValue(value) {
|
|
463
507
|
if (typeof value !== "object" || value === null) {
|
|
@@ -1729,10 +1773,17 @@ function validateFieldValue(collection, fieldName, descriptor, value) {
|
|
|
1729
1773
|
break;
|
|
1730
1774
|
}
|
|
1731
1775
|
case "json": {
|
|
1732
|
-
|
|
1776
|
+
const nonJson = findNonJsonSerializable(value, fieldName);
|
|
1777
|
+
if (nonJson) {
|
|
1733
1778
|
throw new SchemaValidationError(
|
|
1734
|
-
`Field "${fieldName}" in collection "${collection}" must be JSON-serializable
|
|
1735
|
-
{
|
|
1779
|
+
`Field "${fieldName}" in collection "${collection}" must be JSON-serializable; found ${nonJson.receivedType} at "${nonJson.path}"`,
|
|
1780
|
+
{
|
|
1781
|
+
collection,
|
|
1782
|
+
field: fieldName,
|
|
1783
|
+
expectedType: "json",
|
|
1784
|
+
receivedType: nonJson.receivedType,
|
|
1785
|
+
path: nonJson.path
|
|
1786
|
+
}
|
|
1736
1787
|
);
|
|
1737
1788
|
}
|
|
1738
1789
|
break;
|
|
@@ -1769,21 +1820,41 @@ function isPlainObject(value) {
|
|
|
1769
1820
|
const proto = Object.getPrototypeOf(value);
|
|
1770
1821
|
return proto === null || proto === Object.prototype;
|
|
1771
1822
|
}
|
|
1772
|
-
function
|
|
1823
|
+
function findNonJsonSerializable(value, path, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1773
1824
|
if (value === null) {
|
|
1774
|
-
return
|
|
1825
|
+
return null;
|
|
1775
1826
|
}
|
|
1776
1827
|
const type = typeof value;
|
|
1777
1828
|
if (type === "string" || type === "number" || type === "boolean") {
|
|
1778
|
-
|
|
1829
|
+
if (type === "number" && !Number.isFinite(value)) {
|
|
1830
|
+
return { path, receivedType: describeType(value) };
|
|
1831
|
+
}
|
|
1832
|
+
return null;
|
|
1833
|
+
}
|
|
1834
|
+
if (type === "undefined" || type === "function" || type === "symbol" || type === "bigint") {
|
|
1835
|
+
return { path, receivedType: describeType(value) };
|
|
1779
1836
|
}
|
|
1780
1837
|
if (Array.isArray(value)) {
|
|
1781
|
-
|
|
1838
|
+
for (let index = 0; index < value.length; index++) {
|
|
1839
|
+
const invalid = findNonJsonSerializable(value[index], `${path}[${index}]`, seen);
|
|
1840
|
+
if (invalid) return invalid;
|
|
1841
|
+
}
|
|
1842
|
+
return null;
|
|
1782
1843
|
}
|
|
1783
1844
|
if (type === "object") {
|
|
1784
|
-
|
|
1845
|
+
const objectValue = value;
|
|
1846
|
+
if (seen.has(objectValue)) {
|
|
1847
|
+
return { path, receivedType: "circular object" };
|
|
1848
|
+
}
|
|
1849
|
+
seen.add(objectValue);
|
|
1850
|
+
for (const [key, nestedValue] of Object.entries(objectValue)) {
|
|
1851
|
+
const invalid = findNonJsonSerializable(nestedValue, `${path}.${key}`, seen);
|
|
1852
|
+
if (invalid) return invalid;
|
|
1853
|
+
}
|
|
1854
|
+
seen.delete(objectValue);
|
|
1855
|
+
return null;
|
|
1785
1856
|
}
|
|
1786
|
-
return
|
|
1857
|
+
return { path, receivedType: describeType(value) };
|
|
1787
1858
|
}
|
|
1788
1859
|
function describeType(value) {
|
|
1789
1860
|
if (value === null) {
|
|
@@ -2561,6 +2632,7 @@ export {
|
|
|
2561
2632
|
StorageError,
|
|
2562
2633
|
SyncError,
|
|
2563
2634
|
advanceVector,
|
|
2635
|
+
applyAtomicOp,
|
|
2564
2636
|
applyOperationTransforms,
|
|
2565
2637
|
base64ToBytes,
|
|
2566
2638
|
buildScopeMap,
|
|
@@ -2610,6 +2682,7 @@ export {
|
|
|
2610
2682
|
migrationStepsToSQL,
|
|
2611
2683
|
op,
|
|
2612
2684
|
quoteIdent,
|
|
2685
|
+
replayOperationsForRecord,
|
|
2613
2686
|
resolveAtomicOp,
|
|
2614
2687
|
revealSecret,
|
|
2615
2688
|
rollbackStepsToSQL,
|