@xnetjs/data-bridge 0.0.2 → 0.0.3

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.
@@ -1,2 +1,162 @@
1
+ import { D as DataWorkerAPI, a as WorkerConfig, S as SerializedQueryOptions, Q as QueryDelta, W as WorkerQuerySnapshot, b as WorkerAcquiredDoc, v as WorkerSubscription, B as BoundedQueryWorkingSet } from '../query-descriptor-D0k2gUQ0.js';
2
+ import { B as BridgeTransactionResult, S as SyncStatus } from '../types-BRvuTwEn.js';
3
+ import { NodeStore, NodeStorageAdapter, NodeState, NodeBatchWriteInput, NodeBatchWriteResult, TransactionOperation, NodeChangeEvent } from '@xnetjs/data';
4
+ import 'y-protocols/awareness';
5
+ import 'yjs';
1
6
 
2
- export { }
7
+ /**
8
+ * DataWorker host - the worker-resident data layer (exploration 0164)
9
+ *
10
+ * This class runs NodeStore, query subscriptions, and invalidation off the
11
+ * main thread. It is exposed via Comlink by `data-worker.ts`; tests
12
+ * instantiate it directly.
13
+ *
14
+ * Key responsibilities:
15
+ * - Initialize and manage NodeStore inside the worker
16
+ * - Handle query subscriptions and push per-query deltas to the main thread
17
+ * - Execute CRUD operations and atomic transactions
18
+ * - Manage Y.Doc pool for collaborative editing
19
+ * - Handle signing/verification (all crypto happens here)
20
+ *
21
+ * Invalidation mirrors MainThreadBridge's 0163 machinery:
22
+ * - Bounded working sets keep limited+ordered queries incremental
23
+ * - Batch change events hydrate touched nodes once instead of re-querying
24
+ * - Re-queries graft previous node references back in for unchanged rows
25
+ */
26
+
27
+ interface ActiveWorkerSubscription extends WorkerSubscription {
28
+ onDelta: (delta: QueryDelta) => void;
29
+ /** Overfetched prefix buffer for bounded (limit + orderBy) descriptors */
30
+ workingSet: BoundedQueryWorkingSet | null;
31
+ }
32
+ declare class DataWorker implements DataWorkerAPI {
33
+ protected store: NodeStore | null;
34
+ protected storage: NodeStorageAdapter | null;
35
+ private subscriptions;
36
+ private status;
37
+ private statusHandlers;
38
+ private changeFeedHandlers;
39
+ private storeUnsubscribe;
40
+ private storeBatchUnsubscribe;
41
+ private pendingStoreChanges;
42
+ private storeChangeFlushQueued;
43
+ private docPool;
44
+ private nextClientId;
45
+ initialize(config: WorkerConfig): Promise<void>;
46
+ /**
47
+ * Create the worker's storage adapter.
48
+ *
49
+ * With a forwarded `storagePort`, persistence goes through the existing
50
+ * SQLite worker via PortSQLiteAdapter (worker-to-worker, no main-thread
51
+ * hop). Without one, storage is in-memory.
52
+ */
53
+ protected createStorageAdapter(config: WorkerConfig): Promise<NodeStorageAdapter>;
54
+ subscribe(queryId: string, schemaId: string, options: SerializedQueryOptions, onDelta: (delta: QueryDelta) => void): Promise<WorkerQuerySnapshot>;
55
+ unsubscribe(queryId: string): Promise<void>;
56
+ reloadQuery(queryId: string): Promise<WorkerQuerySnapshot>;
57
+ /**
58
+ * Encode a snapshot for the wire. Binary payloads ride a freshly
59
+ * allocated buffer, so it is transferred (zero-copy) instead of cloned.
60
+ */
61
+ private toWireSnapshot;
62
+ create(schemaId: string, data: Record<string, unknown>, id?: string): Promise<NodeState>;
63
+ update(nodeId: string, changes: Record<string, unknown>): Promise<NodeState>;
64
+ delete(nodeId: string): Promise<void>;
65
+ restore(nodeId: string): Promise<NodeState>;
66
+ bulkWrite(input: NodeBatchWriteInput): Promise<NodeBatchWriteResult>;
67
+ transaction(operations: TransactionOperation[]): Promise<BridgeTransactionResult>;
68
+ get(nodeId: string): Promise<NodeState | null>;
69
+ acquireDoc(nodeId: string, onUpdate: (update: Uint8Array, origin: string) => void): Promise<WorkerAcquiredDoc>;
70
+ private acquireDocEntry;
71
+ private createDocEntry;
72
+ private handleDocUpdate;
73
+ private persistDocState;
74
+ private forwardRemoteDocUpdate;
75
+ private sendDocUpdate;
76
+ releaseDoc(nodeId: string): void;
77
+ applyLocalUpdate(nodeId: string, update: Uint8Array): void;
78
+ getStatus(): SyncStatus;
79
+ onStatusChange(handler: (status: SyncStatus) => void): void;
80
+ /**
81
+ * Subscribe to the worker's raw store change feed (devtools and other
82
+ * instrumentation). Events are structured-clone-safe NodeChangeEvents.
83
+ * The bridge registers a single forwarder and fans out locally, so the
84
+ * worker keeps at most one handler per bridge.
85
+ */
86
+ subscribeToChanges(handler: (event: NodeChangeEvent) => void): void;
87
+ private emitChangeFeedEvent;
88
+ destroy(): Promise<void>;
89
+ private detachStoreListeners;
90
+ private closeStorage;
91
+ /**
92
+ * Execute a subscription's query against storage. Bounded descriptors
93
+ * overfetch a small buffer so later node changes can be applied in
94
+ * memory, and re-queries graft previous node references back in wherever
95
+ * the snapshots are equivalent (so reference-based delta math and
96
+ * downstream identity caches keep working).
97
+ */
98
+ private loadQueryState;
99
+ private reloadSubscription;
100
+ private enqueueStoreChange;
101
+ private flushStoreChanges;
102
+ private isBulkStoreChangeSet;
103
+ private subscriptionsForSchema;
104
+ private handleStoreChangeSet;
105
+ /**
106
+ * Batch notifications carry node ids only. Small batches hydrate the
107
+ * touched nodes once and flow through the same delta path as regular
108
+ * change events; only genuinely bulk batches re-query each subscription.
109
+ */
110
+ private handleStoreBatchChange;
111
+ private reloadSubscriptionsForSchemas;
112
+ private applyStoreBatchChangeDeltas;
113
+ /**
114
+ * Apply a list of node changes to one subscription, falling back to a
115
+ * storage re-query only when a delta is ambiguous. Emits at most one
116
+ * wire delta per change.
117
+ */
118
+ protected applyChangesToSubscription(sub: ActiveWorkerSubscription, changes: ReadonlyArray<{
119
+ nodeId: string;
120
+ nextNode: NodeState | null;
121
+ }>, options?: {
122
+ onAmbiguous?: 'reload' | 'skip';
123
+ }): Promise<void>;
124
+ /**
125
+ * Apply one change to a subscription and emit its wire delta.
126
+ * Returns false when the change was ambiguous (the subscription was
127
+ * reloaded — or skipped — wholesale, so remaining changes are moot).
128
+ */
129
+ private applyChangeAndEmit;
130
+ private emitSubscriptionDelta;
131
+ /**
132
+ * Find the freshest cached snapshot of a node across all subscriptions.
133
+ */
134
+ private findCachedNode;
135
+ /**
136
+ * Synchronously apply an optimistic node mutation to every affected
137
+ * subscription before persistence, so the main thread sees the edit one
138
+ * postMessage later (~next microtask) instead of after storage commits.
139
+ * Ambiguous deltas are skipped, not reloaded — storage still holds the
140
+ * OLD state, and the durable change event that follows reconciles.
141
+ * Returns a revert function that re-queries authoritative state (used
142
+ * when persistence fails).
143
+ */
144
+ private applyOptimisticNodeChange;
145
+ private applyChangeToSubscriptionState;
146
+ private applyBoundedChange;
147
+ private applyUnboundedChange;
148
+ private setStatus;
149
+ /**
150
+ * Evict unused Y.Docs from the pool to manage memory.
151
+ * Only evicts docs with refCount=0 that haven't been accessed recently.
152
+ */
153
+ private evictOldDocs;
154
+ /**
155
+ * Find eviction candidates — docs with no refs and old enough — ordered
156
+ * oldest-accessed first.
157
+ */
158
+ private collectDocEvictionCandidates;
159
+ private evictDoc;
160
+ }
161
+
162
+ export { DataWorker };