@multiplatform.one/frappe 6.6.0 → 7.0.0
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 +1 -1
- package/dist/cjs/auth.native.js.map +1 -1
- package/dist/cjs/call.native.js.map +1 -1
- package/dist/cjs/collection.native.js.map +1 -1
- package/dist/cjs/common/types.native.js.map +1 -1
- package/dist/cjs/core/http.cjs +45 -1
- package/dist/cjs/core/http.native.js +72 -1
- package/dist/cjs/core/http.native.js.map +1 -1
- package/dist/cjs/core/types.native.js.map +1 -1
- package/dist/cjs/core/wire.native.js.map +1 -1
- package/dist/cjs/db.native.js.map +1 -1
- package/dist/cjs/devtools/FrappeDevtoolsPanel.native.js.map +1 -1
- package/dist/cjs/devtools/index.native.js.map +1 -1
- package/dist/cjs/devtools/plugin.native.js.map +1 -1
- package/dist/cjs/devtools/theme.native.js.map +1 -1
- package/dist/cjs/doctype.cjs +15 -2
- package/dist/cjs/doctype.native.js +22 -5
- package/dist/cjs/doctype.native.js.map +1 -1
- package/dist/cjs/file.native.js.map +1 -1
- package/dist/cjs/fixtureDb.native.js.map +1 -1
- package/dist/cjs/fixtures.native.js.map +1 -1
- package/dist/cjs/frappeApp.native.js.map +1 -1
- package/dist/cjs/frappeReact.cjs +55 -1
- package/dist/cjs/frappeReact.native.js +67 -2
- package/dist/cjs/frappeReact.native.js.map +1 -1
- package/dist/cjs/index.cjs +8 -0
- package/dist/cjs/index.native.js +10 -2
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/optimistic.cjs +32 -2
- package/dist/cjs/optimistic.native.js +34 -1
- package/dist/cjs/optimistic.native.js.map +1 -1
- package/dist/cjs/pacer.native.js.map +1 -1
- package/dist/cjs/plugin/index.native.js.map +1 -1
- package/dist/cjs/realtime.cjs +234 -11
- package/dist/cjs/realtime.native.js +368 -18
- package/dist/cjs/realtime.native.js.map +1 -1
- package/dist/cjs/sync/backfill.native.js.map +1 -1
- package/dist/cjs/sync/filters.native.js.map +1 -1
- package/dist/cjs/sync/index.cjs +45 -1
- package/dist/cjs/sync/index.native.js +71 -1
- package/dist/cjs/sync/index.native.js.map +1 -1
- package/dist/cjs/sync/merge.native.js.map +1 -1
- package/dist/cjs/sync/mutationEngine.cjs +51 -15
- package/dist/cjs/sync/mutationEngine.native.js +69 -16
- package/dist/cjs/sync/mutationEngine.native.js.map +1 -1
- package/dist/cjs/sync/mutationJournal.cjs +8 -0
- package/dist/cjs/sync/mutationJournal.native.js +10 -0
- package/dist/cjs/sync/mutationJournal.native.js.map +1 -1
- package/dist/cjs/sync/normalizedCache.native.js.map +1 -1
- package/dist/cjs/sync/persistence.native.js.map +1 -1
- package/dist/cjs/sync/realtime.native.js.map +1 -1
- package/dist/cjs/sync/rehydration.native.js.map +1 -1
- package/dist/cjs/sync/storage.native.js.map +1 -1
- package/dist/cjs/sync/subscriptionManager.native.js.map +1 -1
- package/dist/cjs/sync/types.native.js.map +1 -1
- package/dist/cjs/sync/virtualPageManager.native.js.map +1 -1
- package/dist/cjs/useLiveQuery.native.js.map +1 -1
- package/dist/cjs/util.native.js.map +1 -1
- package/dist/esm/auth.native.js.map +1 -1
- package/dist/esm/call.native.js.map +1 -1
- package/dist/esm/collection.native.js +1 -1
- package/dist/esm/collection.native.js.map +1 -1
- package/dist/esm/common/types.native.js.map +1 -1
- package/dist/esm/core/http.mjs +45 -2
- package/dist/esm/core/http.mjs.map +1 -1
- package/dist/esm/core/http.native.js +74 -4
- package/dist/esm/core/http.native.js.map +1 -1
- package/dist/esm/core/types.native.js.map +1 -1
- package/dist/esm/core/wire.native.js.map +1 -1
- package/dist/esm/db.native.js +1 -1
- package/dist/esm/db.native.js.map +1 -1
- package/dist/esm/devtools/FrappeDevtoolsPanel.native.js +2 -2
- package/dist/esm/devtools/FrappeDevtoolsPanel.native.js.map +1 -1
- package/dist/esm/devtools/index.native.js +2 -2
- package/dist/esm/devtools/index.native.js.map +1 -1
- package/dist/esm/devtools/plugin.native.js +1 -1
- package/dist/esm/devtools/plugin.native.js.map +1 -1
- package/dist/esm/devtools/theme.native.js.map +1 -1
- package/dist/esm/doctype.mjs +15 -2
- package/dist/esm/doctype.mjs.map +1 -1
- package/dist/esm/doctype.native.js +23 -6
- package/dist/esm/doctype.native.js.map +1 -1
- package/dist/esm/file.native.js.map +1 -1
- package/dist/esm/fixtureDb.native.js +1 -1
- package/dist/esm/fixtureDb.native.js.map +1 -1
- package/dist/esm/fixtures.native.js.map +1 -1
- package/dist/esm/frappeApp.native.js +7 -7
- package/dist/esm/frappeApp.native.js.map +1 -1
- package/dist/esm/frappeReact.mjs +55 -3
- package/dist/esm/frappeReact.mjs.map +1 -1
- package/dist/esm/frappeReact.native.js +73 -10
- package/dist/esm/frappeReact.native.js.map +1 -1
- package/dist/esm/index.mjs +5 -5
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +22 -22
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/optimistic.mjs +27 -1
- package/dist/esm/optimistic.mjs.map +1 -1
- package/dist/esm/optimistic.native.js +30 -1
- package/dist/esm/optimistic.native.js.map +1 -1
- package/dist/esm/pacer.mjs.map +1 -1
- package/dist/esm/pacer.native.js +4 -4
- package/dist/esm/pacer.native.js.map +1 -1
- package/dist/esm/plugin/index.native.js.map +1 -1
- package/dist/esm/realtime.mjs +234 -11
- package/dist/esm/realtime.mjs.map +1 -1
- package/dist/esm/realtime.native.js +369 -19
- package/dist/esm/realtime.native.js.map +1 -1
- package/dist/esm/sync/backfill.native.js +1 -1
- package/dist/esm/sync/backfill.native.js.map +1 -1
- package/dist/esm/sync/filters.native.js.map +1 -1
- package/dist/esm/sync/index.mjs +45 -1
- package/dist/esm/sync/index.mjs.map +1 -1
- package/dist/esm/sync/index.native.js +79 -9
- package/dist/esm/sync/index.native.js.map +1 -1
- package/dist/esm/sync/merge.native.js.map +1 -1
- package/dist/esm/sync/mutationEngine.mjs +51 -15
- package/dist/esm/sync/mutationEngine.mjs.map +1 -1
- package/dist/esm/sync/mutationEngine.native.js +73 -20
- package/dist/esm/sync/mutationEngine.native.js.map +1 -1
- package/dist/esm/sync/mutationJournal.mjs +8 -0
- package/dist/esm/sync/mutationJournal.mjs.map +1 -1
- package/dist/esm/sync/mutationJournal.native.js +11 -1
- package/dist/esm/sync/mutationJournal.native.js.map +1 -1
- package/dist/esm/sync/normalizedCache.native.js.map +1 -1
- package/dist/esm/sync/persistence.native.js +2 -2
- package/dist/esm/sync/persistence.native.js.map +1 -1
- package/dist/esm/sync/realtime.native.js +1 -1
- package/dist/esm/sync/realtime.native.js.map +1 -1
- package/dist/esm/sync/rehydration.native.js +1 -1
- package/dist/esm/sync/rehydration.native.js.map +1 -1
- package/dist/esm/sync/storage.native.js.map +1 -1
- package/dist/esm/sync/subscriptionManager.native.js +4 -4
- package/dist/esm/sync/subscriptionManager.native.js.map +1 -1
- package/dist/esm/sync/types.mjs.map +1 -1
- package/dist/esm/sync/types.native.js.map +1 -1
- package/dist/esm/sync/virtualPageManager.native.js +1 -1
- package/dist/esm/sync/virtualPageManager.native.js.map +1 -1
- package/dist/esm/useLiveQuery.native.js.map +1 -1
- package/dist/esm/util.native.js.map +1 -1
- package/dist/jsx/core/http.mjs +45 -2
- package/dist/jsx/core/http.mjs.map +1 -1
- package/dist/jsx/core/http.native.js +72 -1
- package/dist/jsx/core/http.native.js.map +1 -1
- package/dist/jsx/doctype.mjs +15 -2
- package/dist/jsx/doctype.mjs.map +1 -1
- package/dist/jsx/doctype.native.js +22 -5
- package/dist/jsx/doctype.native.js.map +1 -1
- package/dist/jsx/frappeReact.mjs +55 -3
- package/dist/jsx/frappeReact.mjs.map +1 -1
- package/dist/jsx/frappeReact.native.js +66 -1
- package/dist/jsx/frappeReact.native.js.map +1 -1
- package/dist/jsx/index.js +5 -5
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +5 -5
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +8 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/optimistic.mjs +27 -1
- package/dist/jsx/optimistic.mjs.map +1 -1
- package/dist/jsx/optimistic.native.js +34 -1
- package/dist/jsx/optimistic.native.js.map +1 -1
- package/dist/jsx/pacer.mjs.map +1 -1
- package/dist/jsx/pacer.native.js.map +1 -1
- package/dist/jsx/realtime.mjs +234 -11
- package/dist/jsx/realtime.mjs.map +1 -1
- package/dist/jsx/realtime.native.js +368 -18
- package/dist/jsx/realtime.native.js.map +1 -1
- package/dist/jsx/sync/index.mjs +45 -1
- package/dist/jsx/sync/index.mjs.map +1 -1
- package/dist/jsx/sync/index.native.js +71 -1
- package/dist/jsx/sync/index.native.js.map +1 -1
- package/dist/jsx/sync/mutationEngine.mjs +51 -15
- package/dist/jsx/sync/mutationEngine.mjs.map +1 -1
- package/dist/jsx/sync/mutationEngine.native.js +69 -16
- package/dist/jsx/sync/mutationEngine.native.js.map +1 -1
- package/dist/jsx/sync/mutationJournal.mjs +8 -0
- package/dist/jsx/sync/mutationJournal.mjs.map +1 -1
- package/dist/jsx/sync/mutationJournal.native.js +10 -0
- package/dist/jsx/sync/mutationJournal.native.js.map +1 -1
- package/dist/jsx/sync/types.mjs.map +1 -1
- package/dist/jsx/sync/types.native.js.map +1 -1
- package/package.json +8 -8
- package/src/core/http.spec.ts +81 -0
- package/src/core/http.ts +80 -3
- package/src/doctype.spec.ts +82 -3
- package/src/doctype.ts +51 -7
- package/src/frappeReact.ts +126 -4
- package/src/index.ts +28 -3
- package/src/optimistic.spec.ts +113 -2
- package/src/optimistic.ts +95 -0
- package/src/pacer.ts +8 -0
- package/src/realtime.spec.ts +62 -0
- package/src/realtime.ts +440 -14
- package/src/realtimeSse.spec.ts +547 -0
- package/src/sync/index.ts +44 -1
- package/src/sync/mutationEngine.spec.ts +7 -2
- package/src/sync/mutationEngine.ts +83 -27
- package/src/sync/mutationJournal.ts +9 -0
- package/src/sync/mutations.spec.ts +1 -1
- package/src/sync/syncModule.spec.ts +255 -1
- package/src/sync/types.ts +20 -0
- package/types/core/http.d.ts +11 -0
- package/types/core/http.d.ts.map +1 -1
- package/types/doctype.d.ts +7 -0
- package/types/doctype.d.ts.map +1 -1
- package/types/frappeReact.d.ts +50 -2
- package/types/frappeReact.d.ts.map +1 -1
- package/types/index.d.ts +8 -6
- package/types/index.d.ts.map +1 -1
- package/types/optimistic.d.ts +38 -0
- package/types/optimistic.d.ts.map +1 -1
- package/types/pacer.d.ts +8 -0
- package/types/pacer.d.ts.map +1 -1
- package/types/realtime.d.ts +183 -1
- package/types/realtime.d.ts.map +1 -1
- package/types/sync/index.d.ts +16 -1
- package/types/sync/index.d.ts.map +1 -1
- package/types/sync/mutationEngine.d.ts +7 -0
- package/types/sync/mutationEngine.d.ts.map +1 -1
- package/types/sync/mutationJournal.d.ts +6 -0
- package/types/sync/mutationJournal.d.ts.map +1 -1
- package/types/sync/types.d.ts +20 -0
- package/types/sync/types.d.ts.map +1 -1
|
@@ -78,9 +78,14 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
78
78
|
function RealtimeModule2(config) {
|
|
79
79
|
_class_call_check(this, RealtimeModule2);
|
|
80
80
|
_define_property(this, "socket", void 0);
|
|
81
|
+
_define_property(this, "eventSource", void 0);
|
|
81
82
|
_define_property(this, "handlerMap", /* @__PURE__ */new Map());
|
|
82
83
|
_define_property(this, "attachedSocketEvents", /* @__PURE__ */new Set());
|
|
83
84
|
_define_property(this, "socketEventHandlers", /* @__PURE__ */new Map());
|
|
85
|
+
_define_property(this, "attachedSseEvents", /* @__PURE__ */new Set());
|
|
86
|
+
_define_property(this, "sseListeners", /* @__PURE__ */new Map());
|
|
87
|
+
_define_property(this, "sseRoomNoticeLogged", false);
|
|
88
|
+
_define_property(this, "sseEmitNoticeLogged", false);
|
|
84
89
|
_define_property(this, "docRooms", /* @__PURE__ */new Map());
|
|
85
90
|
_define_property(this, "listRooms", /* @__PURE__ */new Map());
|
|
86
91
|
_define_property(this, "socketHealthy", false);
|
|
@@ -108,19 +113,31 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
108
113
|
key: "getSocketURL",
|
|
109
114
|
value: function getSocketURL() {
|
|
110
115
|
var base = this.config.baseURL.replace(/\/$/, "");
|
|
116
|
+
if (this.config.socketBaseURL) {
|
|
117
|
+
var socketBase = this.config.socketBaseURL.replace(/\/$/, "");
|
|
118
|
+
var siteName = this.config.siteName;
|
|
119
|
+
if (!siteName) {
|
|
120
|
+
try {
|
|
121
|
+
siteName = new URL(base).hostname;
|
|
122
|
+
} catch (unused) {
|
|
123
|
+
siteName = base.replace(/^https?:\/\//, "").split(/[/:]/)[0];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return `${socketBase}/${siteName}`;
|
|
127
|
+
}
|
|
111
128
|
try {
|
|
112
129
|
var url = new URL(base);
|
|
113
130
|
var port = this.config.socketPort ? String(this.config.socketPort) : url.port;
|
|
114
131
|
var host = port ? `${url.hostname}:${port}` : url.hostname;
|
|
115
|
-
var
|
|
116
|
-
return `${url.protocol}//${host}/${
|
|
132
|
+
var siteName1 = this.config.siteName || url.hostname;
|
|
133
|
+
return `${url.protocol}//${host}/${siteName1}`;
|
|
117
134
|
} catch (unused) {
|
|
118
135
|
var result = base;
|
|
119
136
|
if (this.config.socketPort) {
|
|
120
137
|
result = result.replace(/(:\d+)/, `:${this.config.socketPort}`);
|
|
121
138
|
}
|
|
122
|
-
var
|
|
123
|
-
return `${result}/${
|
|
139
|
+
var siteName2 = this.config.siteName || result.replace(/^https?:\/\//, "").split(/[/:]/)[0];
|
|
140
|
+
return `${result}/${siteName2}`;
|
|
124
141
|
}
|
|
125
142
|
}
|
|
126
143
|
}, {
|
|
@@ -226,13 +243,17 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
226
243
|
}
|
|
227
244
|
this.healthyWaiters.clear();
|
|
228
245
|
}
|
|
246
|
+
}, {
|
|
247
|
+
key: "isSSE",
|
|
248
|
+
value: function isSSE() {
|
|
249
|
+
return this.config.transport === "sse";
|
|
250
|
+
}
|
|
229
251
|
}, {
|
|
230
252
|
key: "waitUntilHealthy",
|
|
231
253
|
value: function waitUntilHealthy() {
|
|
232
254
|
var _this = this;
|
|
233
255
|
var timeoutMs = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 2e4;
|
|
234
|
-
|
|
235
|
-
if (this.socketHealthy && ((_this_socket = this.socket) === null || _this_socket === void 0 ? void 0 : _this_socket.connected)) return Promise.resolve(true);
|
|
256
|
+
if (this.isHealthy()) return Promise.resolve(true);
|
|
236
257
|
return new Promise(function (resolve) {
|
|
237
258
|
var timer = setTimeout(function () {
|
|
238
259
|
_this.healthyWaiters.delete(onReady);
|
|
@@ -248,9 +269,8 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
248
269
|
}, {
|
|
249
270
|
key: "ensureConnected",
|
|
250
271
|
value: async function ensureConnected() {
|
|
251
|
-
|
|
252
|
-
if (this.
|
|
253
|
-
if (!this.socket && !this.isConnecting) {
|
|
272
|
+
if (this.isHealthy()) return;
|
|
273
|
+
if (!this.socket && !this.eventSource && !this.isConnecting) {
|
|
254
274
|
await this.connect();
|
|
255
275
|
}
|
|
256
276
|
await this.waitUntilHealthy();
|
|
@@ -306,7 +326,17 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
306
326
|
}
|
|
307
327
|
}, {
|
|
308
328
|
key: "connect",
|
|
309
|
-
value:
|
|
329
|
+
value: (
|
|
330
|
+
/**
|
|
331
|
+
* Open the realtime transport now. Room-driven auto-connect
|
|
332
|
+
* (subscribeDoc/subscribeList) remains the primary lifecycle in both
|
|
333
|
+
* transports — this is public for SSE consumers that use no doc/list room
|
|
334
|
+
* bookkeeping: a one-way stream has nothing to emit on join, so nothing
|
|
335
|
+
* else would ever open it. Idempotent while a transport exists or a
|
|
336
|
+
* connect is in flight.
|
|
337
|
+
*/
|
|
338
|
+
async function connect() {
|
|
339
|
+
if (this.isSSE()) return this.connectSSE();
|
|
310
340
|
if (this.socket || this.isConnecting) return;
|
|
311
341
|
this.isConnecting = true;
|
|
312
342
|
try {
|
|
@@ -334,7 +364,259 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
334
364
|
this.resolveHealthyWaiters(false);
|
|
335
365
|
throw err;
|
|
336
366
|
}
|
|
367
|
+
})
|
|
368
|
+
}, {
|
|
369
|
+
key: "connectSSE",
|
|
370
|
+
value: (
|
|
371
|
+
/**
|
|
372
|
+
* SSE branch of connect(): construct an EventSource against the configured
|
|
373
|
+
* stream URL. EventSource connects at construction, auto-reconnects on
|
|
374
|
+
* failure, and resumes missed frames itself by sending the stream's last
|
|
375
|
+
* `id:` as the `Last-Event-ID` request header — none of that is
|
|
376
|
+
* reimplemented here.
|
|
377
|
+
*/
|
|
378
|
+
async function connectSSE() {
|
|
379
|
+
if (this.eventSource || this.isConnecting) return;
|
|
380
|
+
this.isConnecting = true;
|
|
381
|
+
try {
|
|
382
|
+
var _ref;
|
|
383
|
+
var sse = this.config.sse;
|
|
384
|
+
var EventSourceCtor = (_ref = sse === null || sse === void 0 ? void 0 : sse.EventSource) !== null && _ref !== void 0 ? _ref : globalThis.EventSource;
|
|
385
|
+
if (!EventSourceCtor) {
|
|
386
|
+
throw new Error('[RealtimeModule] transport "sse" needs an EventSource implementation, and this runtime has no global EventSource (React Native and Node < 22 ship none). Pass a constructor via config.sse.EventSource \u2014 e.g. the "eventsource" npm package on Node or "react-native-sse" on React Native.');
|
|
387
|
+
}
|
|
388
|
+
var url = await this.buildSSEURL();
|
|
389
|
+
this.eventSource = new EventSourceCtor(url, {
|
|
390
|
+
withCredentials: sse === null || sse === void 0 ? void 0 : sse.withCredentials
|
|
391
|
+
});
|
|
392
|
+
this.initSSEHandlers();
|
|
393
|
+
} catch (err) {
|
|
394
|
+
this.isConnecting = false;
|
|
395
|
+
this.resolveHealthyWaiters(false);
|
|
396
|
+
throw err;
|
|
397
|
+
}
|
|
398
|
+
})
|
|
399
|
+
}, {
|
|
400
|
+
key: "buildSSEURL",
|
|
401
|
+
value: async function buildSSEURL() {
|
|
402
|
+
var _ref;
|
|
403
|
+
var _this_config_sse;
|
|
404
|
+
var sse = this.config.sse;
|
|
405
|
+
var url;
|
|
406
|
+
if (sse === null || sse === void 0 ? void 0 : sse.url) {
|
|
407
|
+
url = sse.url;
|
|
408
|
+
} else if (sse === null || sse === void 0 ? void 0 : sse.path) {
|
|
409
|
+
var base = this.config.baseURL.replace(/\/$/, "");
|
|
410
|
+
url = `${base}${sse.path.startsWith("/") ? "" : "/"}${sse.path}`;
|
|
411
|
+
} else {
|
|
412
|
+
throw new Error('[RealtimeModule] transport "sse" requires config.sse.url or config.sse.path. There is no default stream path: SSE endpoints are server-specific (the SHC daemon serves "/api/method/shc.events.stream"; a real Frappe bench has no SSE endpoint at all), so a framework default would only ever 404.');
|
|
413
|
+
}
|
|
414
|
+
var params = Object.entries((_ref = (_this_config_sse = this.config.sse) === null || _this_config_sse === void 0 ? void 0 : _this_config_sse.queryParams) !== null && _ref !== void 0 ? _ref : {});
|
|
415
|
+
if (params.length === 0) return url;
|
|
416
|
+
var parts = [];
|
|
417
|
+
var _iteratorNormalCompletion = true,
|
|
418
|
+
_didIteratorError = false,
|
|
419
|
+
_iteratorError = void 0;
|
|
420
|
+
try {
|
|
421
|
+
for (var _iterator = params[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
422
|
+
var [key, value] = _step.value;
|
|
423
|
+
var resolved = typeof value === "function" ? await value() : value;
|
|
424
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(resolved)}`);
|
|
425
|
+
}
|
|
426
|
+
} catch (err) {
|
|
427
|
+
_didIteratorError = true;
|
|
428
|
+
_iteratorError = err;
|
|
429
|
+
} finally {
|
|
430
|
+
try {
|
|
431
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
432
|
+
_iterator.return();
|
|
433
|
+
}
|
|
434
|
+
} finally {
|
|
435
|
+
if (_didIteratorError) {
|
|
436
|
+
throw _iteratorError;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return `${url}${url.includes("?") ? "&" : "?"}${parts.join("&")}`;
|
|
337
441
|
}
|
|
442
|
+
}, {
|
|
443
|
+
key: "initSSEHandlers",
|
|
444
|
+
value: function initSSEHandlers() {
|
|
445
|
+
var _ref;
|
|
446
|
+
var _this_config_sse;
|
|
447
|
+
this.attachedSseEvents.clear();
|
|
448
|
+
this.sseListeners.clear();
|
|
449
|
+
this.attachSSEListener("open");
|
|
450
|
+
this.attachSSEListener("error");
|
|
451
|
+
this.attachSSEListener("message");
|
|
452
|
+
var _iteratorNormalCompletion = true,
|
|
453
|
+
_didIteratorError = false,
|
|
454
|
+
_iteratorError = void 0;
|
|
455
|
+
try {
|
|
456
|
+
for (var _iterator = ((_ref = (_this_config_sse = this.config.sse) === null || _this_config_sse === void 0 ? void 0 : _this_config_sse.events) !== null && _ref !== void 0 ? _ref : [])[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
457
|
+
var type = _step.value;
|
|
458
|
+
this.attachSSEListener(type);
|
|
459
|
+
}
|
|
460
|
+
} catch (err) {
|
|
461
|
+
_didIteratorError = true;
|
|
462
|
+
_iteratorError = err;
|
|
463
|
+
} finally {
|
|
464
|
+
try {
|
|
465
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
466
|
+
_iterator.return();
|
|
467
|
+
}
|
|
468
|
+
} finally {
|
|
469
|
+
if (_didIteratorError) {
|
|
470
|
+
throw _iteratorError;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
var _iteratorNormalCompletion1 = true,
|
|
475
|
+
_didIteratorError1 = false,
|
|
476
|
+
_iteratorError1 = void 0;
|
|
477
|
+
try {
|
|
478
|
+
for (var _iterator1 = this.handlerMap.keys()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
|
|
479
|
+
var event = _step1.value;
|
|
480
|
+
this.attachSSEListener(event);
|
|
481
|
+
}
|
|
482
|
+
} catch (err) {
|
|
483
|
+
_didIteratorError1 = true;
|
|
484
|
+
_iteratorError1 = err;
|
|
485
|
+
} finally {
|
|
486
|
+
try {
|
|
487
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
488
|
+
_iterator1.return();
|
|
489
|
+
}
|
|
490
|
+
} finally {
|
|
491
|
+
if (_didIteratorError1) {
|
|
492
|
+
throw _iteratorError1;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}, {
|
|
498
|
+
key: "attachSSEListener",
|
|
499
|
+
value: function attachSSEListener(type) {
|
|
500
|
+
var _this = this;
|
|
501
|
+
if (!this.eventSource || this.attachedSseEvents.has(type)) return;
|
|
502
|
+
var listener = function listener2(event) {
|
|
503
|
+
_this.handleSSEEvent(type, event);
|
|
504
|
+
};
|
|
505
|
+
this.sseListeners.set(type, listener);
|
|
506
|
+
this.attachedSseEvents.add(type);
|
|
507
|
+
this.eventSource.addEventListener(type, listener);
|
|
508
|
+
}
|
|
509
|
+
}, {
|
|
510
|
+
key: "detachSSEListener",
|
|
511
|
+
value: function detachSSEListener(type) {
|
|
512
|
+
if (this.isCoreSSEType(type)) return;
|
|
513
|
+
if (!this.eventSource || !this.attachedSseEvents.has(type)) return;
|
|
514
|
+
var listener = this.sseListeners.get(type);
|
|
515
|
+
if (listener) {
|
|
516
|
+
this.eventSource.removeEventListener(type, listener);
|
|
517
|
+
this.sseListeners.delete(type);
|
|
518
|
+
}
|
|
519
|
+
this.attachedSseEvents.delete(type);
|
|
520
|
+
}
|
|
521
|
+
}, {
|
|
522
|
+
key: "isCoreSSEType",
|
|
523
|
+
value: function isCoreSSEType(type) {
|
|
524
|
+
var _ref;
|
|
525
|
+
var _this_config_sse;
|
|
526
|
+
return type === "open" || type === "error" || type === "message" || ((_ref = (_this_config_sse = this.config.sse) === null || _this_config_sse === void 0 ? void 0 : _this_config_sse.events) !== null && _ref !== void 0 ? _ref : []).includes(type);
|
|
527
|
+
}
|
|
528
|
+
}, {
|
|
529
|
+
key: "handleSSEEvent",
|
|
530
|
+
value: (
|
|
531
|
+
/**
|
|
532
|
+
* Single entry point for everything the EventSource dispatches. Dataless
|
|
533
|
+
* events are transport lifecycle (`open`/`error` as plain Events); anything
|
|
534
|
+
* carrying `data` is a server frame — including frames the server
|
|
535
|
+
* classified `event: error`, which arrive as MessageEvents WITH data and
|
|
536
|
+
* must not be mistaken for connection errors.
|
|
537
|
+
*/
|
|
538
|
+
function handleSSEEvent(type, event) {
|
|
539
|
+
var _event_lastEventId;
|
|
540
|
+
var _this_config_sse;
|
|
541
|
+
if ((event === null || event === void 0 ? void 0 : event.data) === void 0) {
|
|
542
|
+
if (type === "open") {
|
|
543
|
+
this.isConnecting = false;
|
|
544
|
+
this.socketHealthy = true;
|
|
545
|
+
this.emitToHandlers("connected", {
|
|
546
|
+
transport: "sse"
|
|
547
|
+
});
|
|
548
|
+
this.resolveHealthyWaiters(true);
|
|
549
|
+
} else if (type === "error") {
|
|
550
|
+
this.isConnecting = false;
|
|
551
|
+
this.socketHealthy = false;
|
|
552
|
+
this.emitToHandlers("disconnect", {
|
|
553
|
+
reason: "sse-error"
|
|
554
|
+
});
|
|
555
|
+
this.resolveHealthyWaiters(false);
|
|
556
|
+
}
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
var frame = {
|
|
560
|
+
type,
|
|
561
|
+
data: String(event.data),
|
|
562
|
+
lastEventId: (_event_lastEventId = event.lastEventId) !== null && _event_lastEventId !== void 0 ? _event_lastEventId : ""
|
|
563
|
+
};
|
|
564
|
+
var mapFrame = (_this_config_sse = this.config.sse) === null || _this_config_sse === void 0 ? void 0 : _this_config_sse.mapFrame;
|
|
565
|
+
if (mapFrame) {
|
|
566
|
+
var mapped;
|
|
567
|
+
try {
|
|
568
|
+
mapped = mapFrame(frame);
|
|
569
|
+
} catch (err) {
|
|
570
|
+
console.warn("[RealtimeModule] sse.mapFrame threw; frame dropped:", err);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
if (!mapped) return;
|
|
574
|
+
var _iteratorNormalCompletion = true,
|
|
575
|
+
_didIteratorError = false,
|
|
576
|
+
_iteratorError = void 0;
|
|
577
|
+
try {
|
|
578
|
+
for (var _iterator = mapped[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
579
|
+
var {
|
|
580
|
+
event: mappedEvent,
|
|
581
|
+
payload
|
|
582
|
+
} = _step.value;
|
|
583
|
+
this.emitToHandlers(mappedEvent, payload);
|
|
584
|
+
}
|
|
585
|
+
} catch (err) {
|
|
586
|
+
_didIteratorError = true;
|
|
587
|
+
_iteratorError = err;
|
|
588
|
+
} finally {
|
|
589
|
+
try {
|
|
590
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
591
|
+
_iterator.return();
|
|
592
|
+
}
|
|
593
|
+
} finally {
|
|
594
|
+
if (_didIteratorError) {
|
|
595
|
+
throw _iteratorError;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
var payload1 = frame.data;
|
|
602
|
+
try {
|
|
603
|
+
payload1 = JSON.parse(frame.data);
|
|
604
|
+
} catch (unused) {}
|
|
605
|
+
this.emitToHandlers(frame.type, payload1);
|
|
606
|
+
})
|
|
607
|
+
}, {
|
|
608
|
+
key: "logSSERoomNoticeOnce",
|
|
609
|
+
value: (
|
|
610
|
+
/**
|
|
611
|
+
* Logged once: SSE is one-way, so doc/list room membership can't be sent
|
|
612
|
+
* upstream — rooms are recorded client-side (see getDocRooms/getListRooms)
|
|
613
|
+
* for mapFrame-driven filtering and for a future two-way transport.
|
|
614
|
+
*/
|
|
615
|
+
function logSSERoomNoticeOnce() {
|
|
616
|
+
if (this.sseRoomNoticeLogged) return;
|
|
617
|
+
this.sseRoomNoticeLogged = true;
|
|
618
|
+
console.debug("[RealtimeModule] SSE transport is one-way: doc/list room subscriptions are recorded client-side only (getDocRooms()/getListRooms()) and nothing is sent to the server \u2014 filter server-side via sse.queryParams or route frames with sse.mapFrame.");
|
|
619
|
+
})
|
|
338
620
|
}, {
|
|
339
621
|
key: "softDisconnect",
|
|
340
622
|
value: (
|
|
@@ -350,8 +632,36 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
350
632
|
this.socket.disconnect();
|
|
351
633
|
this.socket = void 0;
|
|
352
634
|
}
|
|
635
|
+
if (this.eventSource) {
|
|
636
|
+
var _iteratorNormalCompletion = true,
|
|
637
|
+
_didIteratorError = false,
|
|
638
|
+
_iteratorError = void 0;
|
|
639
|
+
try {
|
|
640
|
+
for (var _iterator = this.sseListeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
641
|
+
var [type, listener] = _step.value;
|
|
642
|
+
this.eventSource.removeEventListener(type, listener);
|
|
643
|
+
}
|
|
644
|
+
} catch (err) {
|
|
645
|
+
_didIteratorError = true;
|
|
646
|
+
_iteratorError = err;
|
|
647
|
+
} finally {
|
|
648
|
+
try {
|
|
649
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
650
|
+
_iterator.return();
|
|
651
|
+
}
|
|
652
|
+
} finally {
|
|
653
|
+
if (_didIteratorError) {
|
|
654
|
+
throw _iteratorError;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
this.eventSource.close();
|
|
659
|
+
this.eventSource = void 0;
|
|
660
|
+
}
|
|
353
661
|
this.attachedSocketEvents.clear();
|
|
354
662
|
this.socketEventHandlers.clear();
|
|
663
|
+
this.attachedSseEvents.clear();
|
|
664
|
+
this.sseListeners.clear();
|
|
355
665
|
this.socketHealthy = false;
|
|
356
666
|
this.isConnecting = false;
|
|
357
667
|
this.resolveHealthyWaiters(false);
|
|
@@ -482,7 +792,11 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
482
792
|
this.handlerMap.set(event, handlerSet);
|
|
483
793
|
}
|
|
484
794
|
handlerSet.add(handler);
|
|
485
|
-
this.
|
|
795
|
+
if (this.isSSE()) {
|
|
796
|
+
this.attachSSEListener(event);
|
|
797
|
+
} else {
|
|
798
|
+
this.attachSocketListener(event);
|
|
799
|
+
}
|
|
486
800
|
}
|
|
487
801
|
}, {
|
|
488
802
|
key: "off",
|
|
@@ -492,7 +806,11 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
492
806
|
handlerSet.delete(handler);
|
|
493
807
|
if (handlerSet.size === 0) {
|
|
494
808
|
this.handlerMap.delete(event);
|
|
495
|
-
this.
|
|
809
|
+
if (this.isSSE()) {
|
|
810
|
+
this.detachSSEListener(event);
|
|
811
|
+
} else {
|
|
812
|
+
this.detachSocketListener(event);
|
|
813
|
+
}
|
|
496
814
|
}
|
|
497
815
|
}
|
|
498
816
|
}, {
|
|
@@ -502,8 +820,9 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
502
820
|
doctype,
|
|
503
821
|
name
|
|
504
822
|
});
|
|
823
|
+
if (this.isSSE()) this.logSSERoomNoticeOnce();
|
|
505
824
|
await this.ensureConnected();
|
|
506
|
-
if (this.socket && this.socketHealthy) {
|
|
825
|
+
if (!this.isSSE() && this.socket && this.socketHealthy) {
|
|
507
826
|
this.socket.emit("doc_subscribe", doctype, name);
|
|
508
827
|
}
|
|
509
828
|
}
|
|
@@ -511,7 +830,7 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
511
830
|
key: "unsubscribeDoc",
|
|
512
831
|
value: function unsubscribeDoc(doctype, name) {
|
|
513
832
|
this.docRooms.delete(docRoomKey(doctype, name));
|
|
514
|
-
if (this.socket && this.socketHealthy) {
|
|
833
|
+
if (!this.isSSE() && this.socket && this.socketHealthy) {
|
|
515
834
|
this.socket.emit("doc_unsubscribe", doctype, name);
|
|
516
835
|
}
|
|
517
836
|
this.teardownWhenIdle();
|
|
@@ -531,8 +850,9 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
531
850
|
doctype,
|
|
532
851
|
filters
|
|
533
852
|
});
|
|
853
|
+
if (this.isSSE()) this.logSSERoomNoticeOnce();
|
|
534
854
|
await this.ensureConnected();
|
|
535
|
-
if (this.socket && this.socketHealthy) {
|
|
855
|
+
if (!this.isSSE() && this.socket && this.socketHealthy) {
|
|
536
856
|
this.socket.emit("doctype_subscribe", doctype);
|
|
537
857
|
}
|
|
538
858
|
})
|
|
@@ -540,7 +860,7 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
540
860
|
key: "unsubscribeList",
|
|
541
861
|
value: function unsubscribeList(doctype) {
|
|
542
862
|
this.listRooms.delete(doctype);
|
|
543
|
-
if (this.socket && this.socketHealthy) {
|
|
863
|
+
if (!this.isSSE() && this.socket && this.socketHealthy) {
|
|
544
864
|
this.socket.emit("doctype_unsubscribe", doctype);
|
|
545
865
|
}
|
|
546
866
|
this.teardownWhenIdle();
|
|
@@ -559,7 +879,7 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
559
879
|
*/
|
|
560
880
|
function teardownWhenIdle() {
|
|
561
881
|
if (this.docRooms.size > 0 || this.listRooms.size > 0) return;
|
|
562
|
-
if (!this.socket && !this.isConnecting) return;
|
|
882
|
+
if (!this.socket && !this.eventSource && !this.isConnecting) return;
|
|
563
883
|
this.emitToHandlers("disconnect", {
|
|
564
884
|
reason: "idle-teardown"
|
|
565
885
|
});
|
|
@@ -569,6 +889,7 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
569
889
|
key: "isHealthy",
|
|
570
890
|
value: function isHealthy() {
|
|
571
891
|
var _this_socket;
|
|
892
|
+
if (this.isSSE()) return this.socketHealthy && this.eventSource !== void 0;
|
|
572
893
|
return this.socketHealthy && ((_this_socket = this.socket) === null || _this_socket === void 0 ? void 0 : _this_socket.connected) === true;
|
|
573
894
|
}
|
|
574
895
|
}, {
|
|
@@ -583,7 +904,7 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
583
904
|
key: "updateAuth",
|
|
584
905
|
value: async function updateAuth(auth) {
|
|
585
906
|
this.config.auth = auth;
|
|
586
|
-
var shouldReconnect = this.docRooms.size > 0 || this.listRooms.size > 0;
|
|
907
|
+
var shouldReconnect = this.docRooms.size > 0 || this.listRooms.size > 0 || this.isSSE() && this.eventSource !== void 0;
|
|
587
908
|
this.softDisconnect();
|
|
588
909
|
if (shouldReconnect) {
|
|
589
910
|
await this.connect();
|
|
@@ -592,6 +913,13 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
592
913
|
}, {
|
|
593
914
|
key: "emit",
|
|
594
915
|
value: function emit(event, data) {
|
|
916
|
+
if (this.isSSE()) {
|
|
917
|
+
if (!this.sseEmitNoticeLogged) {
|
|
918
|
+
this.sseEmitNoticeLogged = true;
|
|
919
|
+
console.debug("[RealtimeModule] emit() is a no-op under the SSE transport \u2014 SSE is one-way (server \u2192 client). Use HTTP calls for client \u2192 server communication.");
|
|
920
|
+
}
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
595
923
|
if (this.socket && this.socketHealthy) {
|
|
596
924
|
this.socket.emit(event, data);
|
|
597
925
|
}
|
|
@@ -601,6 +929,28 @@ var RealtimeModule = /* @__PURE__ */function () {
|
|
|
601
929
|
value: function getSocket() {
|
|
602
930
|
return this.socket;
|
|
603
931
|
}
|
|
932
|
+
}, {
|
|
933
|
+
/** Live EventSource when the SSE transport is connected (undefined otherwise). */
|
|
934
|
+
key: "getEventSource",
|
|
935
|
+
value: function getEventSource() {
|
|
936
|
+
return this.eventSource;
|
|
937
|
+
}
|
|
938
|
+
}, {
|
|
939
|
+
/**
|
|
940
|
+
* Doc rooms recorded by subscribeDoc. Under SSE these are client-side
|
|
941
|
+
* bookkeeping only (nothing is emitted upstream) — mapFrame-driven apps
|
|
942
|
+
* consult them to filter or route frames.
|
|
943
|
+
*/
|
|
944
|
+
key: "getDocRooms",
|
|
945
|
+
value: function getDocRooms() {
|
|
946
|
+
return [...this.docRooms.values()];
|
|
947
|
+
}
|
|
948
|
+
}, {
|
|
949
|
+
/** List rooms recorded by subscribeList — same client-side semantics as getDocRooms. */
|
|
950
|
+
key: "getListRooms",
|
|
951
|
+
value: function getListRooms() {
|
|
952
|
+
return [...this.listRooms.values()];
|
|
953
|
+
}
|
|
604
954
|
}]);
|
|
605
955
|
return RealtimeModule2;
|
|
606
956
|
}();
|