Giter Site home page Giter Site logo

skilldevs / electric_dart Goto Github PK

View Code? Open in Web Editor NEW
101.0 101.0 9.0 12.35 MB

A Dart implementation for Electric (electric-sql.com).

License: Apache License 2.0

Dart 75.59% Kotlin 0.01% Ruby 0.14% Swift 0.10% Objective-C 0.01% CMake 0.96% C++ 1.19% C 0.07% JavaScript 21.15% HTML 0.13% Shell 0.26% Makefile 0.35% Dockerfile 0.07%

electric_dart's People

Contributors

davidmartos96 avatar etienneolivier avatar opsb avatar simolus3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

electric_dart's Issues

Todos_flutter errors

Hello, just downloaded this repo and did everything in readme to hook it up.
In init_app.dart

typedef InitData = ({
  TodosDatabase todosDb,
  ElectricClient<AppDatabase> electricClient,
  ConnectivityStateController connectivityStateController,
});

i get error that The type 'ElectricClient' is declared with 0 type parameters, but 1 type arguments were given. Try adjusting the number of type arguments to match the number of type parameters.

this is also in electric.dart and main.dart. Also its yelling that syncTable() and SyncInputRelation does not exist.

Can someone take a peek so the example works properly?

Thank you!

Version solving failed in todos example

Getting this error on pubspec

Resolving dependencies... Because every version of electricsql_cli from path depends on electricsql from hosted and todos_electrified depends on electricsql from path, electricsql_cli from path is forbidden. So, because todos_electrified depends on electricsql_cli from path, version solving failed. exit code 1

Really excited to try electric btw. Thanks for building a dart client for it.

Issue after upgrade `_electric_trigger_settings has no column named namespace`

Hello again :)

After upgrading electric, and creating a new migration, I have the following error:

[Electric] INFO:  09:27:48.758 Using SQLite version: 3.45.3 
[Electric] Using SQLite version: 3.45.3
[Electric] INFO:  09:27:48.768 applying migration: 20240522072322 
[Electric] applying migration: 20240522072322
[Electric] ERROR: 09:27:48.780 Query error: SqliteException(1): while executing, table _electric_trigger_settings has no column named namespace, SQL logic error (code 1)
             Causing statement: INSERT OR IGNORE INTO _electric_trigger_settings (namespace, tablename, flag) VALUES ('main', 'arrow', 1);, parameters: 
           	Statement: 'INSERT OR IGNORE INTO _electric_trigger_settings (namespace, tablename, flag) VALUES ('main', 'arrow', 1);' - args: null 

Any idea how to solve this ?

Cheers !

  electricsql: ^0.7.1+4
  drift: ^2.15.0
  electricsql_flutter: ^0.7.0

Schema versioning conflicts

When performing an update of Electric service (with new migration schemas for Postgres) + deploying a new Flutter app (that matches new schemas), some app users will still have the old version of the app

Now, the lib fetches the migrations (for sqlite dialect) from Electric service, on App startup, and apply them on the local sqlite db

The problem
The old app may not work with the new schema

The possible solution
I'm still reshaping my brain to think Offline first, does forward/additive migration planning will cover such cases?

Error connecting to Electric: errorType: INVALID_REQUEST when pressing back button on main screen and reopening the app

Device: Android (14)

Flutter version/SDK: Flutter 3.22.0 (stable channel)

Plugin version: Tested both on v0.6.0 and v0.7.0 versions

Issue: Running the todos_flutter Flutter app following the todos_electrified instructions will generate an INVALID_REQUEST error when trying to reconnect to Electric after pressing the system back button and reopening the app from background. This might be an issue on newer Android version that the app would not retain its state upon waking from sleep.

Expected behaviour: After the first initialization, pressing the back button in the main screen (leaving the app running in background) and then reopening it should reconnect to Electric (like on a normal startup)

How to reproduce the issue:
After initializing the example docker and project following the README:

  1. Open the app
  2. Let it connect to electric
  3. Press the back button on the device, then reopen the app (without closing it first)
  4. The error will occur

Stack log (client):

Connecting to VM Service at ws://127.0.0.1:49634/vAFa1zbMXhQ=/ws
D/VRI[MainActivity](15904): Cancelling draw. cancelDueToPreDrawListener=true cancelDueToSync=false
I/Gralloc4(15904): Adding additional valid usage bits: 0x8202000
D/VRI[MainActivity](15904): Cancelling draw. cancelDueToPreDrawListener=true cancelDueToSync=false
I/flutter (15904): Using todos database at path /data/user/0/com.example.todos_electrified/app_flutter/todos-electric/todos.db
D/VRI[MainActivity](15904): Cancelling draw. cancelDueToPreDrawListener=true cancelDueToSync=false
I/flutter (15904): Dummy onCreate
I/flutter (15904): Electrifying database...
I/flutter (15904): Electric URL: http://192.168.11.245:5133
I/flutter (15904): [Electric] INFO:  10:48:48.479 Using SQLite version: 3.45.3 
I/flutter (15904): [Electric] INFO:  10:48:48.513 applying migration: 0 
I/flutter (15904): [Electric] INFO:  10:48:48.544 applying migration: 20230924100310 
I/flutter (15904): [Electric] INFO:  10:48:48.563 applying migration: 20230924100404 
I/flutter (15904): [Electric] INFO:  10:48:48.632 no lsn retrieved from store 
I/flutter (15904): Database electrified!
I/flutter (15904): [Electric] DEBUG: 10:48:48.729 notifying Electric of database changes. Changed tables: {todolist} 
I/flutter (15904): [Electric] INFO:  10:48:49.213 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:48:49.825 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJjNTVmMWYyOC1mNzQzLTQ3YjctYjY3MC0zOWY4YjY0MTg5M2UifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:48:49.834 [proto] send: #SatRpcRequest{method: authenticate, requestId: 1} 
I/flutter (15904): [Electric] DEBUG: 10:48:49.867 notifying client of database changes. Changed tables: [todolist]. Origin: local 
I/flutter (15904): [Electric] DEBUG: 10:48:49.907 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 1} 
I/flutter (15904): [Electric] DEBUG: 10:48:49.912 [rpc] recv: #SatAuthResp{id: d4972d63-cc43-411c-b669-1a40bde4a74d} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.148 [proto] recv: #SatRpcRequest{method: startReplication, requestId: 0} 
I/flutter (15904): [Electric] INFO:  10:48:50.161 Server sent a replication request to start from 0, and options () 
I/flutter (15904): [Electric] DEBUG: 10:48:50.167 [proto] send: #SatRpcResponse{method: startReplication, requestId: 0} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.194 [proto] send: #SatRelation{for: public.todolist, as: 0, cols: id: TEXT, filter: TEXT, editing: TEXT} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.230 [proto] send: #SatOpLog{ops: [#Begin{lsn: AAAAAQ==, ts: 1715849328747, isMigration: false}, #Insert{for: 0, tags: [], new: ["LIST-ID-SAMPLE", ∅, ∅]}, #Commit{lsn: }]} 
I/flutter (15904): [Electric] INFO:  10:48:50.250 no previous LSN, start replication from scratch 
I/flutter (15904): [Electric] DEBUG: 10:48:50.252 [rpc] send: #SatInStartReplicationReq{lsn: , schema: 20230924100404, subscriptions: []} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.255 [proto] send: #SatRpcRequest{method: startReplication, requestId: 2} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.279 [proto] recv: #SatRpcResponse{method: startReplication, requestId: 2} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.283 [rpc] recv: #SatInStartReplicationResp{} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.412 [rpc] send: #SatSubsReq{id: ceeb9690-3883-44ba-863e-f2ace3cc9c4c, shapes: [{"1":"f22d7a4a-38b5-4254-b87d-9ab817cbf557","2":{"1":[{"1":"todolist","3":[{"1":["listid"],"2":{"1":"todo"}}]}]}}]} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.412 [proto] send: #SatRpcRequest{method: subscribe, requestId: 3} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.512 [proto] recv: #SatRpcResponse{method: subscribe, requestId: 3} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.520 [rpc] recv: #SatSubsResp{id: ceeb9690-3883-44ba-863e-f2ace3cc9c4c} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.523 [proto] recv: #SatOpLog{ops: [#Begin{lsn: MjY5Mjk4MTY=, ts: 1715849328747, isMigration: false}, #Commit{lsn: MjY5Mjk4MTY=}]} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.534 [proto] recv: #SatRelation{for: public.todolist, as: 16821, cols: id: text PK, filter: text, editing: text} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.536 [proto] recv: #SatSubsDataBegin{id: ceeb9690-3883-44ba-863e-f2ace3cc9c4c, lsn: MjY5MzIyNjQ=} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.539 [proto] recv: #SatShapeDataBegin{id: f22d7a4a-38b5-4254-b87d-9ab817cbf557} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.541 [proto] recv: #SatOpLog{ops: [#Insert{for: 16821, tags: [f1c3addf-a1ae-43e0-93e8-c6b1d1aa8eb6@1715847403745, 956a17af-751b-4f62-af5a-6dbbc13ecb2b@1715849328747], new: ["LIST-ID-SAMPLE", ∅, ∅]}]} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.542 [proto] recv: #SatShapeDataEnd{} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.542 [proto] recv: #SatSubsDataEnd{} 
I/flutter (15904): [Electric] DEBUG: 10:48:50.592 notifying client of database changes. Changed tables: [todolist]. Origin: initial 
I/flutter (15904): [Electric] DEBUG: 10:48:50.594 notifying Drift of database changes: Changed tables: {todolist}. Origin: initial 
I/flutter (15904): [Electric] DEBUG: 10:48:50.596 [proto] send: #SatOpLogAck{lsn: MjY5Mjk4MTY=, txid: 762} 
W/dos_electrified(15904): ApkAssets: Deleting an ApkAssets object '<empty> and /data/app/~~wvIKYnQN8Z6uwyHGNzBTcA==/com.google.android.marvin.talkback-lSfObUgBlT6vOfsmG0LA2w==/base.apk' with 1 weak references
W/dos_electrified(15904): ApkAssets: Deleting an ApkAssets object '<empty> and /data/app/~~wvIKYnQN8Z6uwyHGNzBTcA==/com.google.android.marvin.talkback-lSfObUgBlT6vOfsmG0LA2w==/split_config.arm64_v8a.apk' with 1 weak references

# Reopening the app after back button press

W/WindowOnBackDispatcher(15904): sendCancelIfRunning: isInProgress=falsecallback=android.view.ViewRootImpl$$ExternalSyntheticLambda17@72cd5ff
I/AdrenoGLES-0(15904): QUALCOMM build                   : 329cf4c2a7, I63533b1e29
I/AdrenoGLES-0(15904): Build Date                       : 01/31/23
I/AdrenoGLES-0(15904): OpenGL ES Shader Compiler Version: EV031.35.01.12
I/AdrenoGLES-0(15904): Local Branch                     :
I/AdrenoGLES-0(15904): Remote Branch                    : refs/tags/AU_LINUX_ANDROID_LA.UM.9.14.11.00.00.571.148
I/AdrenoGLES-0(15904): Remote Branch                    : NONE
I/AdrenoGLES-0(15904): Reconstruct Branch               : NOTHING
I/AdrenoGLES-0(15904): Build Config                     : S P 10.0.7 AArch64
I/AdrenoGLES-0(15904): Driver Path                      : /vendor/lib64/egl/libGLESv2_adreno.so
I/AdrenoGLES-0(15904): PFP: 0x016dc094, ME: 0x00000000
E/OpenGLRenderer(15904): Unable to match the desired swap behavior.
D/VRI[MainActivity](15904): Cancelling draw. cancelDueToPreDrawListener=true cancelDueToSync=false
I/flutter (15904): Using todos database at path /data/user/0/com.example.todos_electrified/app_flutter/todos-electric/todos.db
I/flutter (15904): Electrifying database...
I/flutter (15904): Electric URL: http://192.168.11.245:5133
I/flutter (15904): [Electric] INFO:  10:50:09.082 Using SQLite version: 3.45.3 
I/flutter (15904): [Electric] INFO:  10:50:09.175 retrieved lsn [50, 54, 57, 51, 50, 50, 54, 52] 
I/flutter (15904): Database electrified!
I/flutter (15904): [Electric] INFO:  10:50:09.690 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:50:10.388 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJmMGVjMTUzNi04NTU1LTRmNmYtYTI4ZS00M2FhNTJhYzk1ZWIifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:50:10.398 [proto] send: #SatRpcRequest{method: authenticate, requestId: 1} 
I/flutter (15904): [Electric] DEBUG: 10:50:11.752 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 1, error: #SatErrorResp{type: INVALID_REQUEST}} 
I/flutter (15904): [Electric] WARN:  10:50:11.753 RPC call authenticate/1 failed with #SatErrorResp{type: INVALID_REQUEST} 
I/flutter (15904): [Electric] DEBUG: 10:50:11.763 server returned an error while establishing connection: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] DEBUG: 10:50:11.764 connectAndStartRetryHandler was cancelled: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): Error connecting to Electric: errorType: INVALID_REQUEST
I/flutter (15904):
I/flutter (15904): [Electric] WARN:  10:50:11.783 an error occurred in satellite: socket closed 
I/flutter (15904): [Electric] WARN:  10:50:11.784 Client disconnected with a non fatal error, reconnecting 
I/flutter (15904): [Electric] INFO:  10:50:11.785 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:50:11.900 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJmMGVjMTUzNi04NTU1LTRmNmYtYTI4ZS00M2FhNTJhYzk1ZWIifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:50:11.901 [proto] send: #SatRpcRequest{method: authenticate, requestId: 2} 
I/flutter (15904): [Electric] DEBUG: 10:50:12.947 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 2, error: #SatErrorResp{type: INVALID_REQUEST}} 
I/flutter (15904): [Electric] WARN:  10:50:12.948 RPC call authenticate/2 failed with #SatErrorResp{type: INVALID_REQUEST} 
I/flutter (15904): [Electric] DEBUG: 10:50:12.952 server returned an error while establishing connection: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] DEBUG: 10:50:12.953 connectAndStartRetryHandler was cancelled: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] WARN:  10:50:12.960 an error occurred in satellite: socket closed 
I/flutter (15904): [Electric] WARN:  10:50:12.962 Client disconnected with a non fatal error, reconnecting 
I/flutter (15904): [Electric] INFO:  10:50:12.963 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:50:12.984 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJmMGVjMTUzNi04NTU1LTRmNmYtYTI4ZS00M2FhNTJhYzk1ZWIifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:50:12.985 [proto] send: #SatRpcRequest{method: authenticate, requestId: 3} 
I/flutter (15904): [Electric] DEBUG: 10:50:14.171 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 3, error: #SatErrorResp{type: INVALID_REQUEST}} 
I/flutter (15904): [Electric] WARN:  10:50:14.172 RPC call authenticate/3 failed with #SatErrorResp{type: INVALID_REQUEST} 
I/flutter (15904): [Electric] DEBUG: 10:50:14.174 server returned an error while establishing connection: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] DEBUG: 10:50:14.175 connectAndStartRetryHandler was cancelled: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] WARN:  10:50:14.178 an error occurred in satellite: socket closed 
I/flutter (15904): [Electric] WARN:  10:50:14.178 Client disconnected with a non fatal error, reconnecting 
I/flutter (15904): [Electric] INFO:  10:50:14.179 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:50:14.206 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJmMGVjMTUzNi04NTU1LTRmNmYtYTI4ZS00M2FhNTJhYzk1ZWIifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:50:14.206 [proto] send: #SatRpcRequest{method: authenticate, requestId: 4} 
I/flutter (15904): [Electric] DEBUG: 10:50:15.400 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 4, error: #SatErrorResp{type: INVALID_REQUEST}} 
I/flutter (15904): [Electric] WARN:  10:50:15.401 RPC call authenticate/4 failed with #SatErrorResp{type: INVALID_REQUEST} 
I/flutter (15904): [Electric] DEBUG: 10:50:15.403 server returned an error while establishing connection: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] DEBUG: 10:50:15.405 connectAndStartRetryHandler was cancelled: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] WARN:  10:50:15.407 an error occurred in satellite: socket closed 
I/flutter (15904): [Electric] WARN:  10:50:15.408 Client disconnected with a non fatal error, reconnecting 
I/flutter (15904): [Electric] INFO:  10:50:15.408 connecting to electric server 
I/flutter (15904): [Electric] DEBUG: 10:50:15.445 [rpc] send: #SatAuthReq{id: 956a17af-751b-4f62-af5a-6dbbc13ecb2b, token: eyJhbGciOiJub25lIn0=.eyJzdWIiOiJmMGVjMTUzNi04NTU1LTRmNmYtYTI4ZS00M2FhNTJhYzk1ZWIifQ==.} 
I/flutter (15904): [Electric] DEBUG: 10:50:15.447 [proto] send: #SatRpcRequest{method: authenticate, requestId: 5} 
I/flutter (15904): [Electric] DEBUG: 10:50:16.627 [proto] recv: #SatRpcResponse{method: authenticate, requestId: 5, error: #SatErrorResp{type: INVALID_REQUEST}} 
I/flutter (15904): [Electric] WARN:  10:50:16.629 RPC call authenticate/5 failed with #SatErrorResp{type: INVALID_REQUEST} 
I/flutter (15904): [Electric] DEBUG: 10:50:16.632 server returned an error while establishing connection: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] DEBUG: 10:50:16.633 connectAndStartRetryHandler was cancelled: errorType: INVALID_REQUEST
I/flutter (15904):  
I/flutter (15904): [Electric] WARN:  10:50:16.636 an error occurred in satellite: socket closed 
I/flutter (15904): [Electric] WARN:  10:50:16.637 Client disconnected with a non fatal error, reconnecting 

# ^ Reconnection loop and exception happening until manual app termination

Application finished.

Exited (-1).

Stack log (server):

electric-1  | 08:48:49.122 pid=<0.4027.0> [info] GET /ws
electric-1  | 08:48:49.124 pid=<0.4027.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 1ms
electric-1  | 08:48:49.305 pid=<0.4027.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d user_id=c55f1f28-f743-47b7-b670-39f8b641893e [info] Successfully authenticated the client
electric-1  | 08:48:49.305 pid=<0.4027.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d user_id=c55f1f28-f743-47b7-b670-39f8b641893e [info] Postgres.Client.with_conn(%{database: ~c"todos_electrified", host: ~c"postgres", ip_addr: ~c"172.19.0.2", ipv6: false, nulls: [nil, :null, :undefined], password: ~c"******", port: 5432, ssl: false, ssl_opts: [server_name_indication: ~c"postgres"], timeout: 5000, username: ~c"postgres"})
electric-1  | 08:48:49.872 pid=<0.4032.0> [info] Postgres.Client.with_conn(%{database: ~c"todos_electrified", host: ~c"postgres", ip_addr: ~c"172.19.0.2", ipv6: false, nulls: [nil, :null, :undefined], password: ~c"******", port: 5432, ssl: false, ssl_opts: [server_name_indication: ~c"postgres"], timeout: 5000, username: ~c"postgres"})
electric-1  | 08:48:49.898 pid=<0.4034.0> [info] Postgres.Client.with_conn(%{database: ~c"todos_electrified", host: ~c"postgres", ip_addr: ~c"172.19.0.2", ipv6: false, nulls: [nil, :null, :undefined], password: ~c"******", port: 5432, ssl: false, ssl_opts: [server_name_indication: ~c"postgres"], timeout: 5000, username: ~c"postgres"})
electric-1  | 08:50:04.140 pid=<0.4027.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d user_id=c55f1f28-f743-47b7-b670-39f8b641893e [info] Client is not responding to ping, disconnecting
electric-1  | 08:50:09.532 pid=<0.4036.0> [info] GET /ws
electric-1  | 08:50:09.532 pid=<0.4036.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 194µs
electric-1  | 08:50:10.870 pid=<0.4036.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client
electric-1  | 08:50:11.338 pid=<0.4037.0> [info] GET /ws
electric-1  | 08:50:11.338 pid=<0.4037.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 246µs
electric-1  | 08:50:12.350 pid=<0.4037.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client
electric-1  | 08:50:12.419 pid=<0.4039.0> [info] GET /ws
electric-1  | 08:50:12.419 pid=<0.4039.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 189µs
electric-1  | 08:50:13.435 pid=<0.4039.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client
electric-1  | 08:50:13.641 pid=<0.4040.0> [info] GET /ws
electric-1  | 08:50:13.642 pid=<0.4040.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 377µs
electric-1  | 08:50:14.656 pid=<0.4040.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client
electric-1  | 08:50:14.879 pid=<0.4041.0> [info] GET /ws
electric-1  | 08:50:14.879 pid=<0.4041.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 170µs
electric-1  | 08:50:15.897 pid=<0.4041.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client
electric-1  | 08:50:16.099 pid=<0.4042.0> [info] GET /ws
electric-1  | 08:50:16.099 pid=<0.4042.0> instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] Sent 101 in 279µs
electric-1  | 08:50:17.119 pid=<0.4042.0> client_id=956a17af-751b-4f62-af5a-6dbbc13ecb2b instance_id=d4972d63-cc43-411c-b669-1a40bde4a74d [info] attempted multiple connections from the same client

[CLI] cant use custom .env file

Hello, im trying to do custom stats.env file to be processed when running generate, but its loading always the default one.
When i try with-config, then i have to specify everything in the command and its not convenient and also i experienced, that its not using it sometimes and loading default.

Why i need it is to have 2 databases (with 2 electrics, because "Specifically, right now, ElectricSQL works with a single database in a single Postgres installation with tables in the public schema.") and to properly generate schemas, it would be handy.

Is there an option to load custom env files like this?

#!/bin/bash

#Load environment file called chat.env
source ./stats.env

dart run ./electricsql_cli show-config

Error when Satellite performs a Snapshot after DB Connection has been closed

Hello there 👋
I am slowly implementing electricsql in my app. Very promising 🚀

I've started some unit tests.
They are relatively quick and small.

When tearing down those tests, I close the electric client and the database (drift):

await electricClient.close();
await database.close();

However, even if the test passes, I see error logs:

CouldNotRollBackException: Bad state: Tried to send Request (id = 57): RunTransactionAction(TransactionControl.rollback, 5) over isolate channel, but the connection was closed!. 
For context: The transaction was rolled back because of Instance of 'ConnectionClosedException', which was thrown here: 
...
package:electricsql/src/drivers/drift/drift_adapter.dart 57:19   DriftAdapter.transaction.<fn>.<fn>
...
===== asynchronous gap ===========================
...
package:electricsql/src/drivers/drift/drift_adapter.dart 114:8   Transaction.run
package:electricsql/src/satellite/process.dart 1037:29           SatelliteProcess.performSnapshot.<fn>.<fn>.<fn>
...
===== asynchronous gap ===========================
...
package:electricsql/src/satellite/process.dart 142:14            SatelliteProcess._mutexSnapshot.<fn>
...
===== asynchronous gap ===========================
...
package:electricsql/src/drivers/drift/drift.dart 42:15           electrify

(logs cleared for clarity)

Any idea how to fix that? Happy to contribute if someone point me a direction 🙂

Bad state: No element when generating tables.

dart run electricsql_cli generate       
Generating the Electric client code...
Service URL: http://localhost:5133
Proxy URL: postgresql://prisma:********@IP:65432/electric
✓ Prisma CLI installed (1.4s)
✓ Database introspected (0.6s)
✗ Generating Drift DB schema (14ms)
generate command failed: Bad state: No element
Unhandled exception:
Bad state: No element
#0      ListBase.firstWhere (dart:collection/list.dart:132:5)
#1      _getPrismaRelationValue (package:electricsql_cli/src/commands/generate/prisma.dart:421:25)
#2      _extractOutgoindRelation (package:electricsql_cli/src/commands/generate/prisma.dart:364:24)
#3      _extractFromModel (package:electricsql_cli/src/commands/generate/prisma.dart:289:11)
#4      extractInfoFromPrismaSchema.<anonymous closure> (package:electricsql_cli/src/commands/generate/prisma.dart:172:25)
#5      MappedListIterable.elementAt (dart:_internal/iterable.dart:425:31)
#6      ListIterator.moveNext (dart:_internal/iterable.dart:354:26)
#7      new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)
#8      new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#9      new List.of (dart:core-patch/array_patch.dart:39:18)
#10     ListIterable.toList (dart:_internal/iterable.dart:224:7)
#11     extractInfoFromPrismaSchema (package:electricsql_cli/src/commands/generate/prisma.dart:186:6)
#12     _generateClient (package:electricsql_cli/src/commands/generate/command.dart:370:22)
<asynchronous suspension>
#13     wrapWithProgress (package:electricsql_cli/src/util.dart:142:17)
<asynchronous suspension>
#14     _runGeneratorInner (package:electricsql_cli/src/commands/generate/command.dart:338:5)
<asynchronous suspension>
#15     _runGenerator (package:electricsql_cli/src/commands/generate/command.dart:275:5)
<asynchronous suspension>
#16     runElectricCodeGeneration (package:electricsql_cli/src/commands/generate/command.dart:154:3)
<asynchronous suspension>
#17     GenerateElectricClientCommand.run (package:electricsql_cli/src/commands/generate/command.dart:95:5)
<asynchronous suspension>
#18     CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#19     ElectricCliCommandRunner.runCommand (package:electricsql_cli/src/command_runner.dart:124:18)
<asynchronous suspension>
#20     ElectricCliCommandRunner.run (package:electricsql_cli/src/command_runner.dart:65:14)
<asynchronous suspension>
#21     main (file:///Users/user/.pub-cache/hosted/pub.dev/electricsql_cli-0.6.0/bin/electricsql_cli.dart:6:24)

Version 0.6.0

Not updating views with streambuilder

I am using plain flutter, without flutter_hooks, riverpod and dont know how to reflect data in the UI.
I see that its getting into the client via console debug mode, when i open the local db, the data is there.

im using simple, which loads data properly, when its updated in backend db, its the same, when i do hot reload, then its updated.

StreamBuilder<Stat>(
        stream: StatsDAO(db!).watchStat(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text('loading');
          }
          if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          }
          if (snapshot.hasData && snapshot.data != null) {
            final stat = snapshot.data;
            return Text(
              "${stat?.content}",
            );
          }

          return const Text('No stat');
        },
      )

How can we do this with plain flutter?

Offine First, Sync Optional

Can this be used as a simple Offline First solution without syncing? Syncing requires another host (I am using Supabase) is that correct? What if all I care about is offline capability? What if there is no need to sync? Just simply be able to work offline and have it push to Supabase when back online?

Thanks for the hard work, this is great stuff

[How to] Use the latest master version, skipping the pub.dev

Sharing an small how to use the latest master version in your flutter project (omitting the pub.dev) you can modify the pubspec.yaml as follows:

dependencies:
  electricsql:
     git:
       url: https://github.com/SkillDevs/electric_dart.git
       ref: master
       path: packages/electricsql/
  electricsql_flutter:
    git:
      url: https://github.com/SkillDevs/electric_dart.git
      ref: master
      path: packages/electricsql_flutter/

dev_dependencies:
  electricsql_cli:
    git:
      url: https://github.com/SkillDevs/electric_dart.git
      ref: master
      path: packages/electricsql_cli/

dependency_overrides:
  electricsql:
    git:
      url: https://github.com/SkillDevs/electric_dart.git
      ref: master
      path: packages/electricsql/

Supabase example

Electric v0.8 and the Electric Dart client v0.4+ now support Supabase for authentication and for the Postgres data synchronization.

It would be great to have an example that uses Supabase authentication supabase_auth_ui + a simple database schema that synchronizes with the Supabase Postgres.

For inspiration, the official Typescript client has a Checkout example, which uses auth and edge functions https://electric-sql.com/docs/examples/checkout

Contributions are welcome!

Electric custom types (eg, Postgres date type) not generating correct SQL for query.

All ElectricTypes custom types currently implement DialectAwareSqlType via CustomElectricTypeGeneric. Which is great, but there is currently a bug in drift which, when creating variables via query builders, it does not correctly pass through the electric type as the helper is checking against CustomSqlType and not UserDefinedSqlType.

See: https://github.com/SkillDevs/electric_dart/blob/master/packages/electricsql/lib/src/client/conversions/custom_types.dart

Helper:

/// Utilities to derive other expressions with a type compatible to `this`
/// expression.
extension WithTypes<T extends Object> on Expression<T> {
  /// Creates a variable with a matching [driftSqlType].
  Variable<T> variable(T? value) {
    return switch (driftSqlType) {
      CustomSqlType<T> custom => Variable(value, custom),
      _ => Variable(value),
    };
  }
}

I've currently opened a PR to type-check against UserDefinedSqlType instead of CustomSqlType as that is what the Variable constructor is expecting: simolus3/drift#2909

This is more of an FYI issue as queries on for example the Postgres date type are currently not working in Electric Dart.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.