@framers/sql-storage-adapter 0.7.2 → 0.7.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.
Files changed (184) hide show
  1. package/README.md +20 -0
  2. package/dist/adapters/electron/preload.cjs +289 -0
  3. package/dist/adapters/electron/renderer.d.ts +9 -0
  4. package/dist/adapters/electron/renderer.d.ts.map +1 -0
  5. package/dist/adapters/electron/renderer.js +8 -0
  6. package/dist/adapters/electron/renderer.js.map +1 -0
  7. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
  8. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
  9. package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
  10. package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
  11. package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
  12. package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
  13. package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
  14. package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
  15. package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
  16. package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
  17. package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
  18. package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
  19. package/dist/cjs/adapters/electron/index.d.ts +74 -0
  20. package/dist/cjs/adapters/electron/index.js +86 -0
  21. package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
  22. package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
  23. package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
  24. package/dist/cjs/adapters/electron/ipc/index.js +38 -0
  25. package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
  26. package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
  27. package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
  28. package/dist/cjs/adapters/electron/ipc/types.js +15 -0
  29. package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
  30. package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
  31. package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
  32. package/dist/cjs/adapters/electron/migration/index.js +29 -0
  33. package/dist/cjs/adapters/electron/preload.d.ts +126 -0
  34. package/dist/cjs/adapters/electron/preload.js +233 -0
  35. package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
  36. package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
  37. package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
  38. package/dist/cjs/adapters/electron/recovery/index.js +34 -0
  39. package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
  40. package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
  41. package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
  42. package/dist/cjs/adapters/electron/renderer.js +33 -0
  43. package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
  44. package/dist/cjs/adapters/electron/window/index.js +29 -0
  45. package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
  46. package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
  47. package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
  48. package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
  49. package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
  50. package/dist/cjs/adapters/postgresAdapter.js +889 -0
  51. package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
  52. package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
  53. package/dist/cjs/adapters/supabase.d.ts +58 -0
  54. package/dist/cjs/adapters/supabase.js +401 -0
  55. package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
  56. package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
  57. package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
  58. package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
  59. package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
  60. package/dist/cjs/core/contracts/blobCodec.js +15 -0
  61. package/dist/cjs/core/contracts/context.d.ts +221 -0
  62. package/dist/cjs/core/contracts/context.js +15 -0
  63. package/dist/cjs/core/contracts/dialect.d.ts +154 -0
  64. package/dist/cjs/core/contracts/dialect.js +15 -0
  65. package/dist/cjs/core/contracts/events.d.ts +225 -0
  66. package/dist/cjs/core/contracts/events.js +15 -0
  67. package/dist/cjs/core/contracts/exporter.d.ts +13 -0
  68. package/dist/cjs/core/contracts/exporter.js +15 -0
  69. package/dist/cjs/core/contracts/extensions.d.ts +73 -0
  70. package/dist/cjs/core/contracts/extensions.js +15 -0
  71. package/dist/cjs/core/contracts/features.d.ts +25 -0
  72. package/dist/cjs/core/contracts/features.js +61 -0
  73. package/dist/cjs/core/contracts/fts.d.ts +66 -0
  74. package/dist/cjs/core/contracts/fts.js +15 -0
  75. package/dist/cjs/core/contracts/hooks.d.ts +481 -0
  76. package/dist/cjs/core/contracts/hooks.js +140 -0
  77. package/dist/cjs/core/contracts/index.d.ts +260 -0
  78. package/dist/cjs/core/contracts/index.js +41 -0
  79. package/dist/cjs/core/contracts/limitations.d.ts +46 -0
  80. package/dist/cjs/core/contracts/limitations.js +218 -0
  81. package/dist/cjs/core/contracts/performance.d.ts +308 -0
  82. package/dist/cjs/core/contracts/performance.js +144 -0
  83. package/dist/cjs/core/database.d.ts +220 -0
  84. package/dist/cjs/core/database.js +136 -0
  85. package/dist/cjs/core/portable.d.ts +23 -0
  86. package/dist/cjs/core/portable.js +66 -0
  87. package/dist/cjs/core/resolver.d.ts +77 -0
  88. package/dist/cjs/core/resolver.js +235 -0
  89. package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
  90. package/dist/cjs/dialects/PostgresDialect.js +143 -0
  91. package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
  92. package/dist/cjs/dialects/SqliteDialect.js +142 -0
  93. package/dist/cjs/dialects/shared.d.ts +17 -0
  94. package/dist/cjs/dialects/shared.js +90 -0
  95. package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
  96. package/dist/cjs/exporters/PostgresExporter.js +61 -0
  97. package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
  98. package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
  99. package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
  100. package/dist/cjs/features/backup/cloudBackup.js +209 -0
  101. package/dist/cjs/features/kv/idb.d.ts +79 -0
  102. package/dist/cjs/features/kv/idb.js +32 -0
  103. package/dist/cjs/features/kv/index.d.ts +14 -0
  104. package/dist/cjs/features/kv/index.js +40 -0
  105. package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
  106. package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
  107. package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
  108. package/dist/cjs/features/kv/keyValueStore.js +67 -0
  109. package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
  110. package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
  111. package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
  112. package/dist/cjs/features/kv/valueCodec.js +426 -0
  113. package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
  114. package/dist/cjs/features/migrations/dataExport.js +194 -0
  115. package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
  116. package/dist/cjs/features/migrations/dataImport.js +300 -0
  117. package/dist/cjs/features/migrations/migration.d.ts +89 -0
  118. package/dist/cjs/features/migrations/migration.js +187 -0
  119. package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
  120. package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
  121. package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
  122. package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
  123. package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
  124. package/dist/cjs/features/sync/conflicts/index.js +21 -0
  125. package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
  126. package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
  127. package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
  128. package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
  129. package/dist/cjs/features/sync/devices/index.d.ts +10 -0
  130. package/dist/cjs/features/sync/devices/index.js +21 -0
  131. package/dist/cjs/features/sync/index.d.ts +37 -0
  132. package/dist/cjs/features/sync/index.js +111 -0
  133. package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
  134. package/dist/cjs/features/sync/protocol/index.js +23 -0
  135. package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
  136. package/dist/cjs/features/sync/protocol/messages.js +215 -0
  137. package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
  138. package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
  139. package/dist/cjs/features/sync/syncManager.d.ts +348 -0
  140. package/dist/cjs/features/sync/syncManager.js +455 -0
  141. package/dist/cjs/features/sync/tables/index.d.ts +10 -0
  142. package/dist/cjs/features/sync/tables/index.js +21 -0
  143. package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
  144. package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
  145. package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
  146. package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
  147. package/dist/cjs/features/sync/transport/index.d.ts +12 -0
  148. package/dist/cjs/features/sync/transport/index.js +25 -0
  149. package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
  150. package/dist/cjs/features/sync/transport/transport.js +163 -0
  151. package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
  152. package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
  153. package/dist/cjs/fts/PostgresFts.d.ts +29 -0
  154. package/dist/cjs/fts/PostgresFts.js +77 -0
  155. package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
  156. package/dist/cjs/fts/SqliteFts5.js +58 -0
  157. package/dist/cjs/index.d.ts +30 -0
  158. package/dist/cjs/index.js +101 -0
  159. package/dist/cjs/package.json +3 -0
  160. package/dist/cjs/shared/connectionGate.d.ts +94 -0
  161. package/dist/cjs/shared/connectionGate.js +77 -0
  162. package/dist/cjs/shared/errors.d.ts +23 -0
  163. package/dist/cjs/shared/errors.js +45 -0
  164. package/dist/cjs/shared/logger.d.ts +26 -0
  165. package/dist/cjs/shared/logger.js +40 -0
  166. package/dist/cjs/shared/parameterUtils.d.ts +16 -0
  167. package/dist/cjs/shared/parameterUtils.js +59 -0
  168. package/dist/cjs/shared/postgresTarget.d.ts +11 -0
  169. package/dist/cjs/shared/postgresTarget.js +30 -0
  170. package/dist/cjs/shared/segment.d.ts +43 -0
  171. package/dist/cjs/shared/segment.js +63 -0
  172. package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
  173. package/dist/cjs/shared/serializedTransaction.js +74 -0
  174. package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
  175. package/dist/cjs/shared/splitSqlStatements.js +163 -0
  176. package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
  177. package/dist/cjs/shared/sqlPlaceholders.js +263 -0
  178. package/dist/cjs/types/index.d.ts +29 -0
  179. package/dist/cjs/types/index.js +33 -0
  180. package/dist/core/portable.d.ts +23 -0
  181. package/dist/core/portable.d.ts.map +1 -0
  182. package/dist/core/portable.js +23 -0
  183. package/dist/core/portable.js.map +1 -0
  184. package/package.json +139 -24
@@ -0,0 +1,346 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var httpTransport_exports = {};
19
+ __export(httpTransport_exports, {
20
+ HttpTransport: () => HttpTransport,
21
+ createHttpTransport: () => createHttpTransport
22
+ });
23
+ module.exports = __toCommonJS(httpTransport_exports);
24
+ var import_transport = require("./transport.js");
25
+ var import_messages = require("../protocol/messages.js");
26
+ class HttpTransport extends import_transport.BaseTransport {
27
+ constructor(options) {
28
+ super(options);
29
+ this.type = "http";
30
+ this._pollTimer = null;
31
+ this._abortController = null;
32
+ this._isPolling = false;
33
+ this._lastEventId = null;
34
+ this._messageQueue = [];
35
+ this._flushTimer = null;
36
+ this._pendingRequests = /* @__PURE__ */ new Map();
37
+ this._httpOptions = {
38
+ ...this._options,
39
+ pollingInterval: options.pollingInterval ?? 5e3,
40
+ maxMessagesPerPoll: options.maxMessagesPerPoll ?? 100,
41
+ longPolling: options.longPolling ?? true,
42
+ longPollTimeout: options.longPollTimeout ?? 3e4,
43
+ fetchImplementation: options.fetchImplementation ?? globalThis.fetch?.bind(globalThis)
44
+ };
45
+ }
46
+ /**
47
+ * Connect (start polling).
48
+ */
49
+ async connect() {
50
+ this.checkDisposed();
51
+ if (this._state === "connected" || this._state === "connecting") {
52
+ return;
53
+ }
54
+ this.setState("connecting");
55
+ try {
56
+ await this._syncCheck();
57
+ this.setState("connected");
58
+ this._stats.connectedAt = Date.now();
59
+ this.emit("connected", { timestamp: Date.now() });
60
+ this._startPolling();
61
+ } catch (error) {
62
+ this.setState("error");
63
+ throw error;
64
+ }
65
+ }
66
+ /**
67
+ * Disconnect (stop polling).
68
+ */
69
+ async disconnect(reason = "client disconnect") {
70
+ this._stopPolling();
71
+ this._clearPendingRequests(new import_transport.TransportError(reason, import_transport.TransportErrorCodes.DISPOSED, { recoverable: false }));
72
+ this.setState("disconnected");
73
+ this.emit("disconnected", { reason, wasClean: true });
74
+ }
75
+ /**
76
+ * Send a sync message.
77
+ */
78
+ async send(message) {
79
+ this.checkDisposed();
80
+ if (this._state !== "connected") {
81
+ throw new import_transport.TransportError("Not connected", import_transport.TransportErrorCodes.SEND_FAILED, { recoverable: true });
82
+ }
83
+ this._messageQueue.push(message);
84
+ this._scheduleFlush();
85
+ }
86
+ /**
87
+ * Send a message and wait for a response.
88
+ */
89
+ async request(message, timeout) {
90
+ this.checkDisposed();
91
+ const requestId = message.messageId;
92
+ const timeoutMs = timeout ?? this._options.requestTimeout;
93
+ return new Promise((resolve, reject) => {
94
+ const timer = setTimeout(() => {
95
+ this._pendingRequests.delete(requestId);
96
+ reject(new import_transport.TransportError("Request timed out", import_transport.TransportErrorCodes.REQUEST_TIMEOUT, { recoverable: true }));
97
+ }, timeoutMs);
98
+ this._pendingRequests.set(requestId, { resolve, reject, timer });
99
+ this.send(message).catch((error) => {
100
+ clearTimeout(timer);
101
+ this._pendingRequests.delete(requestId);
102
+ reject(error);
103
+ });
104
+ });
105
+ }
106
+ /**
107
+ * Perform initial sync check to verify connectivity.
108
+ */
109
+ async _syncCheck() {
110
+ const url = `${this._options.endpoint}/check`;
111
+ try {
112
+ const response = await this._fetch(url, {
113
+ method: "GET",
114
+ timeout: this._options.connectionTimeout
115
+ });
116
+ if (!response.ok) {
117
+ throw new import_transport.TransportError(`Sync check failed: ${response.status}`, response.status === 401 || response.status === 403 ? import_transport.TransportErrorCodes.AUTH_FAILED : import_transport.TransportErrorCodes.SERVER_ERROR, { recoverable: response.status >= 500 });
118
+ }
119
+ } catch (error) {
120
+ if (error instanceof import_transport.TransportError)
121
+ throw error;
122
+ throw new import_transport.TransportError("Connection failed", import_transport.TransportErrorCodes.CONNECTION_FAILED, { recoverable: true, cause: error });
123
+ }
124
+ }
125
+ /**
126
+ * Start the polling loop.
127
+ */
128
+ _startPolling() {
129
+ if (this._isPolling)
130
+ return;
131
+ this._isPolling = true;
132
+ this._poll();
133
+ }
134
+ /**
135
+ * Stop the polling loop.
136
+ */
137
+ _stopPolling() {
138
+ this._isPolling = false;
139
+ if (this._pollTimer) {
140
+ clearTimeout(this._pollTimer);
141
+ this._pollTimer = null;
142
+ }
143
+ if (this._abortController) {
144
+ this._abortController.abort();
145
+ this._abortController = null;
146
+ }
147
+ if (this._flushTimer) {
148
+ clearTimeout(this._flushTimer);
149
+ this._flushTimer = null;
150
+ }
151
+ }
152
+ /**
153
+ * Poll for new messages.
154
+ */
155
+ async _poll() {
156
+ if (!this._isPolling || this._disposed)
157
+ return;
158
+ this._abortController = new AbortController();
159
+ try {
160
+ const messages = await this._fetchMessages();
161
+ for (const message of messages) {
162
+ this._handleMessage(message);
163
+ }
164
+ this._pollTimer = setTimeout(() => this._poll(), this._httpOptions.pollingInterval);
165
+ } catch (error) {
166
+ if (error.name === "AbortError") {
167
+ return;
168
+ }
169
+ console.warn("[HttpTransport] Poll error:", error);
170
+ this.emit("error", {
171
+ error,
172
+ recoverable: true
173
+ });
174
+ if (this._isPolling && this._options.autoReconnect) {
175
+ this._stats.reconnectAttempts++;
176
+ const delay = this.calculateReconnectDelay(this._stats.reconnectAttempts);
177
+ this.emit("reconnecting", {
178
+ attempt: this._stats.reconnectAttempts,
179
+ delay
180
+ });
181
+ this._pollTimer = setTimeout(() => this._poll(), delay);
182
+ } else {
183
+ this.setState("error");
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * Fetch messages from server.
189
+ */
190
+ async _fetchMessages() {
191
+ const url = new URL(`${this._options.endpoint}/poll`);
192
+ if (this._lastEventId) {
193
+ url.searchParams.set("lastEventId", this._lastEventId);
194
+ }
195
+ url.searchParams.set("limit", String(this._httpOptions.maxMessagesPerPoll));
196
+ if (this._httpOptions.longPolling) {
197
+ url.searchParams.set("timeout", String(this._httpOptions.longPollTimeout));
198
+ }
199
+ const response = await this._fetch(url.toString(), {
200
+ method: "GET",
201
+ timeout: this._httpOptions.longPolling ? this._httpOptions.longPollTimeout + 5e3 : this._options.requestTimeout,
202
+ signal: this._abortController?.signal
203
+ });
204
+ if (!response.ok) {
205
+ throw new import_transport.TransportError(`Poll failed: ${response.status}`, import_transport.TransportErrorCodes.SERVER_ERROR, { recoverable: response.status >= 500 });
206
+ }
207
+ const data = await response.json();
208
+ if (data.lastEventId) {
209
+ this._lastEventId = data.lastEventId;
210
+ }
211
+ const messages = [];
212
+ for (const msg of data.messages) {
213
+ if ((0, import_messages.isSyncMessage)(msg)) {
214
+ messages.push(msg);
215
+ this._stats.messagesReceived++;
216
+ }
217
+ }
218
+ return messages;
219
+ }
220
+ /**
221
+ * Handle an incoming message.
222
+ */
223
+ _handleMessage(message) {
224
+ if ("inResponseTo" in message && message.inResponseTo) {
225
+ const pending = this._pendingRequests.get(message.inResponseTo);
226
+ if (pending) {
227
+ clearTimeout(pending.timer);
228
+ this._pendingRequests.delete(message.inResponseTo);
229
+ pending.resolve(message);
230
+ return;
231
+ }
232
+ }
233
+ if (message.type === "ack") {
234
+ const pending = this._pendingRequests.get(message.ackMessageId);
235
+ if (pending) {
236
+ clearTimeout(pending.timer);
237
+ this._pendingRequests.delete(message.ackMessageId);
238
+ pending.resolve(message);
239
+ }
240
+ return;
241
+ }
242
+ this.emit("message", { message, receivedAt: Date.now() });
243
+ }
244
+ /**
245
+ * Schedule message queue flush.
246
+ */
247
+ _scheduleFlush() {
248
+ if (this._flushTimer)
249
+ return;
250
+ this._flushTimer = setTimeout(() => {
251
+ this._flushTimer = null;
252
+ this._flushQueue().catch((error) => {
253
+ console.error("[HttpTransport] Flush error:", error);
254
+ });
255
+ }, 50);
256
+ }
257
+ /**
258
+ * Flush the message queue to server.
259
+ */
260
+ async _flushQueue() {
261
+ if (this._messageQueue.length === 0)
262
+ return;
263
+ const messages = this._messageQueue.splice(0, 100);
264
+ try {
265
+ const response = await this._fetch(`${this._options.endpoint}/push`, {
266
+ method: "POST",
267
+ body: JSON.stringify({ messages }),
268
+ timeout: this._options.requestTimeout
269
+ });
270
+ if (!response.ok) {
271
+ this._messageQueue.unshift(...messages);
272
+ throw new import_transport.TransportError(`Push failed: ${response.status}`, import_transport.TransportErrorCodes.SEND_FAILED, { recoverable: response.status >= 500 });
273
+ }
274
+ this._stats.messagesSent += messages.length;
275
+ const data = await response.json();
276
+ if (data.responses) {
277
+ for (const resp of data.responses) {
278
+ if ((0, import_messages.isSyncMessage)(resp)) {
279
+ this._handleMessage(resp);
280
+ }
281
+ }
282
+ }
283
+ if (this._messageQueue.length > 0) {
284
+ this._scheduleFlush();
285
+ }
286
+ } catch (error) {
287
+ if (error instanceof import_transport.TransportError)
288
+ throw error;
289
+ this._messageQueue.unshift(...messages);
290
+ throw new import_transport.TransportError("Failed to send messages", import_transport.TransportErrorCodes.SEND_FAILED, { recoverable: true, cause: error });
291
+ }
292
+ }
293
+ /**
294
+ * Make an HTTP request.
295
+ */
296
+ async _fetch(url, options) {
297
+ const fetchFn = this._httpOptions.fetchImplementation;
298
+ if (!fetchFn) {
299
+ throw new import_transport.TransportError("Fetch not available", import_transport.TransportErrorCodes.NETWORK_ERROR, { recoverable: false });
300
+ }
301
+ const headers = {
302
+ "Content-Type": "application/json",
303
+ ...this._options.headers
304
+ };
305
+ if (this._options.authToken) {
306
+ headers["Authorization"] = `Bearer ${this._options.authToken}`;
307
+ }
308
+ let timeoutId;
309
+ let abortController;
310
+ if (options.timeout && !options.signal) {
311
+ abortController = new AbortController();
312
+ timeoutId = setTimeout(() => abortController.abort(), options.timeout);
313
+ }
314
+ try {
315
+ const response = await fetchFn(url, {
316
+ method: options.method,
317
+ headers,
318
+ body: options.body,
319
+ signal: options.signal ?? abortController?.signal
320
+ });
321
+ return response;
322
+ } finally {
323
+ if (timeoutId) {
324
+ clearTimeout(timeoutId);
325
+ }
326
+ }
327
+ }
328
+ /**
329
+ * Clear all pending requests.
330
+ */
331
+ _clearPendingRequests(error) {
332
+ for (const [id, pending] of this._pendingRequests) {
333
+ clearTimeout(pending.timer);
334
+ pending.reject(error);
335
+ }
336
+ this._pendingRequests.clear();
337
+ }
338
+ }
339
+ const createHttpTransport = (options) => {
340
+ return new HttpTransport(options);
341
+ };
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ HttpTransport,
345
+ createHttpTransport
346
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Sync Transport Module.
3
+ *
4
+ * Provides transport layer abstractions for sync communication.
5
+ * Includes WebSocket (real-time) and HTTP (polling fallback) transports.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export * from './transport.js';
10
+ export * from './websocketTransport.js';
11
+ export * from './httpTransport.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,25 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var transport_exports = {};
16
+ module.exports = __toCommonJS(transport_exports);
17
+ __reExport(transport_exports, require("./transport.js"), module.exports);
18
+ __reExport(transport_exports, require("./websocketTransport.js"), module.exports);
19
+ __reExport(transport_exports, require("./httpTransport.js"), module.exports);
20
+ // Annotate the CommonJS export names for ESM import in node:
21
+ 0 && (module.exports = {
22
+ ...require("./transport.js"),
23
+ ...require("./websocketTransport.js"),
24
+ ...require("./httpTransport.js")
25
+ });
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Transport Layer Interface.
3
+ *
4
+ * Defines the contract for sync transports (WebSocket, HTTP polling, etc.).
5
+ * Transports handle the low-level communication between sync nodes.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { SyncMessage } from '../protocol/messages.js';
10
+ /**
11
+ * Transport connection state.
12
+ */
13
+ export type TransportState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
14
+ /**
15
+ * Transport configuration options.
16
+ */
17
+ export interface TransportOptions {
18
+ /** Server endpoint URL */
19
+ endpoint: string;
20
+ /** Authentication token or API key */
21
+ authToken?: string;
22
+ /** Custom headers for HTTP requests */
23
+ headers?: Record<string, string>;
24
+ /** Connection timeout in milliseconds */
25
+ connectionTimeout?: number;
26
+ /** Request timeout in milliseconds */
27
+ requestTimeout?: number;
28
+ /** Enable automatic reconnection */
29
+ autoReconnect?: boolean;
30
+ /** Initial reconnection delay in milliseconds */
31
+ reconnectDelay?: number;
32
+ /** Maximum reconnection delay in milliseconds */
33
+ maxReconnectDelay?: number;
34
+ /** Maximum reconnection attempts (0 = unlimited) */
35
+ maxReconnectAttempts?: number;
36
+ /** Heartbeat interval in milliseconds (0 = disabled) */
37
+ heartbeatInterval?: number;
38
+ /** Enable message compression */
39
+ compression?: boolean;
40
+ }
41
+ /**
42
+ * Transport event types.
43
+ */
44
+ export type TransportEventType = 'connected' | 'disconnected' | 'message' | 'error' | 'reconnecting' | 'stateChange';
45
+ /**
46
+ * Transport event payloads.
47
+ */
48
+ export interface TransportEvents {
49
+ connected: {
50
+ timestamp: number;
51
+ };
52
+ disconnected: {
53
+ reason: string;
54
+ wasClean: boolean;
55
+ };
56
+ message: {
57
+ message: SyncMessage;
58
+ receivedAt: number;
59
+ };
60
+ error: {
61
+ error: Error;
62
+ recoverable: boolean;
63
+ };
64
+ reconnecting: {
65
+ attempt: number;
66
+ delay: number;
67
+ };
68
+ stateChange: {
69
+ previousState: TransportState;
70
+ currentState: TransportState;
71
+ };
72
+ }
73
+ /**
74
+ * Transport event listener.
75
+ */
76
+ export type TransportEventListener<T extends TransportEventType> = (event: TransportEvents[T]) => void;
77
+ /**
78
+ * Transport statistics.
79
+ */
80
+ export interface TransportStats {
81
+ /** Current connection state */
82
+ state: TransportState;
83
+ /** Time when connection was established (epoch ms) */
84
+ connectedAt?: number;
85
+ /** Total messages sent */
86
+ messagesSent: number;
87
+ /** Total messages received */
88
+ messagesReceived: number;
89
+ /** Total bytes sent */
90
+ bytesSent: number;
91
+ /** Total bytes received */
92
+ bytesReceived: number;
93
+ /** Number of reconnection attempts */
94
+ reconnectAttempts: number;
95
+ /** Average round-trip latency in milliseconds */
96
+ averageLatency?: number;
97
+ /** Last error encountered */
98
+ lastError?: Error;
99
+ }
100
+ /**
101
+ * Transport interface for sync communication.
102
+ *
103
+ * Implementations handle the actual network communication,
104
+ * allowing the sync engine to be transport-agnostic.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const transport = new WebSocketTransport({
109
+ * endpoint: 'wss://sync.example.com',
110
+ * authToken: 'bearer-token',
111
+ * autoReconnect: true,
112
+ * });
113
+ *
114
+ * transport.on('message', ({ message }) => {
115
+ * console.log('Received:', message);
116
+ * });
117
+ *
118
+ * await transport.connect();
119
+ * await transport.send(handshakeMessage);
120
+ * ```
121
+ */
122
+ export interface SyncTransport {
123
+ /** Transport type identifier */
124
+ readonly type: 'websocket' | 'http' | 'custom';
125
+ /** Current connection state */
126
+ readonly state: TransportState;
127
+ /** Whether the transport is currently connected */
128
+ readonly isConnected: boolean;
129
+ /**
130
+ * Connect to the sync server.
131
+ *
132
+ * @throws {TransportError} If connection fails
133
+ */
134
+ connect(): Promise<void>;
135
+ /**
136
+ * Disconnect from the sync server.
137
+ *
138
+ * @param reason - Optional disconnect reason
139
+ */
140
+ disconnect(reason?: string): Promise<void>;
141
+ /**
142
+ * Send a message to the sync server.
143
+ *
144
+ * @param message - The sync message to send
145
+ * @returns Promise that resolves when message is sent
146
+ * @throws {TransportError} If send fails
147
+ */
148
+ send(message: SyncMessage): Promise<void>;
149
+ /**
150
+ * Send a message and wait for a response.
151
+ *
152
+ * @param message - The sync message to send
153
+ * @param timeout - Optional response timeout in milliseconds
154
+ * @returns Promise that resolves with the response message
155
+ * @throws {TransportError} If send fails or times out
156
+ */
157
+ request(message: SyncMessage, timeout?: number): Promise<SyncMessage>;
158
+ /**
159
+ * Register an event listener.
160
+ *
161
+ * @param event - Event type to listen for
162
+ * @param listener - Callback function
163
+ * @returns Unsubscribe function
164
+ */
165
+ on<T extends TransportEventType>(event: T, listener: TransportEventListener<T>): () => void;
166
+ /**
167
+ * Register a one-time event listener.
168
+ *
169
+ * @param event - Event type to listen for
170
+ * @param listener - Callback function
171
+ * @returns Unsubscribe function
172
+ */
173
+ once<T extends TransportEventType>(event: T, listener: TransportEventListener<T>): () => void;
174
+ /**
175
+ * Get transport statistics.
176
+ */
177
+ getStats(): TransportStats;
178
+ /**
179
+ * Dispose of the transport and release resources.
180
+ */
181
+ dispose(): Promise<void>;
182
+ }
183
+ /**
184
+ * Transport error with additional context.
185
+ */
186
+ export declare class TransportError extends Error {
187
+ /** Error code for categorization */
188
+ readonly code: string;
189
+ /** Whether the error is recoverable */
190
+ readonly recoverable: boolean;
191
+ /** Original error if wrapping another error */
192
+ readonly cause?: Error;
193
+ constructor(message: string, code: string, options?: {
194
+ recoverable?: boolean;
195
+ cause?: Error;
196
+ });
197
+ }
198
+ /**
199
+ * Common transport error codes.
200
+ */
201
+ export declare const TransportErrorCodes: {
202
+ /** Connection failed */
203
+ readonly CONNECTION_FAILED: "CONNECTION_FAILED";
204
+ /** Connection timeout */
205
+ readonly CONNECTION_TIMEOUT: "CONNECTION_TIMEOUT";
206
+ /** Authentication failed */
207
+ readonly AUTH_FAILED: "AUTH_FAILED";
208
+ /** Request timeout */
209
+ readonly REQUEST_TIMEOUT: "REQUEST_TIMEOUT";
210
+ /** Send failed */
211
+ readonly SEND_FAILED: "SEND_FAILED";
212
+ /** Server error */
213
+ readonly SERVER_ERROR: "SERVER_ERROR";
214
+ /** Network error */
215
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
216
+ /** Protocol error */
217
+ readonly PROTOCOL_ERROR: "PROTOCOL_ERROR";
218
+ /** Transport disposed */
219
+ readonly DISPOSED: "DISPOSED";
220
+ };
221
+ /**
222
+ * Base transport implementation with common functionality.
223
+ */
224
+ export declare abstract class BaseTransport implements SyncTransport {
225
+ abstract readonly type: 'websocket' | 'http' | 'custom';
226
+ protected _state: TransportState;
227
+ protected _stats: TransportStats;
228
+ protected _options: Required<TransportOptions>;
229
+ protected _disposed: boolean;
230
+ private _listeners;
231
+ constructor(options: TransportOptions);
232
+ get state(): TransportState;
233
+ get isConnected(): boolean;
234
+ abstract connect(): Promise<void>;
235
+ abstract disconnect(reason?: string): Promise<void>;
236
+ abstract send(message: SyncMessage): Promise<void>;
237
+ abstract request(message: SyncMessage, timeout?: number): Promise<SyncMessage>;
238
+ on<T extends TransportEventType>(event: T, listener: TransportEventListener<T>): () => void;
239
+ once<T extends TransportEventType>(event: T, listener: TransportEventListener<T>): () => void;
240
+ getStats(): TransportStats;
241
+ dispose(): Promise<void>;
242
+ /**
243
+ * Emit an event to all registered listeners.
244
+ */
245
+ protected emit<T extends TransportEventType>(event: T, data: TransportEvents[T]): void;
246
+ /**
247
+ * Update transport state and emit event.
248
+ */
249
+ protected setState(newState: TransportState): void;
250
+ /**
251
+ * Check if transport is disposed and throw if so.
252
+ */
253
+ protected checkDisposed(): void;
254
+ /**
255
+ * Calculate next reconnection delay with exponential backoff.
256
+ */
257
+ protected calculateReconnectDelay(attempt: number): number;
258
+ }
259
+ //# sourceMappingURL=transport.d.ts.map