@korajs/store 0.5.0 → 0.6.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
@@ -4,6 +4,7 @@ import { Operation, KoraError, VersionVector, SchemaDefinition, MergeTrace, Coll
4
4
  export { ApplyResult } from '@korajs/core';
5
5
  import { R as RelationEnforcer, L as LocalMutationContext } from './types-CTr00g_d.cjs';
6
6
  export { C as Collection } from './types-CTr00g_d.cjs';
7
+ import * as yjs from 'yjs';
7
8
 
8
9
  /**
9
10
  * In-memory materialized state at a causal cut in the operation log.
@@ -896,6 +897,62 @@ interface CollectionAccessor {
896
897
  where(conditions: Record<string, unknown>): QueryBuilder;
897
898
  }
898
899
 
900
+ /**
901
+ * Bridges the async QueryBuilder.subscribe() API with synchronous snapshot reads
902
+ * required by React useSyncExternalStore, Vue composables, and Svelte stores.
903
+ *
904
+ * Uses lazy subscription: the underlying query subscription starts when the first
905
+ * listener attaches and stops when the last listener detaches.
906
+ */
907
+ declare class QueryStore<T = CollectionRecord> {
908
+ private snapshot;
909
+ private listeners;
910
+ private unsubscribeQuery;
911
+ private active;
912
+ private readonly queryBuilder;
913
+ constructor(queryBuilder: QueryBuilder<T>);
914
+ /**
915
+ * Subscribe to snapshot changes.
916
+ *
917
+ * @returns Unsubscribe function
918
+ */
919
+ subscribe: (onStoreChange: () => void) => (() => void);
920
+ /** Synchronous read of the latest query results. */
921
+ getSnapshot: () => readonly T[];
922
+ /** Tear down listeners and the underlying query subscription. */
923
+ destroy(): void;
924
+ private startSubscription;
925
+ private stopSubscription;
926
+ private notifyListeners;
927
+ }
928
+
929
+ /**
930
+ * Ensures a query builder is backed by an open store (not a legacy pending placeholder).
931
+ */
932
+ declare function assertQueryReady(query: QueryBuilder<unknown>): void;
933
+
934
+ /**
935
+ * Reference-counted cache of {@link QueryStore} instances keyed by query descriptor.
936
+ * Identical queries from different components share one underlying subscription.
937
+ */
938
+ declare class QueryStoreCache {
939
+ private readonly scopeKey;
940
+ private entries;
941
+ constructor(scopeKey?: string);
942
+ getOrCreate<T>(queryBuilder: QueryBuilder<T>): QueryStore<T>;
943
+ release(queryBuilder: QueryBuilder<unknown>): void;
944
+ clear(): void;
945
+ get size(): number;
946
+ private getKey;
947
+ }
948
+ /**
949
+ * Process-wide shared query store cache for framework bindings.
950
+ *
951
+ * @deprecated Prefer {@link KoraApp.getQueryStoreCache} via `KoraProvider` context
952
+ * so each app instance owns an isolated cache.
953
+ */
954
+ declare function getSharedQueryStoreCache(): QueryStoreCache;
955
+
899
956
  /**
900
957
  * Bloom filter for subscription dependency tracking.
901
958
  *
@@ -1040,6 +1097,91 @@ declare function validateStateTransition(collectionName: string, recordId: strin
1040
1097
  */
1041
1098
  declare function validateUpdateStateMachine(collectionName: string, recordId: string, collectionDef: CollectionDefinition, currentRecord: Record<string, unknown>, updateData: Record<string, unknown>): Record<string, unknown>;
1042
1099
 
1100
+ /** User identity for collaborative cursor presence. */
1101
+ interface RichTextAwarenessUser {
1102
+ name: string;
1103
+ color: string;
1104
+ avatar?: string;
1105
+ }
1106
+ /** Remote collaborator cursor for a richtext field. */
1107
+ interface RichTextCursorInfo {
1108
+ clientId: number;
1109
+ userName: string;
1110
+ color: string;
1111
+ anchor: number;
1112
+ head: number;
1113
+ }
1114
+ /** Minimal sync surface required for richtext collaboration. */
1115
+ interface RichTextSyncEngine {
1116
+ getRichtextDocChannel?(): RichTextDocChannel;
1117
+ getAwarenessManager(): RichTextAwarenessManager;
1118
+ }
1119
+ interface RichTextDocChannel {
1120
+ shouldUseChannel(snapshotBytes: number, useDocChannel?: boolean): boolean;
1121
+ send(collection: string, recordId: string, field: string, update: Uint8Array): void;
1122
+ subscribe(collection: string, recordId: string, field: string, listener: (update: Uint8Array) => void): () => void;
1123
+ }
1124
+ interface RichTextAwarenessManager {
1125
+ clientId: number;
1126
+ getLocalState(): RichTextAwarenessState | null;
1127
+ setLocalState(state: RichTextAwarenessState): void;
1128
+ getStates(): Map<number, RichTextAwarenessState>;
1129
+ on(event: 'change', listener: () => void): () => void;
1130
+ }
1131
+ interface RichTextAwarenessState {
1132
+ user: RichTextAwarenessUser;
1133
+ cursor?: {
1134
+ collection: string;
1135
+ recordId: string;
1136
+ field: string;
1137
+ anchor: number;
1138
+ head: number;
1139
+ };
1140
+ }
1141
+ interface CreateRichTextControllerOptions {
1142
+ collection: CollectionAccessor;
1143
+ collectionName: string;
1144
+ recordId: string;
1145
+ fieldName: string;
1146
+ store: {
1147
+ collection(name: string): CollectionAccessor;
1148
+ };
1149
+ syncEngine?: RichTextSyncEngine | null;
1150
+ useDocChannel?: boolean;
1151
+ user?: RichTextAwarenessUser;
1152
+ }
1153
+ interface RichTextControllerSnapshot {
1154
+ ready: boolean;
1155
+ error: Error | null;
1156
+ canUndo: boolean;
1157
+ canRedo: boolean;
1158
+ cursors: readonly RichTextCursorInfo[];
1159
+ }
1160
+ interface RichTextController {
1161
+ readonly doc: yjs.Doc;
1162
+ readonly text: yjs.Text;
1163
+ getSnapshot(): RichTextControllerSnapshot;
1164
+ subscribe(listener: () => void): () => void;
1165
+ undo(): void;
1166
+ redo(): void;
1167
+ setCursor(anchor: number, head: number): void;
1168
+ clearCursor(): void;
1169
+ setUser(user: RichTextAwarenessUser | undefined): void;
1170
+ destroy(): void;
1171
+ }
1172
+
1173
+ /**
1174
+ * Framework-agnostic richtext binding: Yjs document lifecycle, persistence,
1175
+ * incremental doc channel, and awareness cursors.
1176
+ */
1177
+ declare function createRichTextController(options: CreateRichTextControllerOptions): RichTextController;
1178
+
1179
+ /**
1180
+ * Narrows a sync engine reference to the richtext controller surface.
1181
+ * SyncEngine satisfies this interface at runtime; types live in different packages.
1182
+ */
1183
+ declare function asRichTextSyncEngine(engine: unknown): RichTextSyncEngine | null;
1184
+
1043
1185
  type RichtextInput = string | Uint8Array | ArrayBuffer | null | undefined;
1044
1186
  /**
1045
1187
  * Encodes richtext values into Yjs document updates.
@@ -1145,4 +1287,4 @@ declare function readAuditExportManifest(data: Uint8Array): AuditExportManifest;
1145
1287
  */
1146
1288
  declare function verifyAuditExportChecksum(data: Uint8Array): Promise<boolean>;
1147
1289
 
1148
- export { AdapterError, ApplyRemoteOptions, type AuditExportManifest, type AuditExportOptions, type AuditExportPayload, type AuditExportProgress, type AuditTraceQuery, type BackupManifest, type BackupOptions, type BackupProgress, COMPACTION_BASELINE_META_KEY, type CollectionAccessor, CollectionRecord, type CompactionResult, type CompactionStrategy, InvalidStateTransitionError, LAST_ACKED_SERVER_VECTOR_META_KEY, LocalMutationHandler, MaterializedRowSnapshot, OrderByDirection, type PersistedAuditTrace, PersistenceError, QueryBuilder, QueryDescriptor, QueryError, RecordNotFoundError, type ReplaySnapshot, type RestoreOptions, type RestoreResult, SequenceManager, StorageAdapter, Store, StoreConfig, StoreNotOpenError, SubscriptionBloomFilter, SubscriptionCallback, SubscriptionManager, type SubscriptionManagerOptions, type SubscriptionStats, type TransactionCollectionAccessor, TransactionContext, type TransactionContextConfig, WhereClause, WorkerInitError, WorkerTimeoutError, collectOperationsAheadOfServer, compactOperationLog, computeAckCompactionWatermark, decodeAuditExport, decodeRichtext, deserializeVersionVectorFromMeta, encodeRichtext, exportBackup, mergeVersionVectors, persistedAuditTraceFromEvent, pluralize, readAuditExportManifest, readBackupManifest, restoreBackup, richtextStatesEqual, richtextToPlainText, serializeVersionVectorToMeta, singularize, validateStateTransition, validateUpdateStateMachine, verifyAuditExportChecksum, verifyBackupChecksum };
1290
+ export { AdapterError, ApplyRemoteOptions, type AuditExportManifest, type AuditExportOptions, type AuditExportPayload, type AuditExportProgress, type AuditTraceQuery, type BackupManifest, type BackupOptions, type BackupProgress, COMPACTION_BASELINE_META_KEY, type CollectionAccessor, CollectionRecord, type CompactionResult, type CompactionStrategy, type CreateRichTextControllerOptions, InvalidStateTransitionError, LAST_ACKED_SERVER_VECTOR_META_KEY, LocalMutationHandler, MaterializedRowSnapshot, OrderByDirection, type PersistedAuditTrace, PersistenceError, QueryBuilder, QueryDescriptor, QueryError, QueryStore, QueryStoreCache, RecordNotFoundError, type ReplaySnapshot, type RestoreOptions, type RestoreResult, type RichTextAwarenessUser, type RichTextController, type RichTextControllerSnapshot, type RichTextCursorInfo, type RichTextSyncEngine, SequenceManager, StorageAdapter, Store, StoreConfig, StoreNotOpenError, SubscriptionBloomFilter, SubscriptionCallback, SubscriptionManager, type SubscriptionManagerOptions, type SubscriptionStats, type TransactionCollectionAccessor, TransactionContext, type TransactionContextConfig, WhereClause, WorkerInitError, WorkerTimeoutError, asRichTextSyncEngine, assertQueryReady, collectOperationsAheadOfServer, compactOperationLog, computeAckCompactionWatermark, createRichTextController, decodeAuditExport, decodeRichtext, deserializeVersionVectorFromMeta, encodeRichtext, exportBackup, getSharedQueryStoreCache, mergeVersionVectors, persistedAuditTraceFromEvent, pluralize, readAuditExportManifest, readBackupManifest, restoreBackup, richtextStatesEqual, richtextToPlainText, serializeVersionVectorToMeta, singularize, validateStateTransition, validateUpdateStateMachine, verifyAuditExportChecksum, verifyBackupChecksum };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { Operation, KoraError, VersionVector, SchemaDefinition, MergeTrace, Coll
4
4
  export { ApplyResult } from '@korajs/core';
5
5
  import { R as RelationEnforcer, L as LocalMutationContext } from './types-BMyHmwvn.js';
6
6
  export { C as Collection } from './types-BMyHmwvn.js';
7
+ import * as yjs from 'yjs';
7
8
 
8
9
  /**
9
10
  * In-memory materialized state at a causal cut in the operation log.
@@ -896,6 +897,62 @@ interface CollectionAccessor {
896
897
  where(conditions: Record<string, unknown>): QueryBuilder;
897
898
  }
898
899
 
900
+ /**
901
+ * Bridges the async QueryBuilder.subscribe() API with synchronous snapshot reads
902
+ * required by React useSyncExternalStore, Vue composables, and Svelte stores.
903
+ *
904
+ * Uses lazy subscription: the underlying query subscription starts when the first
905
+ * listener attaches and stops when the last listener detaches.
906
+ */
907
+ declare class QueryStore<T = CollectionRecord> {
908
+ private snapshot;
909
+ private listeners;
910
+ private unsubscribeQuery;
911
+ private active;
912
+ private readonly queryBuilder;
913
+ constructor(queryBuilder: QueryBuilder<T>);
914
+ /**
915
+ * Subscribe to snapshot changes.
916
+ *
917
+ * @returns Unsubscribe function
918
+ */
919
+ subscribe: (onStoreChange: () => void) => (() => void);
920
+ /** Synchronous read of the latest query results. */
921
+ getSnapshot: () => readonly T[];
922
+ /** Tear down listeners and the underlying query subscription. */
923
+ destroy(): void;
924
+ private startSubscription;
925
+ private stopSubscription;
926
+ private notifyListeners;
927
+ }
928
+
929
+ /**
930
+ * Ensures a query builder is backed by an open store (not a legacy pending placeholder).
931
+ */
932
+ declare function assertQueryReady(query: QueryBuilder<unknown>): void;
933
+
934
+ /**
935
+ * Reference-counted cache of {@link QueryStore} instances keyed by query descriptor.
936
+ * Identical queries from different components share one underlying subscription.
937
+ */
938
+ declare class QueryStoreCache {
939
+ private readonly scopeKey;
940
+ private entries;
941
+ constructor(scopeKey?: string);
942
+ getOrCreate<T>(queryBuilder: QueryBuilder<T>): QueryStore<T>;
943
+ release(queryBuilder: QueryBuilder<unknown>): void;
944
+ clear(): void;
945
+ get size(): number;
946
+ private getKey;
947
+ }
948
+ /**
949
+ * Process-wide shared query store cache for framework bindings.
950
+ *
951
+ * @deprecated Prefer {@link KoraApp.getQueryStoreCache} via `KoraProvider` context
952
+ * so each app instance owns an isolated cache.
953
+ */
954
+ declare function getSharedQueryStoreCache(): QueryStoreCache;
955
+
899
956
  /**
900
957
  * Bloom filter for subscription dependency tracking.
901
958
  *
@@ -1040,6 +1097,91 @@ declare function validateStateTransition(collectionName: string, recordId: strin
1040
1097
  */
1041
1098
  declare function validateUpdateStateMachine(collectionName: string, recordId: string, collectionDef: CollectionDefinition, currentRecord: Record<string, unknown>, updateData: Record<string, unknown>): Record<string, unknown>;
1042
1099
 
1100
+ /** User identity for collaborative cursor presence. */
1101
+ interface RichTextAwarenessUser {
1102
+ name: string;
1103
+ color: string;
1104
+ avatar?: string;
1105
+ }
1106
+ /** Remote collaborator cursor for a richtext field. */
1107
+ interface RichTextCursorInfo {
1108
+ clientId: number;
1109
+ userName: string;
1110
+ color: string;
1111
+ anchor: number;
1112
+ head: number;
1113
+ }
1114
+ /** Minimal sync surface required for richtext collaboration. */
1115
+ interface RichTextSyncEngine {
1116
+ getRichtextDocChannel?(): RichTextDocChannel;
1117
+ getAwarenessManager(): RichTextAwarenessManager;
1118
+ }
1119
+ interface RichTextDocChannel {
1120
+ shouldUseChannel(snapshotBytes: number, useDocChannel?: boolean): boolean;
1121
+ send(collection: string, recordId: string, field: string, update: Uint8Array): void;
1122
+ subscribe(collection: string, recordId: string, field: string, listener: (update: Uint8Array) => void): () => void;
1123
+ }
1124
+ interface RichTextAwarenessManager {
1125
+ clientId: number;
1126
+ getLocalState(): RichTextAwarenessState | null;
1127
+ setLocalState(state: RichTextAwarenessState): void;
1128
+ getStates(): Map<number, RichTextAwarenessState>;
1129
+ on(event: 'change', listener: () => void): () => void;
1130
+ }
1131
+ interface RichTextAwarenessState {
1132
+ user: RichTextAwarenessUser;
1133
+ cursor?: {
1134
+ collection: string;
1135
+ recordId: string;
1136
+ field: string;
1137
+ anchor: number;
1138
+ head: number;
1139
+ };
1140
+ }
1141
+ interface CreateRichTextControllerOptions {
1142
+ collection: CollectionAccessor;
1143
+ collectionName: string;
1144
+ recordId: string;
1145
+ fieldName: string;
1146
+ store: {
1147
+ collection(name: string): CollectionAccessor;
1148
+ };
1149
+ syncEngine?: RichTextSyncEngine | null;
1150
+ useDocChannel?: boolean;
1151
+ user?: RichTextAwarenessUser;
1152
+ }
1153
+ interface RichTextControllerSnapshot {
1154
+ ready: boolean;
1155
+ error: Error | null;
1156
+ canUndo: boolean;
1157
+ canRedo: boolean;
1158
+ cursors: readonly RichTextCursorInfo[];
1159
+ }
1160
+ interface RichTextController {
1161
+ readonly doc: yjs.Doc;
1162
+ readonly text: yjs.Text;
1163
+ getSnapshot(): RichTextControllerSnapshot;
1164
+ subscribe(listener: () => void): () => void;
1165
+ undo(): void;
1166
+ redo(): void;
1167
+ setCursor(anchor: number, head: number): void;
1168
+ clearCursor(): void;
1169
+ setUser(user: RichTextAwarenessUser | undefined): void;
1170
+ destroy(): void;
1171
+ }
1172
+
1173
+ /**
1174
+ * Framework-agnostic richtext binding: Yjs document lifecycle, persistence,
1175
+ * incremental doc channel, and awareness cursors.
1176
+ */
1177
+ declare function createRichTextController(options: CreateRichTextControllerOptions): RichTextController;
1178
+
1179
+ /**
1180
+ * Narrows a sync engine reference to the richtext controller surface.
1181
+ * SyncEngine satisfies this interface at runtime; types live in different packages.
1182
+ */
1183
+ declare function asRichTextSyncEngine(engine: unknown): RichTextSyncEngine | null;
1184
+
1043
1185
  type RichtextInput = string | Uint8Array | ArrayBuffer | null | undefined;
1044
1186
  /**
1045
1187
  * Encodes richtext values into Yjs document updates.
@@ -1145,4 +1287,4 @@ declare function readAuditExportManifest(data: Uint8Array): AuditExportManifest;
1145
1287
  */
1146
1288
  declare function verifyAuditExportChecksum(data: Uint8Array): Promise<boolean>;
1147
1289
 
1148
- export { AdapterError, ApplyRemoteOptions, type AuditExportManifest, type AuditExportOptions, type AuditExportPayload, type AuditExportProgress, type AuditTraceQuery, type BackupManifest, type BackupOptions, type BackupProgress, COMPACTION_BASELINE_META_KEY, type CollectionAccessor, CollectionRecord, type CompactionResult, type CompactionStrategy, InvalidStateTransitionError, LAST_ACKED_SERVER_VECTOR_META_KEY, LocalMutationHandler, MaterializedRowSnapshot, OrderByDirection, type PersistedAuditTrace, PersistenceError, QueryBuilder, QueryDescriptor, QueryError, RecordNotFoundError, type ReplaySnapshot, type RestoreOptions, type RestoreResult, SequenceManager, StorageAdapter, Store, StoreConfig, StoreNotOpenError, SubscriptionBloomFilter, SubscriptionCallback, SubscriptionManager, type SubscriptionManagerOptions, type SubscriptionStats, type TransactionCollectionAccessor, TransactionContext, type TransactionContextConfig, WhereClause, WorkerInitError, WorkerTimeoutError, collectOperationsAheadOfServer, compactOperationLog, computeAckCompactionWatermark, decodeAuditExport, decodeRichtext, deserializeVersionVectorFromMeta, encodeRichtext, exportBackup, mergeVersionVectors, persistedAuditTraceFromEvent, pluralize, readAuditExportManifest, readBackupManifest, restoreBackup, richtextStatesEqual, richtextToPlainText, serializeVersionVectorToMeta, singularize, validateStateTransition, validateUpdateStateMachine, verifyAuditExportChecksum, verifyBackupChecksum };
1290
+ export { AdapterError, ApplyRemoteOptions, type AuditExportManifest, type AuditExportOptions, type AuditExportPayload, type AuditExportProgress, type AuditTraceQuery, type BackupManifest, type BackupOptions, type BackupProgress, COMPACTION_BASELINE_META_KEY, type CollectionAccessor, CollectionRecord, type CompactionResult, type CompactionStrategy, type CreateRichTextControllerOptions, InvalidStateTransitionError, LAST_ACKED_SERVER_VECTOR_META_KEY, LocalMutationHandler, MaterializedRowSnapshot, OrderByDirection, type PersistedAuditTrace, PersistenceError, QueryBuilder, QueryDescriptor, QueryError, QueryStore, QueryStoreCache, RecordNotFoundError, type ReplaySnapshot, type RestoreOptions, type RestoreResult, type RichTextAwarenessUser, type RichTextController, type RichTextControllerSnapshot, type RichTextCursorInfo, type RichTextSyncEngine, SequenceManager, StorageAdapter, Store, StoreConfig, StoreNotOpenError, SubscriptionBloomFilter, SubscriptionCallback, SubscriptionManager, type SubscriptionManagerOptions, type SubscriptionStats, type TransactionCollectionAccessor, TransactionContext, type TransactionContextConfig, WhereClause, WorkerInitError, WorkerTimeoutError, asRichTextSyncEngine, assertQueryReady, collectOperationsAheadOfServer, compactOperationLog, computeAckCompactionWatermark, createRichTextController, decodeAuditExport, decodeRichtext, deserializeVersionVectorFromMeta, encodeRichtext, exportBackup, getSharedQueryStoreCache, mergeVersionVectors, persistedAuditTraceFromEvent, pluralize, readAuditExportManifest, readBackupManifest, restoreBackup, richtextStatesEqual, richtextToPlainText, serializeVersionVectorToMeta, singularize, validateStateTransition, validateUpdateStateMachine, verifyAuditExportChecksum, verifyBackupChecksum };