@eventmodelers/cli 1.0.6 → 1.0.7

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/cli.js CHANGED
@@ -1430,7 +1430,9 @@ async function runModeling(kitDir, projectDir, verbose = false) {
1430
1430
  log(`channel "${channelName}": ${status}`);
1431
1431
  if (status === 'SUBSCRIBED') drain().catch((err) => log(`initial drain error: ${err.message}`));
1432
1432
  },
1433
- );
1433
+ ).catch((err) => {
1434
+ log(`realtime subscribe failed, prompts won't be pushed live: ${err.message}`);
1435
+ });
1434
1436
 
1435
1437
  setInterval(async () => {
1436
1438
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, or modeling-only)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,6 +7,15 @@
7
7
 
8
8
  const REALTIME_EVENTS_COLLECTION = 'realtime_events';
9
9
 
10
+ // Same backoff steps the PocketBase SDK uses for its own reconnects (see
11
+ // predefinedReconnectIntervals in the SDK) — reused here because the SDK only
12
+ // applies that backoff to a connection that drops *after* it was established.
13
+ // A failed first handshake (e.g. "Invalid realtime client" from the initial
14
+ // GET /api/realtime and the follow-up subscribe POST landing on different
15
+ // backend instances) rejects immediately with no retry at all, so we retry it
16
+ // ourselves.
17
+ const RECONNECT_INTERVALS_MS = [200, 300, 500, 1000, 1200, 1500, 2000];
18
+
10
19
  export async function createPocketBaseRealtimeAdapter(cfg, initialToken) {
11
20
  const { EventSource } = await import('eventsource');
12
21
  if (!globalThis.EventSource) globalThis.EventSource = EventSource; // PocketBase's SDK assumes a browser-style global
@@ -16,11 +25,20 @@ export async function createPocketBaseRealtimeAdapter(cfg, initialToken) {
16
25
 
17
26
  return {
18
27
  async subscribe(topic, handlers, onStatus) {
19
- await pb.collection(REALTIME_EVENTS_COLLECTION).subscribe('*', (e) => {
20
- if (e.action !== 'create' || e.record.topic !== topic) return;
21
- handlers[e.record.event]?.(e.record.payload);
22
- });
23
- onStatus?.('SUBSCRIBED');
28
+ for (let attempt = 0; ; attempt++) {
29
+ try {
30
+ await pb.collection(REALTIME_EVENTS_COLLECTION).subscribe('*', (e) => {
31
+ if (e.action !== 'create' || e.record.topic !== topic) return;
32
+ handlers[e.record.event]?.(e.record.payload);
33
+ });
34
+ onStatus?.('SUBSCRIBED');
35
+ return;
36
+ } catch (err) {
37
+ if (attempt >= RECONNECT_INTERVALS_MS.length) throw err;
38
+ onStatus?.(`RECONNECTING (attempt ${attempt + 1}/${RECONNECT_INTERVALS_MS.length}): ${err.message}`);
39
+ await new Promise((resolve) => setTimeout(resolve, RECONNECT_INTERVALS_MS[attempt]));
40
+ }
41
+ }
24
42
  },
25
43
  setAuth(token) {
26
44
  pb.authStore.save(token, null);