@syncular/core 0.1.3 → 0.2.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.
Files changed (231) hide show
  1. package/README.md +5 -19
  2. package/dist/blob-ref.d.ts +21 -0
  3. package/dist/blob-ref.js +97 -0
  4. package/dist/bytes.d.ts +45 -0
  5. package/dist/bytes.js +242 -0
  6. package/dist/canonical-json.d.ts +10 -0
  7. package/dist/canonical-json.js +18 -0
  8. package/dist/constants.d.ts +5 -0
  9. package/dist/constants.js +5 -0
  10. package/dist/crypto.d.ts +60 -0
  11. package/dist/crypto.js +251 -0
  12. package/dist/errors.d.ts +14 -0
  13. package/dist/errors.js +17 -0
  14. package/dist/frames.d.ts +24 -0
  15. package/dist/frames.js +42 -0
  16. package/dist/index.d.ts +18 -26
  17. package/dist/index.js +18 -43
  18. package/dist/message.d.ts +157 -0
  19. package/dist/message.js +786 -0
  20. package/dist/realtime.d.ts +92 -0
  21. package/dist/realtime.js +222 -0
  22. package/dist/render.d.ts +22 -0
  23. package/dist/render.js +273 -0
  24. package/dist/row-codec.d.ts +39 -0
  25. package/dist/row-codec.js +176 -0
  26. package/dist/segment.d.ts +18 -0
  27. package/dist/segment.js +105 -0
  28. package/dist/stream.d.ts +20 -0
  29. package/dist/stream.js +102 -0
  30. package/package.json +7 -59
  31. package/src/blob-ref.ts +135 -0
  32. package/src/bytes.ts +301 -0
  33. package/src/canonical-json.ts +20 -0
  34. package/src/constants.ts +7 -0
  35. package/src/crypto.ts +335 -0
  36. package/src/errors.ts +18 -0
  37. package/src/frames.ts +47 -0
  38. package/src/index.ts +18 -43
  39. package/src/message.ts +1024 -0
  40. package/src/realtime.ts +340 -0
  41. package/src/render.ts +325 -0
  42. package/src/row-codec.ts +265 -0
  43. package/src/segment.ts +150 -0
  44. package/src/stream.ts +128 -0
  45. package/dist/blobs.d.ts +0 -153
  46. package/dist/blobs.d.ts.map +0 -1
  47. package/dist/blobs.js +0 -47
  48. package/dist/blobs.js.map +0 -1
  49. package/dist/column-codecs.d.ts +0 -59
  50. package/dist/column-codecs.d.ts.map +0 -1
  51. package/dist/column-codecs.js +0 -159
  52. package/dist/column-codecs.js.map +0 -1
  53. package/dist/conflict.d.ts +0 -22
  54. package/dist/conflict.d.ts.map +0 -1
  55. package/dist/conflict.js +0 -81
  56. package/dist/conflict.js.map +0 -1
  57. package/dist/database.d.ts +0 -7
  58. package/dist/database.d.ts.map +0 -1
  59. package/dist/database.js +0 -14
  60. package/dist/database.js.map +0 -1
  61. package/dist/dialect.d.ts +0 -7
  62. package/dist/dialect.d.ts.map +0 -1
  63. package/dist/dialect.js +0 -2
  64. package/dist/dialect.js.map +0 -1
  65. package/dist/error-responses.d.ts +0 -393
  66. package/dist/error-responses.d.ts.map +0 -1
  67. package/dist/error-responses.js +0 -393
  68. package/dist/error-responses.js.map +0 -1
  69. package/dist/http/api-client.d.ts +0 -11
  70. package/dist/http/api-client.d.ts.map +0 -1
  71. package/dist/http/api-client.js +0 -30
  72. package/dist/http/api-client.js.map +0 -1
  73. package/dist/http/blob.d.ts +0 -6
  74. package/dist/http/blob.d.ts.map +0 -1
  75. package/dist/http/blob.js +0 -46
  76. package/dist/http/blob.js.map +0 -1
  77. package/dist/http/generated/api.d.ts +0 -5241
  78. package/dist/http/generated/api.d.ts.map +0 -1
  79. package/dist/http/generated/api.js +0 -6
  80. package/dist/http/generated/api.js.map +0 -1
  81. package/dist/http/index.d.ts +0 -18
  82. package/dist/http/index.d.ts.map +0 -1
  83. package/dist/http/index.js +0 -212
  84. package/dist/http/index.js.map +0 -1
  85. package/dist/http/shared.d.ts +0 -45
  86. package/dist/http/shared.d.ts.map +0 -1
  87. package/dist/http/shared.js +0 -122
  88. package/dist/http/shared.js.map +0 -1
  89. package/dist/http/transport-client.d.ts +0 -31
  90. package/dist/http/transport-client.d.ts.map +0 -1
  91. package/dist/http/transport-client.js +0 -193
  92. package/dist/http/transport-client.js.map +0 -1
  93. package/dist/index.d.ts.map +0 -1
  94. package/dist/index.js.map +0 -1
  95. package/dist/kysely-column-codecs.d.ts +0 -31
  96. package/dist/kysely-column-codecs.d.ts.map +0 -1
  97. package/dist/kysely-column-codecs.js +0 -452
  98. package/dist/kysely-column-codecs.js.map +0 -1
  99. package/dist/logger.d.ts +0 -29
  100. package/dist/logger.d.ts.map +0 -1
  101. package/dist/logger.js +0 -26
  102. package/dist/logger.js.map +0 -1
  103. package/dist/proxy/index.d.ts +0 -54
  104. package/dist/proxy/index.d.ts.map +0 -1
  105. package/dist/proxy/index.js +0 -7
  106. package/dist/proxy/index.js.map +0 -1
  107. package/dist/schemas/blobs.d.ts +0 -82
  108. package/dist/schemas/blobs.d.ts.map +0 -1
  109. package/dist/schemas/blobs.js +0 -64
  110. package/dist/schemas/blobs.js.map +0 -1
  111. package/dist/schemas/common.d.ts +0 -100
  112. package/dist/schemas/common.d.ts.map +0 -1
  113. package/dist/schemas/common.js +0 -64
  114. package/dist/schemas/common.js.map +0 -1
  115. package/dist/schemas/index.d.ts +0 -7
  116. package/dist/schemas/index.d.ts.map +0 -1
  117. package/dist/schemas/index.js +0 -7
  118. package/dist/schemas/index.js.map +0 -1
  119. package/dist/schemas/sync.d.ts +0 -1065
  120. package/dist/schemas/sync.d.ts.map +0 -1
  121. package/dist/schemas/sync.js +0 -361
  122. package/dist/schemas/sync.js.map +0 -1
  123. package/dist/scopes/index.d.ts +0 -113
  124. package/dist/scopes/index.d.ts.map +0 -1
  125. package/dist/scopes/index.js +0 -103
  126. package/dist/scopes/index.js.map +0 -1
  127. package/dist/sentry.d.ts +0 -31
  128. package/dist/sentry.d.ts.map +0 -1
  129. package/dist/sentry.js +0 -147
  130. package/dist/sentry.js.map +0 -1
  131. package/dist/snapshot-chunks.d.ts +0 -110
  132. package/dist/snapshot-chunks.d.ts.map +0 -1
  133. package/dist/snapshot-chunks.js +0 -682
  134. package/dist/snapshot-chunks.js.map +0 -1
  135. package/dist/sync-packs.d.ts +0 -33
  136. package/dist/sync-packs.d.ts.map +0 -1
  137. package/dist/sync-packs.js +0 -821
  138. package/dist/sync-packs.js.map +0 -1
  139. package/dist/telemetry.d.ts +0 -114
  140. package/dist/telemetry.d.ts.map +0 -1
  141. package/dist/telemetry.js +0 -114
  142. package/dist/telemetry.js.map +0 -1
  143. package/dist/transforms.d.ts +0 -146
  144. package/dist/transforms.d.ts.map +0 -1
  145. package/dist/transforms.js +0 -155
  146. package/dist/transforms.js.map +0 -1
  147. package/dist/types.d.ts +0 -210
  148. package/dist/types.d.ts.map +0 -1
  149. package/dist/types.js +0 -20
  150. package/dist/types.js.map +0 -1
  151. package/dist/utils/bytes.d.ts +0 -4
  152. package/dist/utils/bytes.d.ts.map +0 -1
  153. package/dist/utils/bytes.js +0 -66
  154. package/dist/utils/bytes.js.map +0 -1
  155. package/dist/utils/compression.d.ts +0 -22
  156. package/dist/utils/compression.d.ts.map +0 -1
  157. package/dist/utils/compression.js +0 -129
  158. package/dist/utils/compression.js.map +0 -1
  159. package/dist/utils/crypto.d.ts +0 -13
  160. package/dist/utils/crypto.d.ts.map +0 -1
  161. package/dist/utils/crypto.js +0 -107
  162. package/dist/utils/crypto.js.map +0 -1
  163. package/dist/utils/id.d.ts +0 -3
  164. package/dist/utils/id.d.ts.map +0 -1
  165. package/dist/utils/id.js +0 -25
  166. package/dist/utils/id.js.map +0 -1
  167. package/dist/utils/index.d.ts +0 -10
  168. package/dist/utils/index.d.ts.map +0 -1
  169. package/dist/utils/index.js +0 -10
  170. package/dist/utils/index.js.map +0 -1
  171. package/dist/utils/internal-runtime.d.ts +0 -16
  172. package/dist/utils/internal-runtime.d.ts.map +0 -1
  173. package/dist/utils/internal-runtime.js +0 -14
  174. package/dist/utils/internal-runtime.js.map +0 -1
  175. package/dist/utils/object.d.ts +0 -2
  176. package/dist/utils/object.d.ts.map +0 -1
  177. package/dist/utils/object.js +0 -4
  178. package/dist/utils/object.js.map +0 -1
  179. package/dist/utils/realtime-change-index.d.ts +0 -9
  180. package/dist/utils/realtime-change-index.d.ts.map +0 -1
  181. package/dist/utils/realtime-change-index.js +0 -36
  182. package/dist/utils/realtime-change-index.js.map +0 -1
  183. package/dist/utils/realtime-connection-registry.d.ts +0 -40
  184. package/dist/utils/realtime-connection-registry.d.ts.map +0 -1
  185. package/dist/utils/realtime-connection-registry.js +0 -237
  186. package/dist/utils/realtime-connection-registry.js.map +0 -1
  187. package/dist/utils/table-registry.d.ts +0 -10
  188. package/dist/utils/table-registry.d.ts.map +0 -1
  189. package/dist/utils/table-registry.js +0 -54
  190. package/dist/utils/table-registry.js.map +0 -1
  191. package/dist/utils/url.d.ts +0 -3
  192. package/dist/utils/url.d.ts.map +0 -1
  193. package/dist/utils/url.js +0 -20
  194. package/dist/utils/url.js.map +0 -1
  195. package/src/blobs.ts +0 -219
  196. package/src/column-codecs.ts +0 -262
  197. package/src/conflict.ts +0 -92
  198. package/src/database.ts +0 -21
  199. package/src/dialect.ts +0 -8
  200. package/src/error-responses.ts +0 -423
  201. package/src/http/api-client.ts +0 -39
  202. package/src/http/blob.ts +0 -95
  203. package/src/http/generated/api.ts +0 -5241
  204. package/src/http/index.ts +0 -365
  205. package/src/http/shared.ts +0 -220
  206. package/src/http/transport-client.ts +0 -314
  207. package/src/kysely-column-codecs.ts +0 -585
  208. package/src/logger.ts +0 -38
  209. package/src/proxy/index.ts +0 -57
  210. package/src/schemas/blobs.ts +0 -110
  211. package/src/schemas/common.ts +0 -89
  212. package/src/schemas/index.ts +0 -7
  213. package/src/schemas/sync.ts +0 -517
  214. package/src/scopes/index.ts +0 -237
  215. package/src/sentry.ts +0 -200
  216. package/src/snapshot-chunks.ts +0 -964
  217. package/src/sync-packs.ts +0 -1096
  218. package/src/telemetry.ts +0 -243
  219. package/src/transforms.ts +0 -256
  220. package/src/types.ts +0 -267
  221. package/src/utils/bytes.ts +0 -75
  222. package/src/utils/compression.ts +0 -187
  223. package/src/utils/crypto.ts +0 -146
  224. package/src/utils/id.ts +0 -34
  225. package/src/utils/index.ts +0 -9
  226. package/src/utils/internal-runtime.ts +0 -39
  227. package/src/utils/object.ts +0 -3
  228. package/src/utils/realtime-change-index.ts +0 -44
  229. package/src/utils/realtime-connection-registry.ts +0 -286
  230. package/src/utils/table-registry.ts +0 -67
  231. package/src/utils/url.ts +0 -29
@@ -1,314 +0,0 @@
1
- import type {
2
- SyncAuthErrorContext,
3
- SyncAuthLifecycle,
4
- SyncCombinedRequest,
5
- SyncCombinedResponse,
6
- } from '@syncular/core';
7
- import {
8
- decodeBinarySyncPack,
9
- isBinarySyncPackContentType,
10
- } from '@syncular/core';
11
- import type { SyncClient } from './api-client';
12
- import {
13
- type ApiResult,
14
- type ClientOptions,
15
- encodeSnapshotScopes,
16
- type ResolveAuthRetry,
17
- resolveRequestUrl,
18
- SNAPSHOT_SCOPES_HEADER,
19
- } from './shared';
20
-
21
- export type { ClientOptions };
22
-
23
- export const HTTP_TRANSPORT_SOURCE = Symbol.for('@syncular/core/http/source');
24
-
25
- export type HttpTransportSource = SyncClient | ClientOptions;
26
-
27
- function isApiClientLike(value: unknown): value is SyncClient {
28
- return (
29
- typeof value === 'object' &&
30
- value !== null &&
31
- typeof (value as SyncClient).GET === 'function' &&
32
- typeof (value as SyncClient).POST === 'function'
33
- );
34
- }
35
-
36
- interface TransportApiClient {
37
- sync(
38
- request: SyncCombinedRequest,
39
- signal?: AbortSignal
40
- ): Promise<ApiResult<SyncCombinedResponse>>;
41
- initiateUpload(
42
- args: { hash: string; size: number; mimeType: string },
43
- signal?: AbortSignal
44
- ): Promise<
45
- ApiResult<{
46
- exists: boolean;
47
- uploadUrl?: string;
48
- uploadMethod?: 'PUT' | 'POST';
49
- uploadHeaders?: Record<string, string>;
50
- }>
51
- >;
52
- completeUpload(
53
- hash: string,
54
- signal?: AbortSignal
55
- ): Promise<ApiResult<{ ok: boolean; error?: string }>>;
56
- getDownloadUrl(
57
- hash: string,
58
- signal?: AbortSignal
59
- ): Promise<ApiResult<{ url: string; expiresAt: string }>>;
60
- getSnapshotChunk(
61
- chunkId: string,
62
- scopeValues: Record<string, string | string[]> | undefined,
63
- signal?: AbortSignal
64
- ): Promise<ApiResult<Blob>>;
65
- }
66
-
67
- function isJsonContentType(contentType: string | null): boolean {
68
- return contentType?.includes('application/json') === true;
69
- }
70
-
71
- async function parseErrorBody(response: Response): Promise<unknown> {
72
- if (!isJsonContentType(response.headers.get('content-type'))) {
73
- return undefined;
74
- }
75
- try {
76
- return (await response.json()) as unknown;
77
- } catch {
78
- return undefined;
79
- }
80
- }
81
-
82
- async function parseJsonBody<T>(response: Response): Promise<T | undefined> {
83
- if (!isJsonContentType(response.headers.get('content-type'))) {
84
- return undefined;
85
- }
86
- try {
87
- return (await response.json()) as T;
88
- } catch {
89
- return undefined;
90
- }
91
- }
92
-
93
- function createAuthRetryResolver(
94
- defaultAuthLifecycle: SyncAuthLifecycle | undefined
95
- ): ResolveAuthRetry {
96
- let refreshInFlight: Promise<boolean> | null = null;
97
-
98
- const runRefreshSingleFlight = async (
99
- lifecycle: SyncAuthLifecycle,
100
- context: SyncAuthErrorContext
101
- ): Promise<boolean> => {
102
- if (!lifecycle.refreshToken) return false;
103
-
104
- if (!refreshInFlight) {
105
- refreshInFlight = Promise.resolve(lifecycle.refreshToken(context))
106
- .then((result) => Boolean(result))
107
- .finally(() => {
108
- refreshInFlight = null;
109
- });
110
- }
111
-
112
- return refreshInFlight;
113
- };
114
-
115
- return async (context, options) => {
116
- const lifecycle = options?.authLifecycle ?? defaultAuthLifecycle;
117
- if (!lifecycle) return false;
118
-
119
- await lifecycle.onAuthExpired?.(context);
120
-
121
- const refreshResult = await runRefreshSingleFlight(lifecycle, context);
122
- if (lifecycle.retryWithFreshToken) {
123
- return Boolean(
124
- await lifecycle.retryWithFreshToken({ ...context, refreshResult })
125
- );
126
- }
127
- return refreshResult;
128
- };
129
- }
130
-
131
- function createRequestHeaders(
132
- baseOptions: ClientOptions,
133
- extraHeaders?: Record<string, string>
134
- ): Promise<Headers> {
135
- return Promise.resolve(baseOptions.getHeaders?.()).then((dynamicHeaders) => {
136
- const headers = new Headers(extraHeaders);
137
- if (dynamicHeaders) {
138
- for (const [key, value] of Object.entries(dynamicHeaders)) {
139
- headers.set(key, value);
140
- }
141
- }
142
- if (!headers.has('x-syncular-transport-path')) {
143
- headers.set(
144
- 'x-syncular-transport-path',
145
- baseOptions.transportPath ?? 'direct'
146
- );
147
- }
148
- return headers;
149
- });
150
- }
151
-
152
- function createFetchApiClient(baseOptions: ClientOptions): TransportApiClient {
153
- const fetchImpl = baseOptions.fetch ?? globalThis.fetch;
154
-
155
- const request = async <T>(args: {
156
- method: 'GET' | 'POST';
157
- path: string;
158
- body?: unknown;
159
- headers?: Record<string, string>;
160
- signal?: AbortSignal;
161
- parseAs?: 'json' | 'blob';
162
- }): Promise<ApiResult<T>> => {
163
- const headers = await createRequestHeaders(baseOptions, args.headers);
164
- let body: BodyInit | undefined;
165
- if (args.body !== undefined) {
166
- headers.set('content-type', 'application/json');
167
- body = JSON.stringify(args.body);
168
- }
169
-
170
- const response = await fetchImpl(
171
- resolveRequestUrl(baseOptions.baseUrl, args.path),
172
- {
173
- method: args.method,
174
- headers,
175
- body,
176
- ...(args.signal ? { signal: args.signal } : {}),
177
- }
178
- );
179
-
180
- if (!response.ok) {
181
- return {
182
- response,
183
- error: await parseErrorBody(response),
184
- };
185
- }
186
-
187
- if (args.parseAs === 'blob') {
188
- return {
189
- response,
190
- data: (await response.blob()) as T,
191
- };
192
- }
193
-
194
- if (isBinarySyncPackContentType(response.headers.get('content-type'))) {
195
- return {
196
- response,
197
- data: decodeBinarySyncPack(
198
- new Uint8Array(await response.arrayBuffer())
199
- ) as T,
200
- };
201
- }
202
-
203
- return {
204
- response,
205
- data: await parseJsonBody<T>(response),
206
- };
207
- };
208
-
209
- return {
210
- sync: (requestBody, signal) =>
211
- request({
212
- method: 'POST',
213
- path: '/sync',
214
- body: requestBody,
215
- signal,
216
- }),
217
- initiateUpload: (args, signal) =>
218
- request({
219
- method: 'POST',
220
- path: '/sync/blobs/upload',
221
- body: args,
222
- signal,
223
- }),
224
- completeUpload: (hash, signal) =>
225
- request({
226
- method: 'POST',
227
- path: `/sync/blobs/${encodeURIComponent(hash)}/complete`,
228
- signal,
229
- }),
230
- getDownloadUrl: (hash, signal) =>
231
- request({
232
- method: 'GET',
233
- path: `/sync/blobs/${encodeURIComponent(hash)}/url`,
234
- signal,
235
- }),
236
- getSnapshotChunk: (chunkId, scopeValues, signal) =>
237
- request({
238
- method: 'GET',
239
- path: `/sync/snapshot-chunks/${encodeURIComponent(chunkId)}`,
240
- headers: (() => {
241
- const encodedScopes = encodeSnapshotScopes(scopeValues);
242
- return encodedScopes
243
- ? {
244
- [SNAPSHOT_SCOPES_HEADER]: encodedScopes,
245
- }
246
- : undefined;
247
- })(),
248
- signal,
249
- parseAs: 'blob',
250
- }),
251
- };
252
- }
253
-
254
- function createTypedTransportClient(client: SyncClient): TransportApiClient {
255
- return {
256
- sync: (request, signal) =>
257
- client.POST('/sync', {
258
- body: request,
259
- ...(signal ? { signal } : {}),
260
- }) as Promise<ApiResult<SyncCombinedResponse>>,
261
- initiateUpload: (args, signal) =>
262
- client.POST('/sync/blobs/upload', {
263
- body: args,
264
- ...(signal ? { signal } : {}),
265
- }) as Promise<
266
- ApiResult<{
267
- exists: boolean;
268
- uploadUrl?: string;
269
- uploadMethod?: 'PUT' | 'POST';
270
- uploadHeaders?: Record<string, string>;
271
- }>
272
- >,
273
- completeUpload: (hash, signal) =>
274
- client.POST('/sync/blobs/{hash}/complete', {
275
- params: { path: { hash } },
276
- ...(signal ? { signal } : {}),
277
- }) as Promise<ApiResult<{ ok: boolean; error?: string }>>,
278
- getDownloadUrl: (hash, signal) =>
279
- client.GET('/sync/blobs/{hash}/url', {
280
- params: { path: { hash } },
281
- ...(signal ? { signal } : {}),
282
- }) as Promise<ApiResult<{ url: string; expiresAt: string }>>,
283
- getSnapshotChunk: (chunkId, scopeValues, signal) =>
284
- client.GET('/sync/snapshot-chunks/{chunkId}', {
285
- params: { path: { chunkId } },
286
- parseAs: 'blob',
287
- headers: (() => {
288
- const encodedScopes = encodeSnapshotScopes(scopeValues);
289
- return encodedScopes
290
- ? {
291
- [SNAPSHOT_SCOPES_HEADER]: encodedScopes,
292
- }
293
- : undefined;
294
- })(),
295
- ...(signal ? { signal } : {}),
296
- }) as Promise<ApiResult<Blob>>,
297
- };
298
- }
299
-
300
- export function createTransportApiClient(
301
- source: HttpTransportSource
302
- ): TransportApiClient {
303
- return isApiClientLike(source)
304
- ? createTypedTransportClient(source)
305
- : createFetchApiClient(source);
306
- }
307
-
308
- export function createTransportAuthRetryResolver(
309
- source: HttpTransportSource
310
- ): ResolveAuthRetry {
311
- return createAuthRetryResolver(
312
- isApiClientLike(source) ? undefined : source.authLifecycle
313
- );
314
- }