@jcbuisson/express-x-plugins 4.0.4 → 4.0.5

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 CHANGED
@@ -1,23 +1,43 @@
1
- # express-x-electric
1
+ # express-x-plugins
2
+
3
+ Currently includes:
4
+
5
+ - a plugin which preserves room membership and socket data across page reloads
6
+ - a plugin integrating ElectricSQL sync engine into express-x, which greatly simplifies relational database
7
+ access and provides powerful local-first features
2
8
 
3
- The smallest useful ElectricSQL integration for Express-X. Express-X handles
4
- authorized PostgreSQL mutations; Electric's Shape API streams those changes to
5
- clients: Electric is the sync engine.
6
9
 
7
10
  ## Install
8
11
 
9
12
  ```sh
10
- npm install @jcbuisson/express-x-electric pg
13
+ npm install @jcbuisson/express-x-plugins
11
14
  ```
12
15
 
13
- This server-only installation does not install the browser Electric client or RxJS.
14
16
 
15
- ## Server
17
+ ## Reload plugin
18
+
19
+ ### Server
20
+
21
+ ```js
22
+ import { reloadPlugin } from '@jcbuisson/express-x-plugins/reload-server'
23
+ ```
24
+
25
+
26
+ ## Local-first Postgres plugin
27
+
28
+ The smallest useful ElectricSQL integration for Express-X. Express-X handles authorized PostgreSQL mutations;
29
+ Electric's Shape API streams those changes to clients: Electric is the sync engine.
30
+
31
+ ### Server
32
+
33
+ ```sh
34
+ npm install pg
35
+ ```
16
36
 
17
37
  ```js
18
38
  import { Pool } from 'pg'
19
- import { expressX } from '@jcbuisson/express-x'
20
- import { electricOfflinePlugin } from '@jcbuisson/express-x-electric'
39
+ import { expressX } from '@jcbuisson/express-x/server'
40
+ import { electricOfflinePlugin } from '@jcbuisson/express-x-plugins/electric-server'
21
41
 
22
42
  const app = expressX()
23
43
  const db = new Pool({ connectionString: process.env.DATABASE_URL })
@@ -49,16 +69,16 @@ Mutation results remain `[value, meta]` tuples for compatibility. `meta.txid`
49
69
  contains `pg_current_xact_id()` and can be passed to an Electric-aware client to
50
70
  wait for the matching transaction in its Shape stream.
51
71
 
52
- ## Client Shape
72
+ ### Client
53
73
 
54
74
  Install the optional client dependencies in the browser application:
55
75
 
56
76
  ```sh
57
- npm install @jcbuisson/express-x-electric @electric-sql/client rxjs vue
77
+ npm install @electric-sql/client rxjs
58
78
  ```
59
79
 
60
80
  ```js
61
- import { electricClientPlugin } from '@jcbuisson/express-x-electric/client'
81
+ import { electricClientPlugin } from '@jcbuisson/express-x-plugins/electric-client'
62
82
 
63
83
  app.configure(electricClientPlugin, {
64
84
  shapePath: '/electric/v1/shape',
@@ -93,7 +113,7 @@ Object filters use parameterized Electric Shape predicates. Exact values,
93
113
  All Electric cursor parameters are forwarded. The client cannot override the
94
114
  configured table, and Electric source credentials stay server-side.
95
115
 
96
- ## Model configuration
116
+ ### Model configuration
97
117
 
98
118
  Models may be strings (table, service name, and default `uid` key) or objects:
99
119
 
@@ -108,7 +128,7 @@ Requires Node 18+ for the built-in Fetch API. The PostgreSQL client only needs a
108
128
  `query(sql, values)` method; a `pg.Pool` is recommended so each mutation and its
109
129
  transaction ID are captured in the same transaction.
110
130
 
111
- ## Run Electric from Docker
131
+ ### Run Electric from Docker
112
132
 
113
133
  A local install of the Electric sync engine requires Elixir and Erlang; it is simpler to use a pre-built Docker image.
114
134
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcbuisson/express-x-plugins",
3
- "version": "4.0.4",
3
+ "version": "4.0.5",
4
4
  "description": "Plugins for express-x",
5
5
  "type": "module",
6
6
  "main": "./src/electric-server-plugin.mjs",
@@ -10,6 +10,7 @@ import { getCurrentScope, onScopeDispose, ref } from 'vue'
10
10
  * electricClientPlugin(app)
11
11
  * const todo = app.createElectricModel('todos')
12
12
  * todo.getObservable({ completed: false }).subscribe(...)
13
+ * const completedTodos = await todo.findMany({ completed: false })
13
14
  */
14
15
  export function electricClientPlugin(app, options = {}) {
15
16
  const shapePath = options.shapePath ?? '/electric/v1/shape'
@@ -47,13 +48,6 @@ export function electricClientPlugin(app, options = {}) {
47
48
  })
48
49
  }
49
50
 
50
- function getVueRef(where = {}) {
51
- const value = ref([])
52
- const subscription = getObservable(where).subscribe(rows => { value.value = rows })
53
- if (getCurrentScope()) onScopeDispose(() => subscription.unsubscribe())
54
- return value
55
- }
56
-
57
51
  function findMany(where = {}) {
58
52
  const observable = getObservable(where)
59
53
  if (!getCurrentScope()) return firstValueFrom(observable)
@@ -66,10 +60,6 @@ export function electricClientPlugin(app, options = {}) {
66
60
  return firstValueFrom(observable.pipe(takeUntil(scopeDisposed)))
67
61
  }
68
62
 
69
- function findUnique(where = {}) {
70
- return findMany(where).then(rows => rows[0] ?? null)
71
- }
72
-
73
63
  async function create(data) {
74
64
  assertPlainObject(data, 'mutation data')
75
65
  const uid = globalThis.crypto?.randomUUID?.()
@@ -89,7 +79,7 @@ export function electricClientPlugin(app, options = {}) {
89
79
  return value
90
80
  }
91
81
 
92
- return { getObservable, getVueRef, findMany, findUnique, create, update, remove }
82
+ return { getObservable, findMany, create, update, remove }
93
83
  }
94
84
 
95
85
  return Object.assign(app, { createElectricModel })