@sveltebase/sync 1.1.0 → 1.1.2
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 +12 -0
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +10 -9
- package/dist/client/status.svelte.d.ts +6 -0
- package/dist/client/status.svelte.d.ts.map +1 -0
- package/dist/client/status.svelte.js +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -130,6 +130,18 @@ Use it in your Svelte 5 components (using your preferred Dexie reactivity hook,
|
|
|
130
130
|
{/each}
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
### Synced Database Operations
|
|
134
|
+
|
|
135
|
+
Under the hood, `@sveltebase/sync` intercepts native Dexie table writes to capture and propagate mutations to the backend. The following methods automatically sync with the server:
|
|
136
|
+
|
|
137
|
+
* **`.add(row)`**: Triggers a `"create"` sync mutation.
|
|
138
|
+
* **`.put(row)` or `.put(id, changes)`**: Computes a diff of changed properties (for updates) or initiates a `"create"` mutation (for new rows) and sends it to the server.
|
|
139
|
+
* **`.update(id, changes)`**: Performs a local partial update and propagates the changes to the server as an `"update"` mutation.
|
|
140
|
+
* **`.delete(id)`**: Locally deletes the row and propagates a `"delete"` mutation to the server.
|
|
141
|
+
|
|
142
|
+
> [!NOTE]
|
|
143
|
+
> **Bulk methods** (such as `.bulkAdd()`, `.bulkPut()`, and `.bulkDelete()`) bypass backend syncing entirely. They write directly to IndexedDB, which is useful for performing offline seeding or local-only updates.
|
|
144
|
+
|
|
133
145
|
---
|
|
134
146
|
|
|
135
147
|
### Step 2: Define Sync Handlers (Server)
|
package/dist/client/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ declare class SyncClientClass<TSchema extends Record<string, any> = Record<strin
|
|
|
16
16
|
private pingInterval;
|
|
17
17
|
private closedByClient;
|
|
18
18
|
private activeChannels;
|
|
19
|
-
private
|
|
19
|
+
private _statusState;
|
|
20
20
|
private pendingMutations;
|
|
21
21
|
private mutationQueue;
|
|
22
22
|
constructor(options: {
|
|
@@ -41,6 +41,8 @@ declare class SyncClientClass<TSchema extends Record<string, any> = Record<strin
|
|
|
41
41
|
}
|
|
42
42
|
export type SyncClient<TSchema extends Record<string, any> = Record<string, any>> = SyncClientClass<TSchema> & {
|
|
43
43
|
[K in keyof TSchema]: Table<TSchema[K]>;
|
|
44
|
+
} & {
|
|
45
|
+
[tableName: string]: Table<any>;
|
|
44
46
|
};
|
|
45
47
|
export declare const SyncClient: new <TSchema extends Record<string, any> = Record<string, any>>(options: {
|
|
46
48
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,KAAK,EAAwB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,KAAK,EAAwB,MAAM,OAAO,CAAC;AAIhE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC,CAAC;AAaF,cAAM,eAAe,CACnB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CACzD,SAAQ,KAAK;IACb,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAqB;IAG3C,OAAO,CAAC,YAAY,CAA0B;IAG9C,OAAO,CAAC,gBAAgB,CAAsC;IAE9D,OAAO,CAAC,aAAa,CAMb;gBAEI,OAAO,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,MAAM,EAAE,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,EAAE,WAAW,CAAC,CAAC;KACrD;IAoBD,IAAW,MAAM,gDAEhB;IAED,OAAO,CAAC,cAAc;YAiJR,OAAO;IAuFd,SAAS;IAgBhB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,aAAa;YAOP,kBAAkB;IAoBhC,OAAO,CAAC,kBAAkB;YAkBZ,UAAU;YAiBV,aAAa;YAqBb,mBAAmB;IAwEjC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,eAAe;IAqChB,UAAU;CAelB;AAED,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG;KAC5G,CAAC,IAAI,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACxC,GAAG;IACF,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KACvB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzD,OAAO,EAAE;IACT,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,EAAE,WAAW,CAAC,CAAC;CACrD,KAAK,UAAU,CAAC,OAAO,CAA0B,CAAC"}
|
package/dist/client/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Dexie, {} from "dexie";
|
|
2
2
|
import { parseSyncMessage } from "../protocol.js";
|
|
3
|
+
import { ConnectionStatus } from "./status.svelte.js";
|
|
3
4
|
class SyncClientClass extends Dexie {
|
|
4
5
|
wsUrl;
|
|
5
6
|
socket;
|
|
@@ -8,8 +9,8 @@ class SyncClientClass extends Dexie {
|
|
|
8
9
|
pingInterval;
|
|
9
10
|
closedByClient = false;
|
|
10
11
|
activeChannels = new Set();
|
|
11
|
-
// Reactive connection status
|
|
12
|
-
|
|
12
|
+
// Reactive connection status delegated to status.svelte.ts
|
|
13
|
+
_statusState = new ConnectionStatus();
|
|
13
14
|
// Mutations waiting for ack/reject from server
|
|
14
15
|
pendingMutations = new Map();
|
|
15
16
|
// Mutations queued to be sent when connection is established
|
|
@@ -31,7 +32,7 @@ class SyncClientClass extends Dexie {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
get status() {
|
|
34
|
-
return this.
|
|
35
|
+
return this._statusState.value;
|
|
35
36
|
}
|
|
36
37
|
decorateTables() {
|
|
37
38
|
for (const [tableName, config] of Object.entries(this.tableConfigs)) {
|
|
@@ -126,7 +127,7 @@ class SyncClientClass extends Dexie {
|
|
|
126
127
|
async connect() {
|
|
127
128
|
if (this.closedByClient)
|
|
128
129
|
return;
|
|
129
|
-
this.
|
|
130
|
+
this._statusState.value = "connecting";
|
|
130
131
|
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
131
132
|
const host = window.location.host;
|
|
132
133
|
let resolvedUrl;
|
|
@@ -135,7 +136,7 @@ class SyncClientClass extends Dexie {
|
|
|
135
136
|
}
|
|
136
137
|
catch (err) {
|
|
137
138
|
console.error("SyncClient: Failed to resolve wsUrl", err);
|
|
138
|
-
this.
|
|
139
|
+
this._statusState.value = "disconnected";
|
|
139
140
|
if (!this.closedByClient) {
|
|
140
141
|
this.reconnectTimer = setTimeout(() => this.connect(), 2000);
|
|
141
142
|
}
|
|
@@ -150,7 +151,7 @@ class SyncClientClass extends Dexie {
|
|
|
150
151
|
if (this.socket !== socket)
|
|
151
152
|
return;
|
|
152
153
|
console.log("SyncClient: WebSocket connected");
|
|
153
|
-
this.
|
|
154
|
+
this._statusState.value = "connected";
|
|
154
155
|
this.activeChannels.clear();
|
|
155
156
|
this.startHeartbeat();
|
|
156
157
|
// Re-subscribe to all tables (delta-sync aware)
|
|
@@ -186,7 +187,7 @@ class SyncClientClass extends Dexie {
|
|
|
186
187
|
socket.addEventListener("close", () => {
|
|
187
188
|
if (this.socket === socket) {
|
|
188
189
|
this.socket = undefined;
|
|
189
|
-
this.
|
|
190
|
+
this._statusState.value = "disconnected";
|
|
190
191
|
this.stopHeartbeat();
|
|
191
192
|
if (!this.closedByClient) {
|
|
192
193
|
this.reconnectTimer = setTimeout(() => this.connect(), 2000);
|
|
@@ -211,7 +212,7 @@ class SyncClientClass extends Dexie {
|
|
|
211
212
|
}
|
|
212
213
|
catch { }
|
|
213
214
|
this.socket = undefined;
|
|
214
|
-
this.
|
|
215
|
+
this._statusState.value = "disconnected";
|
|
215
216
|
}
|
|
216
217
|
this.connect();
|
|
217
218
|
}
|
|
@@ -403,7 +404,7 @@ class SyncClientClass extends Dexie {
|
|
|
403
404
|
}
|
|
404
405
|
disconnect() {
|
|
405
406
|
this.closedByClient = true;
|
|
406
|
-
this.
|
|
407
|
+
this._statusState.value = "disconnected";
|
|
407
408
|
this.stopHeartbeat();
|
|
408
409
|
if (this.reconnectTimer) {
|
|
409
410
|
clearTimeout(this.reconnectTimer);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.svelte.d.ts","sourceRoot":"","sources":["../../src/client/status.svelte.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAqE;IAEnF,IAAI,KAAK,IAIW,YAAY,GAAG,WAAW,GAAG,cAAc,CAF9D;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,EAE9D;CACF"}
|