@electric-sql/client 1.5.11 → 1.5.12
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/bin/intent.mjs +6 -0
- package/package.json +9 -2
- package/skills/electric-debugging/SKILL.md +217 -0
- package/skills/electric-deployment/SKILL.md +196 -0
- package/skills/electric-new-feature/SKILL.md +366 -0
- package/skills/electric-orm/SKILL.md +189 -0
- package/skills/electric-postgres-security/SKILL.md +196 -0
- package/skills/electric-proxy-auth/SKILL.md +269 -0
- package/skills/electric-schema-shapes/SKILL.md +200 -0
- package/skills/electric-shapes/SKILL.md +339 -0
- package/skills/electric-shapes/references/type-parsers.md +64 -0
- package/skills/electric-shapes/references/where-clause.md +64 -0
package/bin/intent.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Auto-generated by @tanstack/intent setup
|
|
3
|
+
// Exposes the intent end-user CLI for consumers of this library.
|
|
4
|
+
// Commit this file, then add to your package.json:
|
|
5
|
+
// "bin": { "intent": "./bin/intent.mjs" }
|
|
6
|
+
await import(`@tanstack/intent/intent-library`)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-sql/client",
|
|
3
3
|
"description": "Postgres everywhere - your data, in sync, wherever you need it.",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.12",
|
|
5
5
|
"author": "ElectricSQL team and contributors.",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/electric-sql/electric/issues"
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"@microsoft/fetch-event-source": "^2.0.1"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
+
"@tanstack/intent": "^0.0.9",
|
|
13
14
|
"@types/pg": "^8.11.6",
|
|
14
15
|
"@types/uuid": "^10.0.0",
|
|
15
16
|
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
@@ -45,9 +46,15 @@
|
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
},
|
|
49
|
+
"bin": {
|
|
50
|
+
"intent": "./bin/intent.mjs"
|
|
51
|
+
},
|
|
48
52
|
"files": [
|
|
49
53
|
"dist",
|
|
50
|
-
"src"
|
|
54
|
+
"src",
|
|
55
|
+
"skills",
|
|
56
|
+
"bin",
|
|
57
|
+
"!skills/_artifacts"
|
|
51
58
|
],
|
|
52
59
|
"homepage": "https://electric-sql.com",
|
|
53
60
|
"license": "Apache-2.0",
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electric-debugging
|
|
3
|
+
description: >
|
|
4
|
+
Troubleshoot Electric sync issues. Covers fast-loop detection from CDN/proxy
|
|
5
|
+
cache key misconfiguration, stale cache diagnosis (StaleCacheError),
|
|
6
|
+
MissingHeadersError from CORS misconfiguration, 409 shape expired handling,
|
|
7
|
+
SSE proxy buffering (nginx proxy_buffering off, Caddy flush_interval -1),
|
|
8
|
+
HTTP/1.1 6-connection limit in local dev (Caddy HTTP/2 proxy), WAL growth
|
|
9
|
+
from replication slots (max_slot_wal_keep_size), Vercel CDN cache issues,
|
|
10
|
+
and onError/backoff behavior. Load when shapes are not receiving updates,
|
|
11
|
+
sync is slow, or errors appear in the console.
|
|
12
|
+
type: lifecycle
|
|
13
|
+
library: electric
|
|
14
|
+
library_version: '1.5.10'
|
|
15
|
+
requires:
|
|
16
|
+
- electric-shapes
|
|
17
|
+
- electric-proxy-auth
|
|
18
|
+
sources:
|
|
19
|
+
- 'electric-sql/electric:packages/typescript-client/src/client.ts'
|
|
20
|
+
- 'electric-sql/electric:packages/typescript-client/src/fetch.ts'
|
|
21
|
+
- 'electric-sql/electric:packages/typescript-client/src/error.ts'
|
|
22
|
+
- 'electric-sql/electric:website/docs/guides/troubleshooting.md'
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This skill builds on electric-shapes and electric-proxy-auth. Read those first.
|
|
26
|
+
|
|
27
|
+
# Electric — Debugging Sync Issues
|
|
28
|
+
|
|
29
|
+
## Setup
|
|
30
|
+
|
|
31
|
+
Enable debug logging to see retry and state machine behavior:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { ShapeStream, FetchError } from '@electric-sql/client'
|
|
35
|
+
|
|
36
|
+
const stream = new ShapeStream({
|
|
37
|
+
url: '/api/todos',
|
|
38
|
+
backoffOptions: {
|
|
39
|
+
initialDelay: 1000,
|
|
40
|
+
maxDelay: 32000,
|
|
41
|
+
multiplier: 2,
|
|
42
|
+
debug: true, // Logs retry attempts
|
|
43
|
+
},
|
|
44
|
+
onError: (error) => {
|
|
45
|
+
if (error instanceof FetchError) {
|
|
46
|
+
console.error(`Sync error: ${error.status} at ${error.url}`, error.json)
|
|
47
|
+
}
|
|
48
|
+
return {} // Always return {} to retry
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Core Patterns
|
|
54
|
+
|
|
55
|
+
### Error retry behavior
|
|
56
|
+
|
|
57
|
+
| Error | Auto-retry? | Action |
|
|
58
|
+
| --------------------- | -------------------------- | ------------------------------------------------------------- |
|
|
59
|
+
| 5xx server errors | Yes (exponential backoff) | Wait and retry |
|
|
60
|
+
| 429 rate limit | Yes (respects Retry-After) | Wait and retry |
|
|
61
|
+
| Network errors | Yes (exponential backoff) | Wait and retry |
|
|
62
|
+
| 4xx (non-429) | No | Calls `onError` — return `{}` to retry manually |
|
|
63
|
+
| 409 shape expired | Yes (automatic reset) | Client resets and refetches |
|
|
64
|
+
| `MissingHeadersError` | Never | Fix CORS/proxy — not retryable even if `onError` returns `{}` |
|
|
65
|
+
|
|
66
|
+
### Diagnosing MissingHeadersError
|
|
67
|
+
|
|
68
|
+
This error means Electric response headers (`electric-offset`, `electric-handle`) are being stripped, usually by CORS:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
MissingHeadersError: This is often due to a proxy not setting CORS correctly
|
|
72
|
+
so that all Electric headers can be read by the client.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Fix: expose Electric headers in proxy CORS configuration:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
headers.set(
|
|
79
|
+
'Access-Control-Expose-Headers',
|
|
80
|
+
'electric-offset, electric-handle, electric-schema, electric-cursor'
|
|
81
|
+
)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Diagnosing fast-loop detection
|
|
85
|
+
|
|
86
|
+
Console message: "Detected possible fast loop" with diagnostic info.
|
|
87
|
+
|
|
88
|
+
Cause: proxy/CDN cache key doesn't include `handle` and `offset` query params, so the client gets the same stale response repeatedly.
|
|
89
|
+
|
|
90
|
+
Fix: ensure your proxy/CDN includes all query parameters in its cache key.
|
|
91
|
+
|
|
92
|
+
For Vercel, add to `vercel.json`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"headers": [
|
|
97
|
+
{
|
|
98
|
+
"source": "/api/(.*)",
|
|
99
|
+
"headers": [
|
|
100
|
+
{ "key": "CDN-Cache-Control", "value": "no-store" },
|
|
101
|
+
{ "key": "Vercel-CDN-Cache-Control", "value": "no-store" }
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Common Mistakes
|
|
109
|
+
|
|
110
|
+
### HIGH Proxy or CDN not including query params in cache key
|
|
111
|
+
|
|
112
|
+
Wrong:
|
|
113
|
+
|
|
114
|
+
```nginx
|
|
115
|
+
# nginx caching without query params in key
|
|
116
|
+
proxy_cache_key $scheme$host$uri;
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Correct:
|
|
120
|
+
|
|
121
|
+
```nginx
|
|
122
|
+
# Include query params (handle, offset) in cache key
|
|
123
|
+
proxy_cache_key $scheme$host$request_uri;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Fast-loop detection fires after 5 requests in 500ms at the same offset. The client auto-clears caches once, then applies backoff, then throws after 5 consecutive detections.
|
|
127
|
+
|
|
128
|
+
Source: `packages/typescript-client/src/client.ts:929-1002`
|
|
129
|
+
|
|
130
|
+
### HIGH SSE responses buffered by proxy
|
|
131
|
+
|
|
132
|
+
Wrong:
|
|
133
|
+
|
|
134
|
+
```nginx
|
|
135
|
+
location /v1/shape {
|
|
136
|
+
proxy_pass http://electric:3000;
|
|
137
|
+
# Default: proxy_buffering on — SSE responses delayed
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Correct:
|
|
142
|
+
|
|
143
|
+
```nginx
|
|
144
|
+
location /v1/shape {
|
|
145
|
+
proxy_pass http://electric:3000;
|
|
146
|
+
proxy_buffering off;
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For Caddy:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
reverse_proxy localhost:3000 {
|
|
154
|
+
flush_interval -1
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Nginx and Caddy buffer responses by default, causing long delays for SSE live updates. Disable buffering for Electric endpoints. Do NOT disable caching entirely — Electric uses cache headers for request collapsing.
|
|
159
|
+
|
|
160
|
+
Source: `website/docs/guides/troubleshooting.md:69-109`
|
|
161
|
+
|
|
162
|
+
### MEDIUM Running 6+ shapes in local dev without HTTP/2
|
|
163
|
+
|
|
164
|
+
Wrong:
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
# Running Electric directly on localhost:3000
|
|
168
|
+
# With 7+ shapes, browser HTTP/1.1 queues all requests (6 connection limit)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Correct:
|
|
172
|
+
|
|
173
|
+
```sh
|
|
174
|
+
# Run Caddy as HTTP/2 proxy on host (not in Docker — Docker prevents HTTP/2)
|
|
175
|
+
caddy run --config - --adapter caddyfile <<EOF
|
|
176
|
+
localhost:3001 {
|
|
177
|
+
reverse_proxy localhost:3000
|
|
178
|
+
}
|
|
179
|
+
EOF
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Browser HTTP/1.1 limits to 6 TCP connections per origin. With many shapes, requests queue behind each other. Use Caddy as a local HTTP/2 proxy.
|
|
183
|
+
|
|
184
|
+
Source: `website/docs/guides/troubleshooting.md:28-53`
|
|
185
|
+
|
|
186
|
+
### HIGH Leaving replication slot active when Electric is stopped
|
|
187
|
+
|
|
188
|
+
Wrong:
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
docker stop electric
|
|
192
|
+
# Replication slot retains WAL indefinitely — disk fills up
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Correct:
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
docker stop electric
|
|
199
|
+
|
|
200
|
+
# Drop slot when stopping for extended periods
|
|
201
|
+
psql -c "SELECT pg_drop_replication_slot('electric_slot_default');"
|
|
202
|
+
|
|
203
|
+
# Or set a safety limit
|
|
204
|
+
psql -c "ALTER SYSTEM SET max_slot_wal_keep_size = '10GB';"
|
|
205
|
+
psql -c "SELECT pg_reload_conf();"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Replication slots retain WAL indefinitely when Electric is disconnected. Postgres disk fills up. Either drop the slot or set `max_slot_wal_keep_size`.
|
|
209
|
+
|
|
210
|
+
Source: `website/docs/guides/troubleshooting.md:203-316`
|
|
211
|
+
|
|
212
|
+
See also: electric-deployment/SKILL.md — Many sync issues stem from deployment configuration.
|
|
213
|
+
See also: electric-shapes/SKILL.md — onError semantics and backoff behavior.
|
|
214
|
+
|
|
215
|
+
## Version
|
|
216
|
+
|
|
217
|
+
Targets @electric-sql/client v1.5.10.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electric-deployment
|
|
3
|
+
description: >
|
|
4
|
+
Deploy Electric via Docker, Docker Compose, or Electric Cloud. Covers
|
|
5
|
+
DATABASE_URL (direct connection, not pooler), ELECTRIC_SECRET (required
|
|
6
|
+
since v1.x), ELECTRIC_INSECURE for dev, wal_level=logical,
|
|
7
|
+
max_replication_slots, ELECTRIC_STORAGE_DIR persistence,
|
|
8
|
+
ELECTRIC_POOLED_DATABASE_URL for pooled queries, IPv6 with
|
|
9
|
+
ELECTRIC_DATABASE_USE_IPV6, Kubernetes readiness probes (200 vs 202),
|
|
10
|
+
replication slot cleanup, and Postgres v14+ requirements. Load when
|
|
11
|
+
deploying Electric or configuring Postgres for logical replication.
|
|
12
|
+
type: lifecycle
|
|
13
|
+
library: electric
|
|
14
|
+
library_version: '1.5.10'
|
|
15
|
+
sources:
|
|
16
|
+
- 'electric-sql/electric:website/docs/guides/deployment.md'
|
|
17
|
+
- 'electric-sql/electric:packages/sync-service/dev/postgres.conf'
|
|
18
|
+
- 'electric-sql/electric:packages/sync-service/CHANGELOG.md'
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Electric — Deployment
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
### Postgres configuration
|
|
26
|
+
|
|
27
|
+
```conf
|
|
28
|
+
# postgresql.conf
|
|
29
|
+
wal_level = logical
|
|
30
|
+
max_replication_slots = 10
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Docker Compose
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
name: 'electric-backend'
|
|
37
|
+
services:
|
|
38
|
+
postgres:
|
|
39
|
+
image: postgres:16-alpine
|
|
40
|
+
environment:
|
|
41
|
+
POSTGRES_DB: electric
|
|
42
|
+
POSTGRES_USER: postgres
|
|
43
|
+
POSTGRES_PASSWORD: password
|
|
44
|
+
ports: ['54321:5432']
|
|
45
|
+
volumes: ['./postgres.conf:/etc/postgresql/postgresql.conf:ro']
|
|
46
|
+
tmpfs: ['/var/lib/postgresql/data', '/tmp']
|
|
47
|
+
command: ['postgres', '-c', 'config_file=/etc/postgresql/postgresql.conf']
|
|
48
|
+
|
|
49
|
+
electric:
|
|
50
|
+
image: electricsql/electric:latest
|
|
51
|
+
environment:
|
|
52
|
+
DATABASE_URL: postgresql://postgres:password@postgres:5432/electric?sslmode=disable
|
|
53
|
+
ELECTRIC_SECRET: ${ELECTRIC_SECRET}
|
|
54
|
+
ports: ['3000:3000']
|
|
55
|
+
volumes: ['electric_data:/var/lib/electric']
|
|
56
|
+
depends_on: ['postgres']
|
|
57
|
+
|
|
58
|
+
volumes:
|
|
59
|
+
electric_data:
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Electric Cloud
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
npx @electric-sql/start my-app
|
|
66
|
+
pnpm claim && pnpm deploy
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Core Patterns
|
|
70
|
+
|
|
71
|
+
### Environment variables
|
|
72
|
+
|
|
73
|
+
| Variable | Required | Description |
|
|
74
|
+
| ------------------------------ | ---------- | --------------------------------------------- |
|
|
75
|
+
| `DATABASE_URL` | Yes | Direct Postgres connection (not pooler) |
|
|
76
|
+
| `ELECTRIC_SECRET` | Yes (prod) | API authentication secret |
|
|
77
|
+
| `ELECTRIC_INSECURE` | Dev only | Set `true` to skip secret requirement |
|
|
78
|
+
| `ELECTRIC_STORAGE_DIR` | No | Persistent shape cache directory |
|
|
79
|
+
| `ELECTRIC_POOLED_DATABASE_URL` | No | Pooled connection for non-replication queries |
|
|
80
|
+
| `ELECTRIC_DATABASE_USE_IPV6` | No | Set `true` for IPv6 Postgres connections |
|
|
81
|
+
|
|
82
|
+
### Kubernetes health checks
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
livenessProbe:
|
|
86
|
+
httpGet:
|
|
87
|
+
path: /v1/health
|
|
88
|
+
port: 3000
|
|
89
|
+
readinessProbe:
|
|
90
|
+
exec:
|
|
91
|
+
command: ['curl', '-sf', 'http://localhost:3000/v1/health']
|
|
92
|
+
# Use exec, not httpGet — 202 means "alive but not ready"
|
|
93
|
+
# Only 200 means fully ready for traffic
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Replication slot cleanup
|
|
97
|
+
|
|
98
|
+
```sql
|
|
99
|
+
-- When stopping Electric for extended periods:
|
|
100
|
+
SELECT pg_drop_replication_slot('electric_slot_default');
|
|
101
|
+
|
|
102
|
+
-- Prevent unbounded WAL growth:
|
|
103
|
+
ALTER SYSTEM SET max_slot_wal_keep_size = '10GB';
|
|
104
|
+
SELECT pg_reload_conf();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Common Mistakes
|
|
108
|
+
|
|
109
|
+
### CRITICAL Not setting wal_level to logical
|
|
110
|
+
|
|
111
|
+
Wrong:
|
|
112
|
+
|
|
113
|
+
```conf
|
|
114
|
+
# postgresql.conf (default)
|
|
115
|
+
wal_level = replica
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Correct:
|
|
119
|
+
|
|
120
|
+
```conf
|
|
121
|
+
wal_level = logical
|
|
122
|
+
max_replication_slots = 10
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Electric requires logical replication. The default `wal_level = replica` does not support it. Requires Postgres restart after change.
|
|
126
|
+
|
|
127
|
+
Source: `packages/sync-service/dev/postgres.conf`
|
|
128
|
+
|
|
129
|
+
### CRITICAL Running without ELECTRIC_SECRET in production
|
|
130
|
+
|
|
131
|
+
Wrong:
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
docker run electricsql/electric \
|
|
135
|
+
-e DATABASE_URL=postgres://user:pass@host/db
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Correct:
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
docker run electricsql/electric \
|
|
142
|
+
-e DATABASE_URL=postgres://user:pass@host/db \
|
|
143
|
+
-e ELECTRIC_SECRET=my-secret-key
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Since v1.x, `ELECTRIC_SECRET` is required. Without it, Electric refuses to start unless `ELECTRIC_INSECURE=true` is set (dev only).
|
|
147
|
+
|
|
148
|
+
Source: `packages/sync-service/CHANGELOG.md:832-834`
|
|
149
|
+
|
|
150
|
+
### MEDIUM Using ephemeral storage for ELECTRIC_STORAGE_DIR
|
|
151
|
+
|
|
152
|
+
Wrong:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
electric:
|
|
156
|
+
image: electricsql/electric:latest
|
|
157
|
+
# No volume — shape cache lost on restart
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Correct:
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
electric:
|
|
164
|
+
image: electricsql/electric:latest
|
|
165
|
+
volumes: ['electric_data:/var/lib/electric']
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Electric caches shape logs on disk. Ephemeral storage causes full re-sync on every container restart.
|
|
169
|
+
|
|
170
|
+
Source: `website/docs/guides/deployment.md:133-157`
|
|
171
|
+
|
|
172
|
+
### MEDIUM Using deprecated ELECTRIC_QUERY_DATABASE_URL
|
|
173
|
+
|
|
174
|
+
Wrong:
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
ELECTRIC_QUERY_DATABASE_URL=postgres://user:pass@pooler:6432/db
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Correct:
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
ELECTRIC_POOLED_DATABASE_URL=postgres://user:pass@pooler:6432/db
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Renamed from `ELECTRIC_QUERY_DATABASE_URL` to `ELECTRIC_POOLED_DATABASE_URL` in v1.3.x. The old name may stop working in future versions.
|
|
187
|
+
|
|
188
|
+
Source: `packages/sync-service/CHANGELOG.md:415`
|
|
189
|
+
|
|
190
|
+
See also: electric-proxy-auth/SKILL.md — Production requires proxy with ELECTRIC_SECRET.
|
|
191
|
+
See also: electric-postgres-security/SKILL.md — Deployment requires correct Postgres configuration.
|
|
192
|
+
See also: electric-debugging/SKILL.md — Many sync issues stem from deployment configuration.
|
|
193
|
+
|
|
194
|
+
## Version
|
|
195
|
+
|
|
196
|
+
Targets Electric sync service v1.x.
|