@syncular/client 0.1.3 → 0.2.1
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/README.md +227 -709
- package/dist/apply.d.ts +80 -0
- package/dist/apply.js +301 -0
- package/dist/blob.d.ts +127 -0
- package/dist/blob.js +201 -0
- package/dist/bun-database.d.ts +22 -0
- package/dist/bun-database.js +61 -0
- package/dist/client.d.ts +320 -69
- package/dist/client.js +1627 -163
- package/dist/content-type.d.ts +2 -0
- package/dist/content-type.js +2 -0
- package/dist/database.d.ts +35 -80
- package/dist/database.js +32 -947
- package/dist/encryption.d.ts +47 -0
- package/dist/encryption.js +75 -0
- package/dist/errors.d.ts +8 -22
- package/dist/errors.js +10 -207
- package/dist/http.d.ts +32 -0
- package/dist/http.js +196 -0
- package/dist/index.d.ts +28 -16
- package/dist/index.js +25 -12
- package/dist/invalidation.d.ts +69 -0
- package/dist/invalidation.js +84 -0
- package/dist/leader-lock.d.ts +28 -0
- package/dist/leader-lock.js +38 -0
- package/dist/multi-tab.d.ts +134 -0
- package/dist/multi-tab.js +399 -0
- package/dist/node-database.d.ts +41 -0
- package/dist/node-database.js +133 -0
- package/dist/outbox.d.ts +56 -0
- package/dist/outbox.js +140 -0
- package/dist/schema.d.ts +107 -0
- package/dist/schema.js +267 -0
- package/dist/state.d.ts +40 -0
- package/dist/state.js +77 -0
- package/dist/transport.d.ts +44 -0
- package/dist/transport.js +7 -0
- package/dist/wasm-database.d.ts +30 -0
- package/dist/wasm-database.js +170 -0
- package/dist/window.d.ts +64 -0
- package/dist/window.js +0 -0
- package/dist/worker-entry.d.ts +16 -2
- package/dist/worker-entry.js +300 -456
- package/dist/worker-host.d.ts +174 -0
- package/dist/worker-host.js +536 -0
- package/dist/worker-protocol.d.ts +173 -61
- package/dist/worker-protocol.js +7 -16
- package/package.json +45 -112
- package/src/apply.ts +435 -0
- package/src/blob.ts +333 -0
- package/src/bun-database.ts +75 -0
- package/src/client.ts +2247 -277
- package/src/content-type.ts +2 -0
- package/src/database.ts +63 -1389
- package/src/encryption.ts +123 -0
- package/src/errors.ts +11 -265
- package/src/http.ts +254 -0
- package/src/index.ts +25 -20
- package/src/invalidation.ts +128 -0
- package/src/leader-lock.ts +68 -0
- package/src/multi-tab.ts +550 -0
- package/src/node-database.ts +180 -0
- package/src/outbox.ts +206 -0
- package/src/schema.ts +397 -0
- package/src/state.ts +126 -0
- package/src/transport.ts +52 -0
- package/src/wasm-database.ts +279 -0
- package/src/window.ts +0 -0
- package/src/worker-entry.ts +391 -545
- package/src/worker-host.ts +800 -0
- package/src/worker-protocol.ts +204 -99
- package/dist/auth-leases.d.ts +0 -11
- package/dist/auth-leases.d.ts.map +0 -1
- package/dist/auth-leases.js +0 -140
- package/dist/auth-leases.js.map +0 -1
- package/dist/blob-limits.d.ts +0 -15
- package/dist/blob-limits.d.ts.map +0 -1
- package/dist/blob-limits.js +0 -66
- package/dist/blob-limits.js.map +0 -1
- package/dist/bridge-client.d.ts +0 -69
- package/dist/bridge-client.d.ts.map +0 -1
- package/dist/bridge-client.js +0 -282
- package/dist/bridge-client.js.map +0 -1
- package/dist/client-config.d.ts +0 -6
- package/dist/client-config.d.ts.map +0 -1
- package/dist/client-config.js +0 -18
- package/dist/client-config.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/command-history.d.ts +0 -35
- package/dist/command-history.d.ts.map +0 -1
- package/dist/command-history.js +0 -378
- package/dist/command-history.js.map +0 -1
- package/dist/console-diagnostics.d.ts +0 -33
- package/dist/console-diagnostics.d.ts.map +0 -1
- package/dist/console-diagnostics.js +0 -496
- package/dist/console-diagnostics.js.map +0 -1
- package/dist/crdt-yjs/index.d.ts +0 -4
- package/dist/crdt-yjs/index.d.ts.map +0 -1
- package/dist/crdt-yjs/index.js +0 -4
- package/dist/crdt-yjs/index.js.map +0 -1
- package/dist/crdt-yjs/webview-host-facade.d.ts +0 -126
- package/dist/crdt-yjs/webview-host-facade.d.ts.map +0 -1
- package/dist/crdt-yjs/webview-host-facade.js +0 -284
- package/dist/crdt-yjs/webview-host-facade.js.map +0 -1
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts +0 -153
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts.map +0 -1
- package/dist/crdt-yjs/yjs-document-field-adapter.js +0 -406
- package/dist/crdt-yjs/yjs-document-field-adapter.js.map +0 -1
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts +0 -73
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts.map +0 -1
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js +0 -169
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js.map +0 -1
- package/dist/database.d.ts.map +0 -1
- package/dist/database.js.map +0 -1
- package/dist/diagnostics.d.ts +0 -10
- package/dist/diagnostics.d.ts.map +0 -1
- package/dist/diagnostics.js +0 -83
- package/dist/diagnostics.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/generated-bridge.d.ts +0 -365
- package/dist/generated-bridge.d.ts.map +0 -1
- package/dist/generated-bridge.js +0 -250
- package/dist/generated-bridge.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mutations.d.ts +0 -72
- package/dist/mutations.d.ts.map +0 -1
- package/dist/mutations.js +0 -63
- package/dist/mutations.js.map +0 -1
- package/dist/network.d.ts +0 -3
- package/dist/network.d.ts.map +0 -1
- package/dist/network.js +0 -17
- package/dist/network.js.map +0 -1
- package/dist/react/index.d.ts +0 -169
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js +0 -628
- package/dist/react/index.js.map +0 -1
- package/dist/react-native/index.d.ts +0 -35
- package/dist/react-native/index.d.ts.map +0 -1
- package/dist/react-native/index.js +0 -49
- package/dist/react-native/index.js.map +0 -1
- package/dist/runtime-contract.d.ts +0 -13
- package/dist/runtime-contract.d.ts.map +0 -1
- package/dist/runtime-contract.js +0 -24
- package/dist/runtime-contract.js.map +0 -1
- package/dist/rust-client.d.ts +0 -106
- package/dist/rust-client.d.ts.map +0 -1
- package/dist/rust-client.js +0 -938
- package/dist/rust-client.js.map +0 -1
- package/dist/sentry.d.ts +0 -35
- package/dist/sentry.d.ts.map +0 -1
- package/dist/sentry.js +0 -155
- package/dist/sentry.js.map +0 -1
- package/dist/sql-safety.d.ts +0 -3
- package/dist/sql-safety.d.ts.map +0 -1
- package/dist/sql-safety.js +0 -62
- package/dist/sql-safety.js.map +0 -1
- package/dist/syncular-runtime-artifacts.json +0 -61
- package/dist/tauri/index.d.ts +0 -35
- package/dist/tauri/index.d.ts.map +0 -1
- package/dist/tauri/index.js +0 -114
- package/dist/tauri/index.js.map +0 -1
- package/dist/types.d.ts +0 -1096
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/wasm/.syncular-wasm-profile +0 -1
- package/dist/wasm/syncular-runtime-artifact.json +0 -21
- package/dist/wasm/syncular.d.ts +0 -207
- package/dist/wasm/syncular.js +0 -2341
- package/dist/wasm/syncular_bg.wasm +0 -0
- package/dist/wasm/syncular_bg.wasm.d.ts +0 -97
- package/dist/wasm-bindings/runtime-contract.d.ts +0 -22
- package/dist/wasm-bindings/runtime-contract.d.ts.map +0 -1
- package/dist/wasm-bindings/runtime-contract.js +0 -112
- package/dist/wasm-bindings/runtime-contract.js.map +0 -1
- package/dist/wasm-core/.syncular-wasm-profile +0 -1
- package/dist/wasm-core/syncular-runtime-artifact.json +0 -17
- package/dist/wasm-core/syncular.d.ts +0 -162
- package/dist/wasm-core/syncular.js +0 -1847
- package/dist/wasm-core/syncular_bg.wasm +0 -0
- package/dist/wasm-core/syncular_bg.wasm.d.ts +0 -77
- package/dist/wasm-perf/.syncular-wasm-profile +0 -1
- package/dist/wasm-perf/syncular-runtime-artifact.json +0 -21
- package/dist/wasm-perf/syncular.d.ts +0 -207
- package/dist/wasm-perf/syncular.js +0 -2341
- package/dist/wasm-perf/syncular_bg.wasm +0 -0
- package/dist/wasm-perf/syncular_bg.wasm.d.ts +0 -97
- package/dist/wasm-runtime.d.ts +0 -23
- package/dist/wasm-runtime.d.ts.map +0 -1
- package/dist/wasm-runtime.js +0 -69
- package/dist/wasm-runtime.js.map +0 -1
- package/dist/worker-client.d.ts +0 -123
- package/dist/worker-client.d.ts.map +0 -1
- package/dist/worker-client.js +0 -1735
- package/dist/worker-client.js.map +0 -1
- package/dist/worker-entry.d.ts.map +0 -1
- package/dist/worker-entry.js.map +0 -1
- package/dist/worker-protocol.d.ts.map +0 -1
- package/dist/worker-protocol.js.map +0 -1
- package/dist/worker-realtime.d.ts +0 -39
- package/dist/worker-realtime.d.ts.map +0 -1
- package/dist/worker-realtime.js +0 -677
- package/dist/worker-realtime.js.map +0 -1
- package/src/auth-leases.ts +0 -251
- package/src/blob-limits.ts +0 -98
- package/src/bridge-client.ts +0 -512
- package/src/client-config.ts +0 -29
- package/src/command-history.ts +0 -623
- package/src/console-diagnostics.ts +0 -617
- package/src/crdt-yjs/index.ts +0 -3
- package/src/crdt-yjs/webview-host-facade.ts +0 -477
- package/src/crdt-yjs/yjs-document-field-adapter.ts +0 -733
- package/src/crdt-yjs/yjs-prosemirror-bridge.ts +0 -272
- package/src/diagnostics.ts +0 -116
- package/src/generated-bridge.ts +0 -741
- package/src/mutations.ts +0 -168
- package/src/network.ts +0 -32
- package/src/react/index.ts +0 -1036
- package/src/react-native/index.ts +0 -152
- package/src/runtime-contract.ts +0 -48
- package/src/rust-client.ts +0 -1491
- package/src/sentry.ts +0 -215
- package/src/sql-safety.ts +0 -61
- package/src/tauri/index.ts +0 -211
- package/src/types.ts +0 -1397
- package/src/wasm-bindings/generated-wasm-bindings.d.ts +0 -70
- package/src/wasm-bindings/runtime-contract.ts +0 -158
- package/src/wasm-runtime.ts +0 -145
- package/src/worker-client.ts +0 -2289
- package/src/worker-realtime.ts +0 -843
package/src/sentry.ts
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import * as Sentry from '@sentry/react';
|
|
2
|
-
import {
|
|
3
|
-
configureSyncTelemetry,
|
|
4
|
-
type SyncMetricOptions,
|
|
5
|
-
type SyncTelemetry,
|
|
6
|
-
type SyncTelemetryAttributeValue,
|
|
7
|
-
} from '@syncular/core';
|
|
8
|
-
import { createSentrySyncTelemetry } from '@syncular/core/sentry';
|
|
9
|
-
|
|
10
|
-
export type BrowserSentryInitOptions = Parameters<typeof Sentry.init>[0];
|
|
11
|
-
export type BrowserSentryCaptureMessageLevel = Parameters<
|
|
12
|
-
typeof Sentry.captureMessage
|
|
13
|
-
>[1];
|
|
14
|
-
|
|
15
|
-
interface BrowserSentryCaptureMessageOptions {
|
|
16
|
-
level?: BrowserSentryCaptureMessageLevel;
|
|
17
|
-
tags?: Record<string, string>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type BrowserSentryLogLevel =
|
|
21
|
-
| 'trace'
|
|
22
|
-
| 'debug'
|
|
23
|
-
| 'info'
|
|
24
|
-
| 'warn'
|
|
25
|
-
| 'error'
|
|
26
|
-
| 'fatal';
|
|
27
|
-
|
|
28
|
-
interface BrowserSentryLogOptions {
|
|
29
|
-
level?: BrowserSentryLogLevel;
|
|
30
|
-
attributes?: Record<string, SyncTelemetryAttributeValue>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function resolveBrowserLogMethod(
|
|
34
|
-
level: BrowserSentryLogLevel
|
|
35
|
-
):
|
|
36
|
-
| ((
|
|
37
|
-
message: string,
|
|
38
|
-
attributes?: Record<string, SyncTelemetryAttributeValue>
|
|
39
|
-
) => void)
|
|
40
|
-
| null {
|
|
41
|
-
switch (level) {
|
|
42
|
-
case 'trace':
|
|
43
|
-
return Sentry.logger.trace ?? Sentry.logger.debug ?? Sentry.logger.info;
|
|
44
|
-
case 'debug':
|
|
45
|
-
return Sentry.logger.debug ?? Sentry.logger.info;
|
|
46
|
-
case 'info':
|
|
47
|
-
return Sentry.logger.info;
|
|
48
|
-
case 'warn':
|
|
49
|
-
return Sentry.logger.warn ?? Sentry.logger.info;
|
|
50
|
-
case 'error':
|
|
51
|
-
return Sentry.logger.error ?? Sentry.logger.warn ?? Sentry.logger.info;
|
|
52
|
-
case 'fatal':
|
|
53
|
-
return (
|
|
54
|
-
Sentry.logger.fatal ??
|
|
55
|
-
Sentry.logger.error ??
|
|
56
|
-
Sentry.logger.warn ??
|
|
57
|
-
Sentry.logger.info
|
|
58
|
-
);
|
|
59
|
-
default:
|
|
60
|
-
return Sentry.logger.info;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function toCountMetricOptions(
|
|
65
|
-
options?: SyncMetricOptions
|
|
66
|
-
): Parameters<typeof Sentry.metrics.count>[2] | undefined {
|
|
67
|
-
if (!options?.attributes) return undefined;
|
|
68
|
-
return { attributes: options.attributes };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function toValueMetricOptions(
|
|
72
|
-
options?: SyncMetricOptions
|
|
73
|
-
): Parameters<typeof Sentry.metrics.gauge>[2] | undefined {
|
|
74
|
-
if (!options) return undefined;
|
|
75
|
-
const hasAttributes = Boolean(options.attributes);
|
|
76
|
-
const hasUnit = Boolean(options.unit);
|
|
77
|
-
if (!hasAttributes && !hasUnit) return undefined;
|
|
78
|
-
return {
|
|
79
|
-
attributes: options.attributes,
|
|
80
|
-
unit: options.unit,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Create a Syncular telemetry backend wired to `@sentry/react`.
|
|
86
|
-
*/
|
|
87
|
-
export function createBrowserSentryTelemetry(): SyncTelemetry {
|
|
88
|
-
return createSentrySyncTelemetry({
|
|
89
|
-
logger: Sentry.logger,
|
|
90
|
-
startSpan(options, callback) {
|
|
91
|
-
return Sentry.startSpan(options, (span) =>
|
|
92
|
-
callback({
|
|
93
|
-
setAttribute(name, value) {
|
|
94
|
-
span.setAttribute(name, value);
|
|
95
|
-
},
|
|
96
|
-
setAttributes(attributes) {
|
|
97
|
-
span.setAttributes(attributes);
|
|
98
|
-
},
|
|
99
|
-
setStatus(status) {
|
|
100
|
-
span.setStatus({
|
|
101
|
-
code: status === 'ok' ? 1 : 2,
|
|
102
|
-
});
|
|
103
|
-
},
|
|
104
|
-
})
|
|
105
|
-
);
|
|
106
|
-
},
|
|
107
|
-
metrics: {
|
|
108
|
-
count(name, value, options) {
|
|
109
|
-
const metricOptions = toCountMetricOptions(options);
|
|
110
|
-
if (metricOptions) {
|
|
111
|
-
Sentry.metrics.count(name, value, metricOptions);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
Sentry.metrics.count(name, value);
|
|
115
|
-
},
|
|
116
|
-
gauge(name, value, options) {
|
|
117
|
-
const metricOptions = toValueMetricOptions(options);
|
|
118
|
-
if (metricOptions) {
|
|
119
|
-
Sentry.metrics.gauge(name, value, metricOptions);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
Sentry.metrics.gauge(name, value);
|
|
123
|
-
},
|
|
124
|
-
distribution(name, value, options) {
|
|
125
|
-
const metricOptions = toValueMetricOptions(options);
|
|
126
|
-
if (metricOptions) {
|
|
127
|
-
Sentry.metrics.distribution(name, value, metricOptions);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
Sentry.metrics.distribution(name, value);
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
captureException(error) {
|
|
134
|
-
Sentry.captureException(error);
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Configure Syncular core telemetry to use the browser Sentry adapter.
|
|
141
|
-
*/
|
|
142
|
-
export function configureBrowserSentryTelemetry(): SyncTelemetry {
|
|
143
|
-
const telemetry = createBrowserSentryTelemetry();
|
|
144
|
-
configureSyncTelemetry(telemetry);
|
|
145
|
-
return telemetry;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Initialize browser Sentry and configure Syncular telemetry.
|
|
150
|
-
*/
|
|
151
|
-
export function initAndConfigureBrowserSentry(
|
|
152
|
-
options: BrowserSentryInitOptions
|
|
153
|
-
): SyncTelemetry {
|
|
154
|
-
const configuredOptions = ensureBrowserTracingIntegration(options);
|
|
155
|
-
Sentry.init(configuredOptions);
|
|
156
|
-
return configureBrowserSentryTelemetry();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function ensureBrowserTracingIntegration(
|
|
160
|
-
options: BrowserSentryInitOptions
|
|
161
|
-
): BrowserSentryInitOptions {
|
|
162
|
-
const integrations = options.integrations;
|
|
163
|
-
if (typeof integrations === 'function') return options;
|
|
164
|
-
|
|
165
|
-
const configuredIntegrations = integrations ?? [];
|
|
166
|
-
const hasBrowserTracing = configuredIntegrations.some(
|
|
167
|
-
(integration) => integration.name === 'BrowserTracing'
|
|
168
|
-
);
|
|
169
|
-
if (hasBrowserTracing) return options;
|
|
170
|
-
|
|
171
|
-
return {
|
|
172
|
-
...options,
|
|
173
|
-
integrations: [
|
|
174
|
-
Sentry.browserTracingIntegration(),
|
|
175
|
-
...configuredIntegrations,
|
|
176
|
-
],
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Capture a browser message in Sentry with optional tags.
|
|
182
|
-
*/
|
|
183
|
-
export function captureBrowserSentryMessage(
|
|
184
|
-
message: string,
|
|
185
|
-
options?: BrowserSentryCaptureMessageOptions
|
|
186
|
-
): void {
|
|
187
|
-
if (!options?.tags || Object.keys(options.tags).length === 0) {
|
|
188
|
-
Sentry.captureMessage(message, options?.level);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
Sentry.withScope((scope) => {
|
|
193
|
-
for (const [name, value] of Object.entries(options.tags ?? {})) {
|
|
194
|
-
scope.setTag(name, value);
|
|
195
|
-
}
|
|
196
|
-
Sentry.captureMessage(message, options?.level);
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Emit a browser Sentry log entry.
|
|
202
|
-
*/
|
|
203
|
-
export function logBrowserSentryMessage(
|
|
204
|
-
message: string,
|
|
205
|
-
options?: BrowserSentryLogOptions
|
|
206
|
-
): void {
|
|
207
|
-
const level = options?.level ?? 'info';
|
|
208
|
-
const logMethod = resolveBrowserLogMethod(level);
|
|
209
|
-
if (!logMethod) return;
|
|
210
|
-
if (!options?.attributes || Object.keys(options.attributes).length === 0) {
|
|
211
|
-
logMethod(message);
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
logMethod(message, options.attributes);
|
|
215
|
-
}
|
package/src/sql-safety.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const READONLY_SQL_START = new Set(['select', 'with', 'pragma', 'explain']);
|
|
2
|
-
const TRANSACTION_SQL_START = new Set([
|
|
3
|
-
'begin',
|
|
4
|
-
'commit',
|
|
5
|
-
'rollback',
|
|
6
|
-
'savepoint',
|
|
7
|
-
'release',
|
|
8
|
-
]);
|
|
9
|
-
|
|
10
|
-
export function assertSyncularReadonlySql(sql: string): void {
|
|
11
|
-
if (isSyncularReadonlySql(sql)) return;
|
|
12
|
-
throw new Error(
|
|
13
|
-
'Syncular public SQL is read-only. Use generated Syncular mutations for synced writes.'
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function isSyncularReadonlySql(sql: string): boolean {
|
|
18
|
-
const normalized = stripLeadingSqlComments(sql).trimStart();
|
|
19
|
-
if (!normalized) return true;
|
|
20
|
-
if (hasMultipleSqlStatements(normalized)) return false;
|
|
21
|
-
const keyword = firstSqlKeyword(normalized);
|
|
22
|
-
if (!keyword) return true;
|
|
23
|
-
if (TRANSACTION_SQL_START.has(keyword)) return true;
|
|
24
|
-
if (!READONLY_SQL_START.has(keyword)) return false;
|
|
25
|
-
if (keyword === 'pragma') return isReadonlyPragma(normalized);
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function stripLeadingSqlComments(sql: string): string {
|
|
30
|
-
let rest = sql;
|
|
31
|
-
for (;;) {
|
|
32
|
-
const trimmed = rest.trimStart();
|
|
33
|
-
if (trimmed.startsWith('--')) {
|
|
34
|
-
const newline = trimmed.indexOf('\n');
|
|
35
|
-
rest = newline < 0 ? '' : trimmed.slice(newline + 1);
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (trimmed.startsWith('/*')) {
|
|
39
|
-
const end = trimmed.indexOf('*/');
|
|
40
|
-
rest = end < 0 ? '' : trimmed.slice(end + 2);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
return trimmed;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function hasMultipleSqlStatements(sql: string): boolean {
|
|
48
|
-
const firstSemicolon = sql.indexOf(';');
|
|
49
|
-
if (firstSemicolon < 0) return false;
|
|
50
|
-
return sql.slice(firstSemicolon + 1).trim().length > 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function firstSqlKeyword(sql: string): string | null {
|
|
54
|
-
const match = /^[a-zA-Z_]+/.exec(sql);
|
|
55
|
-
return match?.[0]?.toLowerCase() ?? null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function isReadonlyPragma(sql: string): boolean {
|
|
59
|
-
const withoutTrailingSemicolon = sql.trim().replace(/;+$/, '').trim();
|
|
60
|
-
return !withoutTrailingSemicolon.includes('=');
|
|
61
|
-
}
|
package/src/tauri/index.ts
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CreateSyncularBridgeClientOptions,
|
|
3
|
-
createSyncularBridgeClient,
|
|
4
|
-
type SyncularAuthLeaseRecord,
|
|
5
|
-
type SyncularBridge,
|
|
6
|
-
type SyncularBridgeMutationBatch,
|
|
7
|
-
type SyncularBridgeQueryRequest,
|
|
8
|
-
type SyncularBridgeQueryResult,
|
|
9
|
-
type SyncularBridgeStatus,
|
|
10
|
-
type SyncularClientEventMap,
|
|
11
|
-
type SyncularClientEventSink,
|
|
12
|
-
type SyncularClientEventType,
|
|
13
|
-
type SyncularClientLike,
|
|
14
|
-
type SyncularConflictResolution,
|
|
15
|
-
type SyncularConflictSummary,
|
|
16
|
-
type SyncularDiagnosticSnapshot,
|
|
17
|
-
type SyncularPresenceEntry,
|
|
18
|
-
type SyncularPresenceSink,
|
|
19
|
-
type SyncularSubscriptionSpec,
|
|
20
|
-
type SyncularSyncResult,
|
|
21
|
-
} from '@syncular/client';
|
|
22
|
-
import type { SyncAuthLeaseIssueRequest } from '@syncular/core';
|
|
23
|
-
|
|
24
|
-
export type SyncularTauriInvoke = <TResult>(
|
|
25
|
-
command: string,
|
|
26
|
-
args?: Record<string, unknown>
|
|
27
|
-
) => Promise<TResult>;
|
|
28
|
-
|
|
29
|
-
export type SyncularTauriListen = <TPayload>(
|
|
30
|
-
event: string,
|
|
31
|
-
handler: (event: { payload: TPayload }) => void
|
|
32
|
-
) => Promise<() => void>;
|
|
33
|
-
|
|
34
|
-
export interface SyncularTauriCommands {
|
|
35
|
-
executeSql: string;
|
|
36
|
-
applyMutationsCommit: string;
|
|
37
|
-
applyLeasedMutationsCommit: string;
|
|
38
|
-
sync: string;
|
|
39
|
-
resumeFromBackground: string;
|
|
40
|
-
start: string;
|
|
41
|
-
stop: string;
|
|
42
|
-
setSubscriptions: string;
|
|
43
|
-
issueAuthLease: string;
|
|
44
|
-
upsertAuthLease: string;
|
|
45
|
-
authLease: string;
|
|
46
|
-
activeAuthLeases: string;
|
|
47
|
-
diagnosticSnapshot: string;
|
|
48
|
-
joinPresence: string;
|
|
49
|
-
leavePresence: string;
|
|
50
|
-
updatePresenceMetadata: string;
|
|
51
|
-
listConflicts: string;
|
|
52
|
-
retryConflictKeepLocal: string;
|
|
53
|
-
resolveConflict: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface CreateSyncularTauriClientOptions
|
|
57
|
-
extends Omit<CreateSyncularBridgeClientOptions, 'bridge'> {
|
|
58
|
-
invoke: SyncularTauriInvoke;
|
|
59
|
-
listen?: SyncularTauriListen;
|
|
60
|
-
commands?: Partial<SyncularTauriCommands>;
|
|
61
|
-
eventPrefix?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const DEFAULT_COMMANDS: SyncularTauriCommands = {
|
|
65
|
-
executeSql: 'syncular_execute_sql',
|
|
66
|
-
applyMutationsCommit: 'syncular_apply_mutations_commit',
|
|
67
|
-
applyLeasedMutationsCommit: 'syncular_apply_leased_mutations_commit',
|
|
68
|
-
sync: 'syncular_sync',
|
|
69
|
-
resumeFromBackground: 'syncular_resume_from_background',
|
|
70
|
-
start: 'syncular_start',
|
|
71
|
-
stop: 'syncular_stop',
|
|
72
|
-
setSubscriptions: 'syncular_set_subscriptions',
|
|
73
|
-
issueAuthLease: 'syncular_issue_auth_lease',
|
|
74
|
-
upsertAuthLease: 'syncular_upsert_auth_lease',
|
|
75
|
-
authLease: 'syncular_auth_lease',
|
|
76
|
-
activeAuthLeases: 'syncular_active_auth_leases',
|
|
77
|
-
diagnosticSnapshot: 'syncular_diagnostic_snapshot',
|
|
78
|
-
joinPresence: 'syncular_join_presence',
|
|
79
|
-
leavePresence: 'syncular_leave_presence',
|
|
80
|
-
updatePresenceMetadata: 'syncular_update_presence_metadata',
|
|
81
|
-
listConflicts: 'syncular_conflict_summaries',
|
|
82
|
-
retryConflictKeepLocal: 'syncular_retry_conflict_keep_local',
|
|
83
|
-
resolveConflict: 'syncular_resolve_conflict',
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export async function createSyncularTauriClient<DB>(
|
|
87
|
-
options: CreateSyncularTauriClientOptions
|
|
88
|
-
): Promise<SyncularClientLike<DB>> {
|
|
89
|
-
return createSyncularBridgeClient<DB>({
|
|
90
|
-
...options,
|
|
91
|
-
bridge: createSyncularTauriBridge(options),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function createSyncularTauriBridge(
|
|
96
|
-
options: CreateSyncularTauriClientOptions
|
|
97
|
-
): SyncularBridge {
|
|
98
|
-
const commands = { ...DEFAULT_COMMANDS, ...options.commands };
|
|
99
|
-
const eventPrefix = options.eventPrefix ?? 'syncular';
|
|
100
|
-
const presence = new Map<string, SyncularPresenceEntry[]>();
|
|
101
|
-
let status: SyncularBridgeStatus = {};
|
|
102
|
-
|
|
103
|
-
const invoke = <TResult>(
|
|
104
|
-
command: string,
|
|
105
|
-
args?: Record<string, unknown>
|
|
106
|
-
): Promise<TResult> => options.invoke<TResult>(command, args);
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
executeSql: <Row extends Record<string, unknown>>(
|
|
110
|
-
request: SyncularBridgeQueryRequest
|
|
111
|
-
) =>
|
|
112
|
-
invoke<SyncularBridgeQueryResult<Row>>(commands.executeSql, { request }),
|
|
113
|
-
applyMutationsCommit: (batch: SyncularBridgeMutationBatch) =>
|
|
114
|
-
invoke<string>(commands.applyMutationsCommit, { batch }),
|
|
115
|
-
applyLeasedMutationsCommit: (batch: SyncularBridgeMutationBatch) =>
|
|
116
|
-
invoke<string>(commands.applyLeasedMutationsCommit, { batch }),
|
|
117
|
-
sync: () => invoke<SyncularSyncResult>(commands.sync),
|
|
118
|
-
resumeFromBackground: (syncOptions) =>
|
|
119
|
-
invoke<SyncularSyncResult>(commands.resumeFromBackground, {
|
|
120
|
-
options: syncOptions,
|
|
121
|
-
}),
|
|
122
|
-
start: () => invoke<void>(commands.start),
|
|
123
|
-
stop: () => invoke<void>(commands.stop),
|
|
124
|
-
setSubscriptions: (subscriptions: readonly SyncularSubscriptionSpec[]) =>
|
|
125
|
-
invoke<void>(commands.setSubscriptions, {
|
|
126
|
-
subscriptions: [...subscriptions],
|
|
127
|
-
}),
|
|
128
|
-
getStatus: () => status,
|
|
129
|
-
issueAuthLease: (request: SyncAuthLeaseIssueRequest) =>
|
|
130
|
-
invoke<SyncularAuthLeaseRecord>(commands.issueAuthLease, { request }),
|
|
131
|
-
upsertAuthLease: (lease: SyncularAuthLeaseRecord) =>
|
|
132
|
-
invoke<void>(commands.upsertAuthLease, { lease }),
|
|
133
|
-
authLease: (leaseId: string) =>
|
|
134
|
-
invoke<SyncularAuthLeaseRecord | null>(commands.authLease, {
|
|
135
|
-
leaseId,
|
|
136
|
-
}),
|
|
137
|
-
activeAuthLeases: (actorId?: string | null, nowMs?: number) =>
|
|
138
|
-
invoke<SyncularAuthLeaseRecord[]>(commands.activeAuthLeases, {
|
|
139
|
-
actorId,
|
|
140
|
-
nowMs,
|
|
141
|
-
}),
|
|
142
|
-
diagnosticSnapshot: () =>
|
|
143
|
-
invoke<SyncularDiagnosticSnapshot>(commands.diagnosticSnapshot),
|
|
144
|
-
on: (event, listener) =>
|
|
145
|
-
listen(options.listen, `${eventPrefix}:${event}`, (payload) => {
|
|
146
|
-
if (event === 'lifecycleChanged') {
|
|
147
|
-
status = {
|
|
148
|
-
...status,
|
|
149
|
-
lifecycle: payload as SyncularBridgeStatus['lifecycle'],
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
listener(payload as never);
|
|
153
|
-
}),
|
|
154
|
-
presence: {
|
|
155
|
-
get: <TMetadata = Record<string, unknown>>(scopeKey: string) =>
|
|
156
|
-
(presence.get(scopeKey) ?? []) as SyncularPresenceEntry<TMetadata>[],
|
|
157
|
-
join: (scopeKey, metadata) => {
|
|
158
|
-
void invoke<void>(commands.joinPresence, { scopeKey, metadata });
|
|
159
|
-
},
|
|
160
|
-
leave: (scopeKey) => {
|
|
161
|
-
void invoke<void>(commands.leavePresence, { scopeKey });
|
|
162
|
-
},
|
|
163
|
-
updateMetadata: (scopeKey, metadata) => {
|
|
164
|
-
void invoke<void>(commands.updatePresenceMetadata, {
|
|
165
|
-
scopeKey,
|
|
166
|
-
metadata,
|
|
167
|
-
});
|
|
168
|
-
},
|
|
169
|
-
onChange: <TMetadata = Record<string, unknown>>(
|
|
170
|
-
listener: SyncularPresenceSink<TMetadata>
|
|
171
|
-
) =>
|
|
172
|
-
listen(options.listen, `${eventPrefix}:presenceChanged`, (payload) => {
|
|
173
|
-
const event = payload as SyncularClientEventMap['presenceChanged'];
|
|
174
|
-
presence.set(event.scopeKey, event.presence);
|
|
175
|
-
listener(event as Parameters<SyncularPresenceSink<TMetadata>>[0]);
|
|
176
|
-
}),
|
|
177
|
-
},
|
|
178
|
-
conflicts: {
|
|
179
|
-
list: () => invoke<SyncularConflictSummary[]>(commands.listConflicts),
|
|
180
|
-
retryKeepLocal: (id) =>
|
|
181
|
-
invoke<string>(commands.retryConflictKeepLocal, { id }),
|
|
182
|
-
resolve: (id, resolution: SyncularConflictResolution) =>
|
|
183
|
-
invoke<void>(commands.resolveConflict, { id, resolution }),
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function listen<T extends SyncularClientEventType>(
|
|
189
|
-
listenFn: SyncularTauriListen | undefined,
|
|
190
|
-
event: string,
|
|
191
|
-
listener: SyncularClientEventSink<T>
|
|
192
|
-
): () => void {
|
|
193
|
-
if (!listenFn) return noop;
|
|
194
|
-
let unlisten: (() => void) | undefined;
|
|
195
|
-
let closed = false;
|
|
196
|
-
void listenFn(event, ({ payload }) => listener(payload as never)).then(
|
|
197
|
-
(nextUnlisten) => {
|
|
198
|
-
if (closed) {
|
|
199
|
-
nextUnlisten();
|
|
200
|
-
} else {
|
|
201
|
-
unlisten = nextUnlisten;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
);
|
|
205
|
-
return () => {
|
|
206
|
-
closed = true;
|
|
207
|
-
unlisten?.();
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function noop(): void {}
|