@statezero/core 0.2.58 → 0.2.59

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.
@@ -2,11 +2,11 @@ import { ref as J, computed as I, onMounted as hs, onBeforeUnmount as fs, watch
2
2
  import { v7 as B } from "uuid";
3
3
  import { isNil as b, isEmpty as Te, trim as dt, isEqual as He } from "lodash-es";
4
4
  import Oe from "mitt";
5
- import Ft from "handlebars";
6
- import Pt from "superjson";
5
+ import Pt from "handlebars";
6
+ import Ft from "superjson";
7
7
  import ps from "p-queue";
8
8
  import ms from "axios";
9
- import { z as $ } from "zod";
9
+ import { z as O } from "zod";
10
10
  import ys from "pusher-js";
11
11
  import Wt, { createEqualsOperation as ee } from "sift";
12
12
  import { DateTime as _e } from "luxon";
@@ -47,9 +47,9 @@ function Je(n) {
47
47
  const e = Object.fromEntries(se);
48
48
  try {
49
49
  if (typeof n == "string")
50
- return Ft.compile(n, { noEscape: !0 })(e);
51
- const t = Pt.stringify(n), r = Ft.compile(t, { noEscape: !0 })(e);
52
- return Pt.parse(r);
50
+ return Pt.compile(n, { noEscape: !0 })(e);
51
+ const t = Ft.stringify(n), r = Pt.compile(t, { noEscape: !0 })(e);
52
+ return Ft.parse(r);
53
53
  } catch {
54
54
  return n;
55
55
  }
@@ -363,7 +363,7 @@ class Ss {
363
363
  */
364
364
  _loadOperations(e) {
365
365
  e.forEach((t) => {
366
- const s = Fe.get(t.operationId);
366
+ const s = Pe.get(t.operationId);
367
367
  s ? this.operationsMap.set(s.operationId, s) : this.operationsMap.set(t.operationId, new q(t, !0));
368
368
  });
369
369
  }
@@ -480,7 +480,7 @@ class Ss {
480
480
  if (r.push(...Array.from(s.values())), this.groundTruthArray = r, i.length > 0) {
481
481
  const l = /* @__PURE__ */ new Set();
482
482
  for (const c of this.operations)
483
- if ((c.type === P.UPDATE || c.type === P.UPDATE_INSTANCE) && c.status !== C.CONFIRMED && c.status !== C.REJECTED)
483
+ if ((c.type === F.UPDATE || c.type === F.UPDATE_INSTANCE) && c.status !== C.CONFIRMED && c.status !== C.REJECTED)
484
484
  for (const h of c.instances)
485
485
  h && h[t] != null && l.add(h[t]);
486
486
  const a = i.filter(
@@ -489,7 +489,7 @@ class Ss {
489
489
  if (a.length > 0) {
490
490
  const c = new q({
491
491
  operationId: `checkpoint_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
492
- type: P.CHECKPOINT,
492
+ type: F.CHECKPOINT,
493
493
  instances: a,
494
494
  status: C.CONFIRMED,
495
495
  timestamp: Date.now(),
@@ -553,21 +553,21 @@ class Ss {
553
553
  }
554
554
  let o = r[s];
555
555
  switch (e.type) {
556
- case P.CREATE:
557
- case P.BULK_CREATE:
556
+ case F.CREATE:
557
+ case F.BULK_CREATE:
558
558
  t.has(o) || t.set(o, r);
559
559
  break;
560
- case P.CHECKPOINT:
561
- case P.UPDATE_INSTANCE:
562
- case P.UPDATE: {
560
+ case F.CHECKPOINT:
561
+ case F.UPDATE_INSTANCE:
562
+ case F.UPDATE: {
563
563
  const i = t.get(o);
564
564
  i ? t.set(o, { ...i, ...r }) : this.operations.some(
565
- (a) => a.type === P.DELETE && a.status !== C.REJECTED && a.instances.some((c) => c && c[s] === o)
565
+ (a) => a.type === F.DELETE && a.status !== C.REJECTED && a.instances.some((c) => c && c[s] === o)
566
566
  ) || t.set(o, r);
567
567
  break;
568
568
  }
569
- case P.DELETE_INSTANCE:
570
- case P.DELETE:
569
+ case F.DELETE_INSTANCE:
570
+ case F.DELETE:
571
571
  t.delete(o);
572
572
  break;
573
573
  default:
@@ -726,7 +726,7 @@ const j = new Ve(), ie = Oe(), C = {
726
726
  REJECTED: "operation:rejected",
727
727
  CLEAR: "clear:all",
728
728
  MUTATED: "operation:mutated"
729
- }, P = {
729
+ }, F = {
730
730
  CREATE: "create",
731
731
  BULK_CREATE: "bulk_create",
732
732
  UPDATE: "update",
@@ -763,7 +763,7 @@ class q {
763
763
  throw new Error(`All operation instances must be objects with the '${o}' field`);
764
764
  this.#e = r;
765
765
  const i = r.map((a) => a[o]);
766
- j.getStore(s).render(i, !0, !1), this.#t = r.map((a) => s.fromPk(a[o]).serialize()), this.timestamp = e.timestamp || Date.now(), !t && (Fe.register(this), ie.emit(C.CREATED, this));
766
+ j.getStore(s).render(i, !0, !1), this.#t = r.map((a) => s.fromPk(a[o]).serialize()), this.timestamp = e.timestamp || Date.now(), !t && (Pe.register(this), ie.emit(C.CREATED, this));
767
767
  }
768
768
  /**
769
769
  * Getter for instances that replaces any temporary PKs with real PKs
@@ -915,7 +915,7 @@ class Ts {
915
915
  return t.length > 0 ? t[t.length - 1] : void 0;
916
916
  }
917
917
  }
918
- const Fe = new Ts(), Ms = Oe();
918
+ const Pe = new Ts(), Ms = Oe();
919
919
  function As(n) {
920
920
  Ms.emit("error", n);
921
921
  }
@@ -1029,7 +1029,7 @@ class U extends fe {
1029
1029
  super("Configuration error", "config_error", e, t), this.name = "ConfigError";
1030
1030
  }
1031
1031
  }
1032
- function Fs(n) {
1032
+ function Ps(n) {
1033
1033
  const { status: e, type: t, detail: s, data: r } = n;
1034
1034
  if (t === void 0 && s === "Invalid token.")
1035
1035
  return new lt(s, 403);
@@ -1072,7 +1072,7 @@ const xt = {
1072
1072
  BULK_UPDATE: "bulk_update",
1073
1073
  BULK_DELETE: "bulk_delete"
1074
1074
  };
1075
- class Ps {
1075
+ class Fs {
1076
1076
  /**
1077
1077
  * @param {PusherReceiverOptions} options
1078
1078
  * @param {string} configKey - The backend configuration key
@@ -1082,12 +1082,13 @@ class Ps {
1082
1082
  this.configKey = t, this.connectionTimeoutId = null, s.appKey && /^\d+$/.test(s.appKey) && s.appKey.length < 15 && console.warn(
1083
1083
  `%c[Pusher Warning] The provided appKey ("${s.appKey}") looks like a numeric app_id. Pusher requires the alphanumeric key, not the ID. Please verify your configuration for backend: "${this.configKey}".`,
1084
1084
  "color: orange; font-weight: bold; font-size: 14px;"
1085
- ), this.pusherClient = new ys(s.appKey, {
1086
- cluster: s.cluster,
1085
+ );
1086
+ const l = {
1087
1087
  forceTLS: s.forceTLS ?? !0,
1088
1088
  authEndpoint: s.authEndpoint,
1089
1089
  auth: { headers: s.getAuthHeaders?.() || {} }
1090
- }), this.pusherClient.connection.bind("connected", () => {
1090
+ };
1091
+ s.wsHost ? (l.wsHost = s.wsHost, l.wsPort = s.wsPort ?? 443, l.wssPort = s.wssPort ?? 443, l.enabledTransports = s.enabledTransports ?? ["ws", "wss"]) : l.cluster = s.cluster, this.pusherClient = new ys(s.appKey, l), this.pusherClient.connection.bind("connected", () => {
1091
1092
  console.log(
1092
1093
  `Pusher client connected successfully for backend: ${this.configKey}.`
1093
1094
  ), this.connectionTimeoutId && (clearTimeout(this.connectionTimeoutId), this.connectionTimeoutId = null);
@@ -1097,7 +1098,7 @@ class Ps {
1097
1098
  this.pusherClient.connection.state !== "connected" && this._logConnectionError(
1098
1099
  `Pusher connection timed out after ${i / 1e3} seconds.`
1099
1100
  );
1100
- }, i), this.formatChannelName = r ?? ((l) => `private-${l}`), this.namespaceResolver = o ?? ((l) => l), this.channels = /* @__PURE__ */ new Map(), this.eventHandlers = /* @__PURE__ */ new Set();
1101
+ }, i), this.formatChannelName = r ?? ((a) => `private-${a}`), this.namespaceResolver = o ?? ((a) => a), this.channels = /* @__PURE__ */ new Map(), this.eventHandlers = /* @__PURE__ */ new Set();
1101
1102
  }
1102
1103
  /**
1103
1104
  * @private
@@ -1233,53 +1234,60 @@ function zs() {
1233
1234
  let Ut = {
1234
1235
  backendConfigs: {}
1235
1236
  };
1236
- const Rs = $.object({
1237
- clientOptions: $.object({
1238
- appKey: $.string({ required_error: "Pusher appKey is required" }),
1239
- cluster: $.string({ required_error: "Pusher cluster is required" }),
1240
- forceTLS: $.boolean().optional(),
1241
- authEndpoint: $.string().url("Pusher authentication endpoint URL is required"),
1242
- getAuthHeaders: $.function().optional().refine(
1237
+ const Rs = O.object({
1238
+ clientOptions: O.object({
1239
+ appKey: O.string({ required_error: "Pusher appKey is required" }),
1240
+ cluster: O.string().optional(),
1241
+ wsHost: O.string().optional(),
1242
+ wsPort: O.number().optional(),
1243
+ wssPort: O.number().optional(),
1244
+ enabledTransports: O.array(O.string()).optional(),
1245
+ forceTLS: O.boolean().optional(),
1246
+ authEndpoint: O.string().url("Pusher authentication endpoint URL is required"),
1247
+ getAuthHeaders: O.function().optional().refine(
1243
1248
  (n) => n === void 0 || typeof n == "function",
1244
1249
  "getAuthHeaders must be a function if provided"
1245
1250
  )
1246
- })
1247
- }), Ks = $.object({
1248
- type: $.enum(["websocket", "pusher", "none"]),
1249
- websocketUrl: $.string().url().optional(),
1251
+ }).refine(
1252
+ (n) => n.cluster || n.wsHost,
1253
+ "Either cluster or wsHost must be provided"
1254
+ )
1255
+ }), Ks = O.object({
1256
+ type: O.enum(["websocket", "pusher", "none"]),
1257
+ websocketUrl: O.string().url().optional(),
1250
1258
  pusher: Rs.optional(),
1251
- hotpaths: $.array($.string()).default(["default"])
1259
+ hotpaths: O.array(O.string()).default(["default"])
1252
1260
  }).superRefine((n, e) => {
1253
1261
  n.type === "websocket" && (n.websocketUrl || e.addIssue({
1254
- code: $.ZodIssueCode.custom,
1262
+ code: O.ZodIssueCode.custom,
1255
1263
  path: ["websocketUrl"],
1256
1264
  message: "WebSocket URL is required for WebSocket event receiver"
1257
1265
  })), n.type === "pusher" && (n.pusher || e.addIssue({
1258
- code: $.ZodIssueCode.custom,
1266
+ code: O.ZodIssueCode.custom,
1259
1267
  path: ["pusher"],
1260
1268
  message: "Pusher configuration is required for Pusher event receiver"
1261
1269
  }));
1262
- }), Be = $.object({
1263
- API_URL: $.string().url("API_URL must be a valid URL"),
1264
- GENERATED_TYPES_DIR: $.string({
1270
+ }), Be = O.object({
1271
+ API_URL: O.string().url("API_URL must be a valid URL"),
1272
+ GENERATED_TYPES_DIR: O.string({
1265
1273
  required_error: "GENERATED_TYPES_DIR is required"
1266
1274
  }),
1267
- GENERATED_ACTIONS_DIR: $.string().optional(),
1268
- BACKEND_TZ: $.string().optional(),
1269
- SYNC_TOKEN: $.string().optional(),
1270
- fileRootURL: $.string().url("fileRootURL must be a valid URL").optional(),
1271
- fileUploadMode: $.enum(["server", "s3"]).default("server"),
1272
- getAuthHeaders: $.function().optional().refine(
1275
+ GENERATED_ACTIONS_DIR: O.string().optional(),
1276
+ BACKEND_TZ: O.string().optional(),
1277
+ SYNC_TOKEN: O.string().optional(),
1278
+ fileRootURL: O.string().url("fileRootURL must be a valid URL").optional(),
1279
+ fileUploadMode: O.enum(["server", "s3"]).default("server"),
1280
+ getAuthHeaders: O.function().optional().refine(
1273
1281
  (n) => n === void 0 || typeof n == "function",
1274
1282
  "getAuthHeaders must be a function if provided"
1275
1283
  ),
1276
- eventInterceptor: $.function().optional().refine(
1284
+ eventInterceptor: O.function().optional().refine(
1277
1285
  (n) => n === void 0 || typeof n == "function",
1278
1286
  "eventInterceptor must be a function if provided"
1279
1287
  ),
1280
- events: $.lazy(() => Ks.optional())
1281
- }), Is = $.object({
1282
- backendConfigs: $.record($.string(), Be).refine(
1288
+ events: O.lazy(() => Ks.optional())
1289
+ }), Is = O.object({
1290
+ backendConfigs: O.record(O.string(), Be).refine(
1283
1291
  (n) => {
1284
1292
  for (const [e, t] of Object.entries(n))
1285
1293
  if (!Be.safeParse(t).success)
@@ -1298,7 +1306,7 @@ const Rs = $.object({
1298
1306
  return { message: e.join("; ") };
1299
1307
  }
1300
1308
  ),
1301
- periodicSyncIntervalSeconds: $.number().min(5).nullable().optional().default(null)
1309
+ periodicSyncIntervalSeconds: O.number().min(5).nullable().optional().default(null)
1302
1310
  });
1303
1311
  let ht = null;
1304
1312
  function Ns(n) {
@@ -1352,7 +1360,7 @@ function Yt(n = "default") {
1352
1360
  ...t.events.pusher.clientOptions,
1353
1361
  getAuthHeaders: i
1354
1362
  };
1355
- s = new Ps({ clientOptions: l }, n);
1363
+ s = new Fs({ clientOptions: l }, n);
1356
1364
  break;
1357
1365
  case "none":
1358
1366
  return null;
@@ -1556,8 +1564,8 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1556
1564
  query: _,
1557
1565
  serializerOptions: y
1558
1566
  }
1559
- }, v = w?.ast?.serializerOptions?.limit, O = w?.ast?.serializerOptions?.overfetch || 10;
1560
- v && O && (w.ast.serializerOptions.limit = v + O);
1567
+ }, v = w?.ast?.serializerOptions?.limit, $ = w?.ast?.serializerOptions?.overfetch || 10;
1568
+ v && $ && (w.ast.serializerOptions.limit = v + $);
1561
1569
  const k = [
1562
1570
  "create",
1563
1571
  "bulk_create",
@@ -1567,7 +1575,7 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1567
1575
  "delete_instance",
1568
1576
  "get_or_create",
1569
1577
  "update_or_create"
1570
- ].includes(e), Q = `${p.API_URL.replace(/\/+$/, "")}/${c.modelName}/`, N = p.getAuthHeaders ? p.getAuthHeaders() : {}, F = n.semanticKey;
1578
+ ].includes(e), Q = `${p.API_URL.replace(/\/+$/, "")}/${c.modelName}/`, N = p.getAuthHeaders ? p.getAuthHeaders() : {}, P = n.semanticKey;
1571
1579
  s && (N["X-Operation-ID"] = s), o && (N["X-Canonical-ID"] = o);
1572
1580
  const re = async () => {
1573
1581
  try {
@@ -1575,7 +1583,7 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1575
1583
  type: "request",
1576
1584
  modelName: c.modelName,
1577
1585
  configKey: c.configKey,
1578
- semanticKey: F,
1586
+ semanticKey: P,
1579
1587
  operationType: e,
1580
1588
  operationId: s,
1581
1589
  canonicalId: o,
@@ -1601,7 +1609,7 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1601
1609
  type: "response",
1602
1610
  modelName: c.modelName,
1603
1611
  configKey: c.configKey,
1604
- semanticKey: F,
1612
+ semanticKey: P,
1605
1613
  operationType: e,
1606
1614
  operationId: s,
1607
1615
  canonicalId: o,
@@ -1619,7 +1627,7 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1619
1627
  type: "error",
1620
1628
  modelName: c.modelName,
1621
1629
  configKey: c.configKey,
1622
- semanticKey: F,
1630
+ semanticKey: P,
1623
1631
  operationType: e,
1624
1632
  operationId: s,
1625
1633
  canonicalId: o,
@@ -1631,7 +1639,7 @@ async function V(n, e, t = {}, s, r = null, o = null, i = {}) {
1631
1639
  throw new Error(`${D} (${Q})`);
1632
1640
  }
1633
1641
  if (z.response && z.response.data) {
1634
- const D = Fs(z.response.data);
1642
+ const D = Ps(z.response.data);
1635
1643
  throw Error.captureStackTrace && Error.captureStackTrace(D, V), D;
1636
1644
  }
1637
1645
  throw new Error(`API call failed: ${z.message}`);
@@ -1966,11 +1974,11 @@ function ze(n, e, t, s = {}) {
1966
1974
  E === "pk" && p && (E = p.primaryKeyField);
1967
1975
  const Q = k === c.length - 1;
1968
1976
  if (p && p.relationshipFields && p.relationshipFields instanceof Map && p.relationshipFields.has(E)) {
1969
- const N = p.relationshipFields.get(E), F = N.ModelClass(), re = N.relationshipType;
1977
+ const N = p.relationshipFields.get(E), P = N.ModelClass(), re = N.relationshipType;
1970
1978
  if (!Q && re === "many-to-many") {
1971
1979
  let ae = c.slice(k + 1).join("__");
1972
1980
  a.length > 0 ? ae += "__" + a.join("__") : h && (ae += "__" + h);
1973
- const z = ze(ae, e, F, s), D = m.length > 0 ? m.join(".") + "." + E : E, K = z.requiredPath || z.field, me = `${D}.${K}`;
1981
+ const z = ze(ae, e, P, s), D = m.length > 0 ? m.join(".") + "." + E : E, K = z.requiredPath || z.field, me = `${D}.${K}`;
1974
1982
  return {
1975
1983
  field: D,
1976
1984
  operator: { $elemMatch: { [z.field]: z.operator } },
@@ -1980,23 +1988,23 @@ function ze(n, e, t, s = {}) {
1980
1988
  };
1981
1989
  }
1982
1990
  if (m.push(E), !Q)
1983
- p = F;
1991
+ p = P;
1984
1992
  else {
1985
1993
  if (y = !0, re === "many-to-many")
1986
1994
  _ = !0, w = E;
1987
1995
  else {
1988
- const pe = F.primaryKeyField || "id";
1996
+ const pe = P.primaryKeyField || "id";
1989
1997
  m.push(pe), w = pe;
1990
1998
  }
1991
- p = F;
1999
+ p = P;
1992
2000
  }
1993
2001
  } else if (p && p.fields && p.fields.includes(E)) {
1994
2002
  if (m.push(E), w = E, Q)
1995
2003
  break;
1996
2004
  const N = p.schema?.properties?.[E];
1997
2005
  if (N && N.format === "json") {
1998
- const F = c.slice(k + 1);
1999
- m.push(...F);
2006
+ const P = c.slice(k + 1);
2007
+ m.push(...P);
2000
2008
  break;
2001
2009
  }
2002
2010
  throw new Error(`Field '${E}' in '${n}' is not a relationship field and cannot be traversed.`);
@@ -2193,17 +2201,17 @@ function tr(n = "UTC", e = null) {
2193
2201
  if (!y || !(y instanceof Date) || isNaN(y.getTime()))
2194
2202
  return !1;
2195
2203
  const _ = _e.fromJSDate(y).setZone(n);
2196
- let w, v, O;
2204
+ let w, v, $;
2197
2205
  if (typeof a == "string") {
2198
2206
  const T = a.split(":");
2199
- w = parseInt(T[0], 10), v = parseInt(T[1], 10), O = parseInt(T[2], 10);
2207
+ w = parseInt(T[0], 10), v = parseInt(T[1], 10), $ = parseInt(T[2], 10);
2200
2208
  } else {
2201
2209
  const T = s(a, m);
2202
2210
  if (!T) return !1;
2203
2211
  const k = _e.fromJSDate(T).setZone(n);
2204
- w = k.hour, v = k.minute, O = k.second;
2212
+ w = k.hour, v = k.minute, $ = k.second;
2205
2213
  }
2206
- return _.hour === w && _.minute === v && _.second === O;
2214
+ return _.hour === w && _.minute === v && _.second === $;
2207
2215
  },
2208
2216
  c,
2209
2217
  h
@@ -2230,7 +2238,7 @@ function tr(n = "UTC", e = null) {
2230
2238
  const v = s(_, w);
2231
2239
  if (!v || !(v instanceof Date) || isNaN(v.getTime()))
2232
2240
  return !1;
2233
- const O = _e.fromJSDate(v).setZone(n), T = c(O), k = a === "date" ? p : typeof p == "string" ? Number(p) : p;
2241
+ const $ = _e.fromJSDate(v).setZone(n), T = c($), k = a === "date" ? p : typeof p == "string" ? Number(p) : p;
2234
2242
  switch (h) {
2235
2243
  case "gt":
2236
2244
  return T > k;
@@ -2473,7 +2481,7 @@ class ar {
2473
2481
  constructor(e, t, s, r = null, o = null, i = {}) {
2474
2482
  if (this.modelClass = e, this.fetchFn = t, this.queryset = s, this.isSyncing = !1, this.lastSync = null, this.lastHydrated = null, this._createdAt = Date.now(), this.isTemp = i.isTemp || !1, this.pruneThreshold = i.pruneThreshold || 10, this.groundTruthPks = r || [], this.operationsMap = /* @__PURE__ */ new Map(), this.includedPks = /* @__PURE__ */ new Map(), Array.isArray(o))
2475
2483
  for (const l of o) {
2476
- const c = Fe.get(l.operationId) || new q(l, !0);
2484
+ const c = Pe.get(l.operationId) || new q(l, !0);
2477
2485
  this.operationsMap.set(c.operationId, c);
2478
2486
  }
2479
2487
  if (this.qsCache = new Ct("queryset-cache", {}, this.onHydrated.bind(this)), this._lastRenderedPks = null, this.renderCallbacks = /* @__PURE__ */ new Set(), !this.isTemp) {
@@ -2606,7 +2614,7 @@ class ar {
2606
2614
  if (a == null) return null;
2607
2615
  const c = this.pkField, h = new Set(e), p = new Set(e);
2608
2616
  for (const m of s.operations)
2609
- if (m.status !== C.REJECTED && !(!t && m.status !== C.CONFIRMED) && !(m.type !== P.CREATE && m.type !== P.BULK_CREATE && m.type !== P.GET_OR_CREATE && m.type !== P.UPDATE_OR_CREATE))
2617
+ if (m.status !== C.REJECTED && !(!t && m.status !== C.CONFIRMED) && !(m.type !== F.CREATE && m.type !== F.BULK_CREATE && m.type !== F.GET_OR_CREATE && m.type !== F.UPDATE_OR_CREATE))
2610
2618
  for (const y of m.instances) {
2611
2619
  if (!y || y[c] == null || h.has(y[c])) continue;
2612
2620
  const _ = y[o];
@@ -3067,7 +3075,7 @@ class Ce {
3067
3075
  });
3068
3076
  return;
3069
3077
  }
3070
- const v = p.pks.map((k) => i.fromPk(k, e)), O = e.build(), T = ss(v, O, i, !1);
3078
+ const v = p.pks.map((k) => i.fromPk(k, e)), $ = e.build(), T = ss(v, $, i, !1);
3071
3079
  m.setGroundTruth(T), m.setOperations(m.getInflightOperations()), m.lastSync = Date.now(), G({
3072
3080
  type: "groupSync",
3073
3081
  phase: "filteredFromRoot",
@@ -3236,7 +3244,7 @@ class de {
3236
3244
  const o = e.ModelClass.primaryKeyField, i = s || `${B()}`, l = zt(i);
3237
3245
  return new q({
3238
3246
  operationId: i,
3239
- type: P.CREATE,
3247
+ type: F.CREATE,
3240
3248
  instances: [{ ...t, [o]: l }],
3241
3249
  queryset: e,
3242
3250
  args: { data: t },
@@ -3257,7 +3265,7 @@ class de {
3257
3265
  });
3258
3266
  return new q({
3259
3267
  operationId: i,
3260
- type: P.BULK_CREATE,
3268
+ type: F.BULK_CREATE,
3261
3269
  instances: l,
3262
3270
  queryset: e,
3263
3271
  args: { data: t },
@@ -3286,7 +3294,7 @@ class de {
3286
3294
  });
3287
3295
  return new q({
3288
3296
  operationId: c,
3289
- type: P.UPDATE,
3297
+ type: F.UPDATE,
3290
3298
  instances: h,
3291
3299
  queryset: e,
3292
3300
  args: { filter: s, data: t },
@@ -3303,7 +3311,7 @@ class de {
3303
3311
  const r = e.ModelClass.primaryKeyField, i = x.getStore(e).render(), l = t || `${B()}`, a = i.map((c) => ({ [r]: c }));
3304
3312
  return new q({
3305
3313
  operationId: l,
3306
- type: P.DELETE,
3314
+ type: F.DELETE,
3307
3315
  instances: a,
3308
3316
  queryset: e,
3309
3317
  args: {},
@@ -3321,7 +3329,7 @@ class de {
3321
3329
  const o = e.ModelClass.primaryKeyField, l = x.getStore(e).render(), a = s || `${B()}`, c = l.map((h) => ({ ...t, [o]: h }));
3322
3330
  return new q({
3323
3331
  operationId: a,
3324
- type: P.UPDATE_INSTANCE,
3332
+ type: F.UPDATE_INSTANCE,
3325
3333
  instances: c,
3326
3334
  queryset: e,
3327
3335
  args: { data: t },
@@ -3339,7 +3347,7 @@ class de {
3339
3347
  const r = s || `${B()}`;
3340
3348
  return new q({
3341
3349
  operationId: r,
3342
- type: P.DELETE_INSTANCE,
3350
+ type: F.DELETE_INSTANCE,
3343
3351
  instances: [t],
3344
3352
  queryset: e,
3345
3353
  args: t,
@@ -3359,7 +3367,7 @@ class de {
3359
3367
  (E) => _t(y, o.fromPk(E[i], e))
3360
3368
  ), w = mt(_, m, o), v = c.filter(
3361
3369
  (E) => w.includes(E[i])
3362
- ), O = v.length === 0, T = O ? P.CREATE : P.UPDATE, k = O ? { ...t, ...s, [i]: l } : v[0];
3370
+ ), $ = v.length === 0, T = $ ? F.CREATE : F.UPDATE, k = $ ? { ...t, ...s, [i]: l } : v[0];
3363
3371
  return new q({
3364
3372
  operationId: l,
3365
3373
  type: T,
@@ -3382,7 +3390,7 @@ class de {
3382
3390
  (E) => _t(y, o.fromPk(E[i], e))
3383
3391
  ), w = mt(_, m, o), v = c.filter(
3384
3392
  (E) => w.includes(E[i])
3385
- ), O = v.length === 0, T = O ? P.CREATE : P.UPDATE, k = O ? { ...t, ...s, [i]: l } : { ...v[0], ...s };
3393
+ ), $ = v.length === 0, T = $ ? F.CREATE : F.UPDATE, k = $ ? { ...t, ...s, [i]: l } : { ...v[0], ...s };
3386
3394
  return new q({
3387
3395
  operationId: l,
3388
3396
  type: T,
@@ -3474,9 +3482,9 @@ class hr {
3474
3482
  ).then((m) => {
3475
3483
  const { data: y, included: _, model_name: w } = m.data, v = m.metadata.created;
3476
3484
  we(j, _, r, e);
3477
- const O = Array.isArray(y) ? y[0] : y;
3478
- a && (c.pk = O);
3479
- const k = (_[w] || {})[O];
3485
+ const $ = Array.isArray(y) ? y[0] : y;
3486
+ a && (c.pk = $);
3487
+ const k = (_[w] || {})[$];
3480
3488
  return k && l.mutate({
3481
3489
  instances: [k],
3482
3490
  status: C.CONFIRMED
@@ -3500,7 +3508,7 @@ class hr {
3500
3508
  throw new Error(
3501
3509
  `Field parameter is required for ${t} operation`
3502
3510
  );
3503
- const i = Pe.getEntity(t, e, o), l = {};
3511
+ const i = Fe.getEntity(t, e, o), l = {};
3504
3512
  t !== "exists" && (l.field = o);
3505
3513
  const a = V(
3506
3514
  e,
@@ -3508,7 +3516,7 @@ class hr {
3508
3516
  l
3509
3517
  ).then((c) => {
3510
3518
  const h = c.data, p = x.getEntity(e);
3511
- return Pe.setEntity(t, e, o, h, p), Z(i), h;
3519
+ return Fe.setEntity(t, e, o, h, p), Z(i), h;
3512
3520
  });
3513
3521
  return te(i, a);
3514
3522
  }
@@ -3552,7 +3560,7 @@ class hr {
3552
3560
  i,
3553
3561
  l.operationId
3554
3562
  ).then((p) => {
3555
- const { data: m, included: y } = p.data || {}, _ = y[o] || {}, w = Array.isArray(m) ? m.map((O) => _[`${O}`]) : [];
3563
+ const { data: m, included: y } = p.data || {}, _ = y[o] || {}, w = Array.isArray(m) ? m.map(($) => _[`${$}`]) : [];
3556
3564
  l.updateStatus(C.CONFIRMED, w);
3557
3565
  const v = p.metadata?.updated_count ?? 0;
3558
3566
  return c = [v, { [o]: v }, w], Z(c), c;
@@ -3617,13 +3625,13 @@ class hr {
3617
3625
  we(j, y, r, e);
3618
3626
  const w = Array.isArray(m) ? m[0] : m;
3619
3627
  c.pk = w;
3620
- const O = (y[_] || {})[w];
3621
- if (!O)
3628
+ const $ = (y[_] || {})[w];
3629
+ if (!$)
3622
3630
  throw new Error(
3623
3631
  `Entity data not found for ${_} with pk ${w}`
3624
3632
  );
3625
3633
  return l.mutate({
3626
- instances: [O],
3634
+ instances: [$],
3627
3635
  status: C.CONFIRMED
3628
3636
  }), Z(c), c;
3629
3637
  }).catch((p) => {
@@ -3670,9 +3678,9 @@ class hr {
3670
3678
  w.forEach((T, k) => {
3671
3679
  c[k] && (c[k].pk = T);
3672
3680
  });
3673
- const v = y[_] || {}, O = w.map((T) => v[T]).filter(Boolean);
3681
+ const v = y[_] || {}, $ = w.map((T) => v[T]).filter(Boolean);
3674
3682
  return a.mutate({
3675
- instances: O,
3683
+ instances: $,
3676
3684
  status: C.CONFIRMED
3677
3685
  }), c.forEach((T) => Z(T)), Z(c), c;
3678
3686
  }).catch((p) => {
@@ -3814,7 +3822,7 @@ class fr {
3814
3822
  * Delegates to the underlying store's sync method
3815
3823
  */
3816
3824
  refreshFromDb() {
3817
- return Pe.getStore(
3825
+ return Fe.getStore(
3818
3826
  this.metricType,
3819
3827
  this.queryset,
3820
3828
  this.field
@@ -3825,7 +3833,7 @@ class fr {
3825
3833
  * Called implicitly by JS when coercing to a primitive (arithmetic, template literals, etc.)
3826
3834
  */
3827
3835
  valueOf() {
3828
- const e = Pe.getStore(
3836
+ const e = Fe.getStore(
3829
3837
  this.metricType,
3830
3838
  this.queryset,
3831
3839
  this.field
@@ -3941,7 +3949,7 @@ class wt {
3941
3949
  return this._stores.has(e) ? this._stores.get(e).queryset : null;
3942
3950
  }
3943
3951
  }
3944
- const Pe = new wt();
3952
+ const Fe = new wt();
3945
3953
  class pr {
3946
3954
  constructor(e) {
3947
3955
  this.event = e.event, this.model = e.model, this.operation_id = e.operation_id, this.pk_field_name = e.pk_field_name, this.configKey = e.configKey, this.canonical_id = e.canonical_id || null, this.server_ts_ms = e.server_ts_ms || null, this.instances = e.instances?.map((t) => t && this.pk_field_name && t[this.pk_field_name] != null ? {
@@ -4066,7 +4074,7 @@ class mr {
4066
4074
  * Checks the `verify` flag on membership state to determine which querysets need syncing.
4067
4075
  */
4068
4076
  syncQuerysetsNeedingVerification(e) {
4069
- const t = Fe.getQuerysetStates(e);
4077
+ const t = Pe.getQuerysetStates(e);
4070
4078
  if (!t) return;
4071
4079
  const s = this.registries.get(Ce);
4072
4080
  if (!s) return;
@@ -4097,7 +4105,7 @@ class mr {
4097
4105
  operationId: e.operation_id,
4098
4106
  socketId: e.socket_id
4099
4107
  });
4100
- let t = new pr(e), s = Fe.has(t.operation_id);
4108
+ let t = new pr(e), s = Pe.has(t.operation_id);
4101
4109
  if (this.registries.has(wt) && this.processMetrics(t), s) {
4102
4110
  this.syncQuerysetsNeedingVerification(t.operation_id);
4103
4111
  return;
@@ -4197,7 +4205,7 @@ class mr {
4197
4205
  const Ae = new mr();
4198
4206
  Ae.manageRegistry(x);
4199
4207
  Ae.manageRegistry(j);
4200
- Ae.manageRegistry(Pe);
4208
+ Ae.manageRegistry(Fe);
4201
4209
  const yr = /* @__PURE__ */ new Set();
4202
4210
  function gr(n) {
4203
4211
  typeof n == "function" && yr.add(n);
@@ -4224,7 +4232,7 @@ const _r = (n, e) => {
4224
4232
  }, Mr = {
4225
4233
  key: 1,
4226
4234
  class: "szd-header__badge"
4227
- }, Ar = { class: "szd-header__badge" }, Or = { class: "szd-tabs" }, $r = ["onClick"], Fr = { class: "szd-content" }, Pr = {
4235
+ }, Ar = { class: "szd-header__badge" }, Or = { class: "szd-tabs" }, $r = ["onClick"], Pr = { class: "szd-content" }, Fr = {
4228
4236
  key: 0,
4229
4237
  class: "szd-panel"
4230
4238
  }, Dr = { class: "szd-panel__section" }, zr = { class: "szd-kv" }, Rr = { class: "szd-kv__row" }, Kr = { class: "szd-kv__value" }, Ir = { class: "szd-kv__row" }, Nr = { class: "szd-kv__value" }, xr = { class: "szd-kv__row" }, jr = { class: "szd-kv__value" }, Ur = { class: "szd-kv__row" }, Qr = { class: "szd-kv__value" }, Lr = { class: "szd-panel__section" }, Vr = { class: "szd-stats" }, Br = { class: "szd-stat" }, Gr = { class: "szd-stat__value" }, Hr = { class: "szd-stat" }, qr = { class: "szd-stat__value" }, Jr = { class: "szd-stat" }, Wr = { class: "szd-stat__value" }, Zr = { class: "szd-stat" }, Yr = { class: "szd-stat__value" }, Xr = {
@@ -4266,7 +4274,7 @@ const _r = (n, e) => {
4266
4274
  }, $n = {
4267
4275
  class: "szd-kv",
4268
4276
  style: { "margin-bottom": "16px" }
4269
- }, Fn = { class: "szd-kv__row" }, Pn = { class: "szd-kv__value szd-kv__value--mono" }, Dn = { class: "szd-ast" }, zn = {
4277
+ }, Pn = { class: "szd-kv__row" }, Fn = { class: "szd-kv__value szd-kv__value--mono" }, Dn = { class: "szd-ast" }, zn = {
4270
4278
  key: 0,
4271
4279
  class: "szd-detail"
4272
4280
  }, Rn = { class: "szd-detail__panel szd-detail__panel--sm" }, Kn = { class: "szd-detail__header" }, In = { class: "szd-detail__body" }, Nn = { class: "szd-settings-section" }, xn = ["value"], jn = {
@@ -4327,7 +4335,7 @@ const _r = (n, e) => {
4327
4335
  queryset: d
4328
4336
  });
4329
4337
  }), u;
4330
- }), O = I(() => (a.value, Array.from(x._stores.entries()).map(
4338
+ }), $ = I(() => (a.value, Array.from(x._stores.entries()).map(
4331
4339
  ([u, d]) => ({
4332
4340
  semanticKey: u,
4333
4341
  modelName: d?.modelClass?.modelName,
@@ -4343,7 +4351,7 @@ const _r = (n, e) => {
4343
4351
  const u = /* @__PURE__ */ new Map();
4344
4352
  return v.value.forEach((d) => {
4345
4353
  u.set(d.semanticKey, d);
4346
- }), O.value.forEach((d) => {
4354
+ }), $.value.forEach((d) => {
4347
4355
  u.has(d.semanticKey) || u.set(d.semanticKey, d);
4348
4356
  }), Array.from(u.values());
4349
4357
  }), E = I(() => w.value?.semanticKey ? w.value.semanticKey : r.value ? r.value : ""), Q = I(() => w.value ? w.value : r.value && T.value.get(r.value) || null), N = I(() => {
@@ -4354,7 +4362,7 @@ const _r = (n, e) => {
4354
4362
  return null;
4355
4363
  }
4356
4364
  return E.value && x._stores.get(E.value) || null;
4357
- }), F = I(() => {
4365
+ }), P = I(() => {
4358
4366
  a.value;
4359
4367
  const u = N.value, d = Q.value, g = u?.modelClass?.modelName || d?.ModelClass?.modelName, R = u?.modelClass?.configKey || d?.ModelClass?.configKey, H = u?.groundTruthPks?.length ?? 0, oe = u?.operationsMap?.size ?? 0, le = u?.getInflightOperations?.() || [], ke = u?.isSyncing ?? !1, je = u?.lastSync ? new Date(u.lastSync).toLocaleString() : "—", nt = u && Array.isArray(u._lastRenderedPks) ? u._lastRenderedPks.length : null, cs = u?.groundTruthPks?.length ?? 0, ds = u ? u.lastSync === null ? "model store" : "ground truth" : "—", us = ke ? "Sync in progress — results may change." : oe > 0 ? "Optimistic operations are applied to results." : u?.lastSync === null ? "No ground truth yet — rendering from model store." : "Using ground truth + local filters.";
4360
4368
  return {
@@ -4629,11 +4637,11 @@ const _r = (n, e) => {
4629
4637
  f("div", vr, [
4630
4638
  f("div", kr, [
4631
4639
  d[9] || (d[9] = f("div", { class: "szd-header__title" }, "StateZero", -1)),
4632
- E.value ? (A(), M("span", br, S(F.value.modelName || "?"), 1)) : (A(), M("span", Er, "No queryset"))
4640
+ E.value ? (A(), M("span", br, S(P.value.modelName || "?"), 1)) : (A(), M("span", Er, "No queryset"))
4633
4641
  ]),
4634
4642
  f("div", Sr, [
4635
- F.value.isSyncing ? (A(), M("span", Tr, "Syncing")) : L("", !0),
4636
- F.value.opsCount > 0 ? (A(), M("span", Mr, S(F.value.opsCount) + " ops", 1)) : L("", !0),
4643
+ P.value.isSyncing ? (A(), M("span", Tr, "Syncing")) : L("", !0),
4644
+ P.value.opsCount > 0 ? (A(), M("span", Mr, S(P.value.opsCount) + " ops", 1)) : L("", !0),
4637
4645
  f("span", Ar, S(Ie.value) + " events", 1),
4638
4646
  f("button", {
4639
4647
  class: "szd-btn szd-btn--icon",
@@ -4666,8 +4674,8 @@ const _r = (n, e) => {
4666
4674
  }, S(g.label), 11, $r)), 64))
4667
4675
  ])
4668
4676
  ]),
4669
- f("main", Fr, [
4670
- t.value === "overview" ? (A(), M("div", Pr, [
4677
+ f("main", Pr, [
4678
+ t.value === "overview" ? (A(), M("div", Fr, [
4671
4679
  f("div", Dr, [
4672
4680
  d[15] || (d[15] = f("h3", { class: "szd-panel__heading" }, "Why This View?", -1)),
4673
4681
  f("div", zr, [
@@ -4685,7 +4693,7 @@ const _r = (n, e) => {
4685
4693
  ]),
4686
4694
  f("div", Ur, [
4687
4695
  d[14] || (d[14] = f("span", { class: "szd-kv__key" }, "Reason:", -1)),
4688
- f("span", Qr, S(F.value.reason), 1)
4696
+ f("span", Qr, S(P.value.reason), 1)
4689
4697
  ])
4690
4698
  ])
4691
4699
  ]),
@@ -4693,26 +4701,26 @@ const _r = (n, e) => {
4693
4701
  d[21] || (d[21] = f("h3", { class: "szd-panel__heading" }, "Current State", -1)),
4694
4702
  f("div", Vr, [
4695
4703
  f("div", Br, [
4696
- f("div", Gr, S(F.value.optimisticCount ?? "—"), 1),
4704
+ f("div", Gr, S(P.value.optimisticCount ?? "—"), 1),
4697
4705
  d[16] || (d[16] = f("div", { class: "szd-stat__label" }, "Optimistic", -1))
4698
4706
  ]),
4699
4707
  f("div", Hr, [
4700
- f("div", qr, S(F.value.confirmedCount), 1),
4708
+ f("div", qr, S(P.value.confirmedCount), 1),
4701
4709
  d[17] || (d[17] = f("div", { class: "szd-stat__label" }, "Confirmed", -1))
4702
4710
  ]),
4703
4711
  f("div", Jr, [
4704
- f("div", Wr, S(F.value.groundTruthCount), 1),
4712
+ f("div", Wr, S(P.value.groundTruthCount), 1),
4705
4713
  d[18] || (d[18] = f("div", { class: "szd-stat__label" }, "Ground Truth", -1))
4706
4714
  ]),
4707
4715
  f("div", Zr, [
4708
- f("div", Yr, S(F.value.inFlightCount), 1),
4716
+ f("div", Yr, S(P.value.inFlightCount), 1),
4709
4717
  d[19] || (d[19] = f("div", { class: "szd-stat__label" }, "In-Flight", -1))
4710
4718
  ])
4711
4719
  ]),
4712
4720
  f("div", Xr, [
4713
4721
  f("div", en, [
4714
4722
  d[20] || (d[20] = f("span", { class: "szd-kv__key" }, "Last Sync:", -1)),
4715
- f("span", tn, S(F.value.lastSync), 1)
4723
+ f("span", tn, S(P.value.lastSync), 1)
4716
4724
  ])
4717
4725
  ])
4718
4726
  ]),
@@ -4821,9 +4829,9 @@ const _r = (n, e) => {
4821
4829
  t.value === "ast" ? (A(), M("div", On, [
4822
4830
  d[27] || (d[27] = f("h3", { class: "szd-panel__heading" }, "Query AST", -1)),
4823
4831
  f("div", $n, [
4824
- f("div", Fn, [
4832
+ f("div", Pn, [
4825
4833
  d[26] || (d[26] = f("span", { class: "szd-kv__key" }, "Semantic Key:", -1)),
4826
- f("code", Pn, S(E.value || "—"), 1)
4834
+ f("code", Fn, S(E.value || "—"), 1)
4827
4835
  ])
4828
4836
  ]),
4829
4837
  f("pre", Dn, S(re.value ? JSON.stringify(re.value, null, 2) : "Select a queryset to view AST"), 1)
@@ -4901,23 +4909,23 @@ const _r = (n, e) => {
4901
4909
  f("div", Jn, [
4902
4910
  f("div", Wn, [
4903
4911
  d[35] || (d[35] = f("span", { class: "szd-kv__key" }, "Model:", -1)),
4904
- f("span", Zn, S(F.value.modelName || "—"), 1)
4912
+ f("span", Zn, S(P.value.modelName || "—"), 1)
4905
4913
  ]),
4906
4914
  f("div", Yn, [
4907
4915
  d[36] || (d[36] = f("span", { class: "szd-kv__key" }, "Source:", -1)),
4908
- f("span", Xn, S(F.value.source), 1)
4916
+ f("span", Xn, S(P.value.source), 1)
4909
4917
  ]),
4910
4918
  f("div", eo, [
4911
4919
  d[37] || (d[37] = f("span", { class: "szd-kv__key" }, "Syncing:", -1)),
4912
- f("span", to, S(F.value.isSyncing ? "Yes" : "No"), 1)
4920
+ f("span", to, S(P.value.isSyncing ? "Yes" : "No"), 1)
4913
4921
  ]),
4914
4922
  f("div", so, [
4915
4923
  d[38] || (d[38] = f("span", { class: "szd-kv__key" }, "Operations:", -1)),
4916
- f("span", ro, S(F.value.opsCount), 1)
4924
+ f("span", ro, S(P.value.opsCount), 1)
4917
4925
  ]),
4918
4926
  f("div", no, [
4919
4927
  d[39] || (d[39] = f("span", { class: "szd-kv__key" }, "Last Sync:", -1)),
4920
- f("span", oo, S(F.value.lastSync), 1)
4928
+ f("span", oo, S(P.value.lastSync), 1)
4921
4929
  ])
4922
4930
  ])
4923
4931
  ])) : L("", !0)
package/dist/config.js CHANGED
@@ -9,13 +9,17 @@ export let liveConfig = {
9
9
  const pusherSchema = z.object({
10
10
  clientOptions: z.object({
11
11
  appKey: z.string({ required_error: 'Pusher appKey is required' }),
12
- cluster: z.string({ required_error: 'Pusher cluster is required' }),
12
+ cluster: z.string().optional(),
13
+ wsHost: z.string().optional(),
14
+ wsPort: z.number().optional(),
15
+ wssPort: z.number().optional(),
16
+ enabledTransports: z.array(z.string()).optional(),
13
17
  forceTLS: z.boolean().optional(),
14
18
  authEndpoint: z.string()
15
19
  .url('Pusher authentication endpoint URL is required'),
16
20
  getAuthHeaders: z.function().optional()
17
21
  .refine((fn) => fn === undefined || typeof fn === 'function', 'getAuthHeaders must be a function if provided')
18
- })
22
+ }).refine((opts) => opts.cluster || opts.wsHost, 'Either cluster or wsHost must be provided')
19
23
  });
20
24
  const eventConfigSchema = z.object({
21
25
  type: z.enum(['websocket', 'pusher', 'none']),
@@ -48,7 +48,11 @@ export namespace EventType {
48
48
  * Options for instantiating a Pusher client.
49
49
  * @typedef {Object} PusherClientOptions
50
50
  * @property {string} appKey
51
- * @property {string} cluster
51
+ * @property {string} [cluster] - Pusher cluster (use this OR wsHost)
52
+ * @property {string} [wsHost] - Custom WebSocket host (e.g. for Soketi)
53
+ * @property {number} [wsPort] - Custom WebSocket port (default 443)
54
+ * @property {number} [wssPort] - Custom secure WebSocket port (default 443)
55
+ * @property {string[]} [enabledTransports] - Transports to use (default ['ws', 'wss'])
52
56
  * @property {boolean} [forceTLS]
53
57
  * @property {string} authEndpoint
54
58
  * @property {function(): Object<string, string>} [getAuthHeaders]
@@ -162,7 +166,26 @@ export type NamespaceResolver = (modelName: string) => string;
162
166
  */
163
167
  export type PusherClientOptions = {
164
168
  appKey: string;
165
- cluster: string;
169
+ /**
170
+ * - Pusher cluster (use this OR wsHost)
171
+ */
172
+ cluster?: string | undefined;
173
+ /**
174
+ * - Custom WebSocket host (e.g. for Soketi)
175
+ */
176
+ wsHost?: string | undefined;
177
+ /**
178
+ * - Custom WebSocket port (default 443)
179
+ */
180
+ wsPort?: number | undefined;
181
+ /**
182
+ * - Custom secure WebSocket port (default 443)
183
+ */
184
+ wssPort?: number | undefined;
185
+ /**
186
+ * - Transports to use (default ['ws', 'wss'])
187
+ */
188
+ enabledTransports?: string[] | undefined;
166
189
  forceTLS?: boolean | undefined;
167
190
  authEndpoint: string;
168
191
  getAuthHeaders?: (() => {
@@ -41,7 +41,11 @@ export const EventType = {
41
41
  * Options for instantiating a Pusher client.
42
42
  * @typedef {Object} PusherClientOptions
43
43
  * @property {string} appKey
44
- * @property {string} cluster
44
+ * @property {string} [cluster] - Pusher cluster (use this OR wsHost)
45
+ * @property {string} [wsHost] - Custom WebSocket host (e.g. for Soketi)
46
+ * @property {number} [wsPort] - Custom WebSocket port (default 443)
47
+ * @property {number} [wssPort] - Custom secure WebSocket port (default 443)
48
+ * @property {string[]} [enabledTransports] - Transports to use (default ['ws', 'wss'])
45
49
  * @property {boolean} [forceTLS]
46
50
  * @property {string} authEndpoint
47
51
  * @property {function(): Object<string, string>} [getAuthHeaders]
@@ -71,12 +75,21 @@ export class PusherEventReceiver {
71
75
  clientOptions.appKey.length < 15) {
72
76
  console.warn(`%c[Pusher Warning] The provided appKey ("${clientOptions.appKey}") looks like a numeric app_id. Pusher requires the alphanumeric key, not the ID. Please verify your configuration for backend: "${this.configKey}".`, "color: orange; font-weight: bold; font-size: 14px;");
73
77
  }
74
- this.pusherClient = new Pusher(clientOptions.appKey, {
75
- cluster: clientOptions.cluster,
78
+ const pusherOpts = {
76
79
  forceTLS: clientOptions.forceTLS ?? true,
77
80
  authEndpoint: clientOptions.authEndpoint,
78
81
  auth: { headers: clientOptions.getAuthHeaders?.() || {} },
79
- });
82
+ };
83
+ if (clientOptions.wsHost) {
84
+ pusherOpts.wsHost = clientOptions.wsHost;
85
+ pusherOpts.wsPort = clientOptions.wsPort ?? 443;
86
+ pusherOpts.wssPort = clientOptions.wssPort ?? 443;
87
+ pusherOpts.enabledTransports = clientOptions.enabledTransports ?? ['ws', 'wss'];
88
+ }
89
+ else {
90
+ pusherOpts.cluster = clientOptions.cluster;
91
+ }
92
+ this.pusherClient = new Pusher(clientOptions.appKey, pusherOpts);
80
93
  this.pusherClient.connection.bind("connected", () => {
81
94
  console.log(`Pusher client connected successfully for backend: ${this.configKey}.`);
82
95
  if (this.connectionTimeoutId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.2.58",
3
+ "version": "0.2.59",
4
4
  "type": "module",
5
5
  "module": "ESNext",
6
6
  "description": "The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate",