@m4l/realtime-runtime 1.1.0 → 1.2.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/contracts/index.d.ts +1 -1
- package/contracts/index.d.ts.map +1 -1
- package/contracts/types.d.ts +88 -4
- package/contracts/types.d.ts.map +1 -1
- package/engine/runtimeCore.d.ts +3 -1
- package/engine/runtimeCore.d.ts.map +1 -1
- package/engine/runtimeCore.js +9 -7
- package/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +7 -6
- package/package.json +1 -1
- package/transport/atmosphere/SourceDataAtmosphere.d.ts +41 -9
- package/transport/atmosphere/SourceDataAtmosphere.d.ts.map +1 -1
- package/transport/atmosphere/SourceDataAtmosphere.js +240 -96
- package/transport/atmosphere/createAtmosphereSourceData.d.ts +7 -3
- package/transport/atmosphere/createAtmosphereSourceData.d.ts.map +1 -1
- package/transport/atmosphere/createAtmosphereSourceData.js +33 -4
- package/transport/atmosphere/index.d.ts +1 -1
- package/transport/atmosphere/index.d.ts.map +1 -1
- package/transport/atmosphere/types.d.ts +24 -3
- package/transport/atmosphere/types.d.ts.map +1 -1
- package/transport/index.d.ts +1 -1
- package/transport/index.d.ts.map +1 -1
- package/web/index.d.ts +1 -1
- package/web/index.d.ts.map +1 -1
- package/web/runtime.d.ts.map +1 -1
- package/web/runtime.js +55 -53
- package/web/store.d.ts +2 -2
- package/web/store.d.ts.map +1 -1
- package/web/store.helpers.d.ts +24 -4
- package/web/store.helpers.d.ts.map +1 -1
- package/web/store.helpers.js +126 -23
- package/web/store.js +261 -80
- package/web/tools.d.ts.map +1 -1
- package/web/tools.js +15 -4
- package/web/types.d.ts +32 -3
- package/web/types.d.ts.map +1 -1
- package/web.d.ts +1 -1
- package/web.d.ts.map +1 -1
package/web/store.js
CHANGED
|
@@ -1,50 +1,76 @@
|
|
|
1
|
-
import { createStore as
|
|
2
|
-
import { immer as
|
|
3
|
-
import { ObjectQueue as
|
|
4
|
-
import { REALTIME_PRODUCER_STORE_ID as
|
|
5
|
-
import { cloneDeep as
|
|
6
|
-
import { createProducerDevtools as
|
|
7
|
-
function
|
|
8
|
-
return typeof
|
|
1
|
+
import { createStore as B } from "zustand";
|
|
2
|
+
import { immer as x } from "zustand/middleware/immer";
|
|
3
|
+
import { ObjectQueue as H } from "../engine/ObjectQueue.js";
|
|
4
|
+
import { REALTIME_PRODUCER_STORE_ID as L } from "./constants.js";
|
|
5
|
+
import { cloneDeep as z } from "lodash-es";
|
|
6
|
+
import { createProducerDevtools as _, drainQueuedMessages as N, sanitizeProducerMessage as $, createRealtimePatchedResourceSnapshot as U, applyProducerMessage as W, notifySubscribersWithBatch as F, groupMessagesByResourceTypeId as G, normalizeProducerMessage as J } from "./store.helpers.js";
|
|
7
|
+
function Q() {
|
|
8
|
+
return typeof globalThis.performance?.now == "function" ? globalThis.performance.now() : Date.now();
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function T(d) {
|
|
11
|
+
return d ? Q() : 0;
|
|
12
|
+
}
|
|
13
|
+
function R(d, p, M) {
|
|
14
|
+
d?.(p, M);
|
|
15
|
+
}
|
|
16
|
+
function P(d, p, M) {
|
|
17
|
+
d && d(
|
|
18
|
+
p,
|
|
19
|
+
Math.max(0, Q() - M)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function O(d, p) {
|
|
23
|
+
return typeof p == "object" && p !== null && "resourceSerialId" in p && typeof p.resourceSerialId == "string" ? p.resourceSerialId : d;
|
|
24
|
+
}
|
|
25
|
+
function ee(d, p = !1, M) {
|
|
26
|
+
const {
|
|
27
|
+
onPerformanceMetric: o,
|
|
28
|
+
startSourceData: k = !0,
|
|
29
|
+
...w
|
|
30
|
+
} = d, v = {
|
|
31
|
+
...w,
|
|
13
32
|
hasResourcesTypes: {}
|
|
14
|
-
},
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
...
|
|
33
|
+
}, A = {}, C = {};
|
|
34
|
+
return B(
|
|
35
|
+
_(
|
|
36
|
+
x((S, a) => ({
|
|
37
|
+
...v,
|
|
19
38
|
realTimeProducerActions: {
|
|
20
39
|
/**
|
|
21
40
|
* Initialize the configured resources and start their source mechanisms.
|
|
22
41
|
*/
|
|
23
42
|
init: () => {
|
|
24
|
-
const { resourceTypesConfig: e, realTimeProducerActions:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
const { resourceTypesConfig: e, realTimeProducerActions: t } = a(), s = (i, c) => {
|
|
44
|
+
t.ingestMessages(
|
|
45
|
+
i,
|
|
46
|
+
c,
|
|
47
|
+
"transport"
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
S((i) => {
|
|
51
|
+
const c = Date.now();
|
|
52
|
+
for (const r of e) {
|
|
53
|
+
const n = r.initialHashResources ? z(r.initialHashResources) : {};
|
|
54
|
+
i.hasResourcesTypes[r.resourceTypeId] = {
|
|
55
|
+
config: r,
|
|
31
56
|
sourceDataClass: M(
|
|
57
|
+
r,
|
|
32
58
|
s,
|
|
33
|
-
|
|
59
|
+
o
|
|
34
60
|
),
|
|
35
61
|
status: "init",
|
|
36
|
-
hasResources:
|
|
62
|
+
hasResources: n,
|
|
37
63
|
subscribedClients: {}
|
|
38
|
-
},
|
|
64
|
+
}, A[r.resourceTypeId] = {
|
|
39
65
|
messagesToProcces: [],
|
|
40
|
-
messagesQueue: new
|
|
66
|
+
messagesQueue: new H(),
|
|
41
67
|
statusProccesing: !1
|
|
42
|
-
},
|
|
43
|
-
Object.entries(
|
|
44
|
-
|
|
45
|
-
|
|
68
|
+
}, C[r.resourceTypeId] = new Map(
|
|
69
|
+
Object.entries(n).map(([l, u]) => [
|
|
70
|
+
O(l, u),
|
|
71
|
+
c
|
|
46
72
|
])
|
|
47
|
-
),
|
|
73
|
+
), k && i.hasResourcesTypes[r.resourceTypeId].sourceDataClass.start();
|
|
48
74
|
}
|
|
49
75
|
});
|
|
50
76
|
},
|
|
@@ -53,95 +79,250 @@ function _(p, a = !1, M) {
|
|
|
53
79
|
*/
|
|
54
80
|
setStatus: (e) => {
|
|
55
81
|
},
|
|
82
|
+
/**
|
|
83
|
+
* Return the current resource hash by reference for consumers that copy/project it immediately.
|
|
84
|
+
*/
|
|
85
|
+
getResourceTypeSnapshot: (e) => a().hasResourcesTypes[e]?.hasResources ?? {},
|
|
86
|
+
/**
|
|
87
|
+
* Subscribe one MF client and return the current producer hash without cloning it.
|
|
88
|
+
*/
|
|
89
|
+
subscribeResourceType: (e, t) => (S((s) => {
|
|
90
|
+
e in s.hasResourcesTypes && (s.hasResourcesTypes[e].subscribedClients[t.clientId] = t);
|
|
91
|
+
}), a().realTimeProducerActions.getResourceTypeSnapshot(e)),
|
|
56
92
|
/**
|
|
57
93
|
* Subscribe one MF client and send the current producer hash through callbacks.
|
|
58
94
|
*/
|
|
59
|
-
subscribe: (e,
|
|
60
|
-
const { onSubscribeCallbacks:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
for (let
|
|
65
|
-
const
|
|
66
|
-
|
|
95
|
+
subscribe: (e, t) => {
|
|
96
|
+
const { onSubscribeCallbacks: s, ...i } = t, c = a().realTimeProducerActions.subscribeResourceType(
|
|
97
|
+
e,
|
|
98
|
+
i
|
|
99
|
+
);
|
|
100
|
+
for (let r = 0; r < s.length; r++) {
|
|
101
|
+
const n = s[r];
|
|
102
|
+
n(
|
|
103
|
+
e,
|
|
104
|
+
z(c)
|
|
105
|
+
);
|
|
67
106
|
}
|
|
68
107
|
},
|
|
69
108
|
/**
|
|
70
109
|
* Unsubscribe one MF client from the current resource type.
|
|
71
110
|
*/
|
|
72
|
-
unsubscribe: (e,
|
|
73
|
-
|
|
74
|
-
delete
|
|
111
|
+
unsubscribe: (e, t) => {
|
|
112
|
+
S((s) => {
|
|
113
|
+
delete s.hasResourcesTypes[e].subscribedClients[t];
|
|
75
114
|
});
|
|
76
115
|
},
|
|
77
116
|
/**
|
|
78
117
|
* Enqueue one incoming realtime batch and start draining the queue.
|
|
79
118
|
*/
|
|
80
|
-
onMessages: (e,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
119
|
+
onMessages: (e, t) => {
|
|
120
|
+
a().realTimeProducerActions.ingestMessages(
|
|
121
|
+
e,
|
|
122
|
+
t,
|
|
123
|
+
"transport"
|
|
124
|
+
);
|
|
84
125
|
},
|
|
85
126
|
/**
|
|
86
|
-
*
|
|
127
|
+
* Enqueue one incoming batch with explicit ingress metadata and start draining the matching queues.
|
|
128
|
+
*/
|
|
129
|
+
ingestMessages: (e, t, s) => {
|
|
130
|
+
R(
|
|
131
|
+
o,
|
|
132
|
+
"producerIncomingBatch",
|
|
133
|
+
t.length
|
|
134
|
+
), G(
|
|
135
|
+
e,
|
|
136
|
+
t,
|
|
137
|
+
s
|
|
138
|
+
).forEach((c, r) => {
|
|
139
|
+
const n = A[r], l = a().hasResourcesTypes[r]?.config;
|
|
140
|
+
if (!n) {
|
|
141
|
+
console.error(
|
|
142
|
+
"Realtime producer received one batch for an unknown resourceTypeId; dropping those messages.",
|
|
143
|
+
{
|
|
144
|
+
routingContextResourceTypeId: e,
|
|
145
|
+
targetResourceTypeId: r,
|
|
146
|
+
messages: c.map((u) => u.message)
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
c.forEach((u) => {
|
|
152
|
+
const f = l ? J(
|
|
153
|
+
u.message,
|
|
154
|
+
l,
|
|
155
|
+
u.reason
|
|
156
|
+
) : u.message;
|
|
157
|
+
f && n.messagesQueue.enqueue({
|
|
158
|
+
...u,
|
|
159
|
+
message: f
|
|
160
|
+
});
|
|
161
|
+
}), R(
|
|
162
|
+
o,
|
|
163
|
+
"producerQueueLength",
|
|
164
|
+
n.messagesQueue.size()
|
|
165
|
+
), a().realTimeProducerActions.processMessages(r);
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
/**
|
|
169
|
+
* Drain one resource-type queue, sanitize its messages, and publish one ordered batch.
|
|
170
|
+
*
|
|
171
|
+
* Why this algorithm exists:
|
|
172
|
+
* - Realtime messages can arrive from sockets and startup snapshots faster than we should mutate Zustand.
|
|
173
|
+
* - Resource-type sanitizers need a stable plain-object "current resource" input, not an Immer draft.
|
|
174
|
+
* - One drained batch can contain several messages for the same resource, so later messages must see
|
|
175
|
+
* the sanitized result of earlier messages even before the Zustand transaction is committed.
|
|
176
|
+
*
|
|
177
|
+
* What it does:
|
|
178
|
+
* 1. Locks the resource-type queue so only one drain runs at a time.
|
|
179
|
+
* 2. Moves the current queue into a local ordered batch; messages arriving later stay queued.
|
|
180
|
+
* 3. Pre-sanitizes every message outside Immer using the current resource snapshot.
|
|
181
|
+
* 4. Builds a lightweight working snapshot only for resources repeated in the same batch.
|
|
182
|
+
* 5. Applies the sanitized patches in one Zustand transaction and notifies subscribers with that same batch.
|
|
183
|
+
*
|
|
184
|
+
* Final guarantee:
|
|
185
|
+
* Producer state and subscribers observe the same ordered, resource-type-normalized patch batch, while
|
|
186
|
+
* messages enqueued during apply/notify are deferred to the next drain instead of being interleaved.
|
|
87
187
|
*/
|
|
88
188
|
processMessages: (e) => {
|
|
89
|
-
const
|
|
90
|
-
|
|
189
|
+
const t = T(
|
|
190
|
+
o
|
|
191
|
+
), s = A[e], i = C[e];
|
|
192
|
+
if (s.statusProccesing)
|
|
91
193
|
return;
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
if (!
|
|
95
|
-
|
|
194
|
+
s.statusProccesing = !0;
|
|
195
|
+
const c = N(s.messagesQueue);
|
|
196
|
+
if (!c.length) {
|
|
197
|
+
s.statusProccesing = !1;
|
|
96
198
|
return;
|
|
97
199
|
}
|
|
98
|
-
|
|
99
|
-
|
|
200
|
+
R(
|
|
201
|
+
o,
|
|
202
|
+
"producerDrainSet",
|
|
203
|
+
c.length
|
|
204
|
+
);
|
|
205
|
+
const r = Date.now(), n = a().hasResourcesTypes[e], l = /* @__PURE__ */ new Map();
|
|
206
|
+
c.forEach(({ message: h }) => {
|
|
207
|
+
const m = h.resourceSerialId;
|
|
208
|
+
l.set(
|
|
209
|
+
m,
|
|
210
|
+
(l.get(m) ?? 0) + 1
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
let u = 0;
|
|
214
|
+
l.forEach((h) => {
|
|
215
|
+
h > 1 && (u += 1);
|
|
216
|
+
}), R(
|
|
217
|
+
o,
|
|
218
|
+
"producerRepeatedResourceCount",
|
|
219
|
+
u
|
|
220
|
+
), o && R(
|
|
221
|
+
o,
|
|
222
|
+
"producerSubscriberCount",
|
|
223
|
+
Object.keys(n.subscribedClients).length
|
|
224
|
+
);
|
|
225
|
+
const f = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Set(), j = T(
|
|
226
|
+
o
|
|
227
|
+
), E = c.map(({
|
|
228
|
+
message: h,
|
|
229
|
+
reason: m
|
|
230
|
+
}) => {
|
|
231
|
+
const g = h.resourceSerialId, D = b.has(g) ? f.get(g) : n.hasResources[g], y = $(
|
|
232
|
+
D,
|
|
233
|
+
h,
|
|
234
|
+
n.config,
|
|
235
|
+
m
|
|
236
|
+
);
|
|
237
|
+
return (l.get(g) ?? 0) > 1 && (b.add(g), y.type === "delete" ? f.set(g, void 0) : f.set(
|
|
238
|
+
g,
|
|
239
|
+
U(
|
|
240
|
+
D ?? {},
|
|
241
|
+
y.payload,
|
|
242
|
+
g
|
|
243
|
+
)
|
|
244
|
+
)), y;
|
|
245
|
+
});
|
|
246
|
+
P(
|
|
247
|
+
o,
|
|
248
|
+
"producerSanitizeDurationMs",
|
|
249
|
+
j
|
|
250
|
+
);
|
|
100
251
|
try {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
252
|
+
const h = T(
|
|
253
|
+
o
|
|
254
|
+
);
|
|
255
|
+
S((g) => {
|
|
256
|
+
const y = g.hasResourcesTypes[e].hasResources;
|
|
257
|
+
E.forEach((I) => {
|
|
258
|
+
W(
|
|
259
|
+
y,
|
|
260
|
+
i,
|
|
261
|
+
I,
|
|
262
|
+
r
|
|
263
|
+
);
|
|
105
264
|
});
|
|
106
|
-
}),
|
|
265
|
+
}), P(
|
|
266
|
+
o,
|
|
267
|
+
"producerApplyDurationMs",
|
|
268
|
+
h
|
|
269
|
+
), o && R(
|
|
270
|
+
o,
|
|
271
|
+
"producerResourceCount",
|
|
272
|
+
Object.keys(a().hasResourcesTypes[e].hasResources).length
|
|
273
|
+
);
|
|
274
|
+
const m = T(
|
|
275
|
+
o
|
|
276
|
+
);
|
|
277
|
+
F(
|
|
107
278
|
e,
|
|
108
|
-
|
|
109
|
-
|
|
279
|
+
a().hasResourcesTypes[e].subscribedClients,
|
|
280
|
+
E
|
|
281
|
+
), P(
|
|
282
|
+
o,
|
|
283
|
+
"producerNotifyDurationMs",
|
|
284
|
+
m
|
|
110
285
|
);
|
|
111
286
|
} finally {
|
|
112
|
-
|
|
287
|
+
P(
|
|
288
|
+
o,
|
|
289
|
+
"producerProcessDurationMs",
|
|
290
|
+
t
|
|
291
|
+
), s.statusProccesing = !1;
|
|
113
292
|
}
|
|
114
|
-
|
|
293
|
+
s.messagesQueue.isEmpty() || a().realTimeProducerActions.processMessages(e);
|
|
115
294
|
},
|
|
116
295
|
/**
|
|
117
296
|
* Emit delete messages for resources that have not received updates inside the configured TTL window.
|
|
118
297
|
*/
|
|
119
|
-
cleanupStaleResources: (e,
|
|
120
|
-
const
|
|
121
|
-
if (!
|
|
298
|
+
cleanupStaleResources: (e, t = Date.now()) => {
|
|
299
|
+
const s = a().hasResourcesTypes[e], i = s?.config.staleResourceTtlMs, c = C[e];
|
|
300
|
+
if (!s || !c || i === void 0 || i <= 0)
|
|
122
301
|
return 0;
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
),
|
|
128
|
-
return
|
|
302
|
+
const r = Object.keys(s.hasResources).reduce((n, l) => {
|
|
303
|
+
const u = s.hasResources[l], f = O(
|
|
304
|
+
l,
|
|
305
|
+
u
|
|
306
|
+
), b = c.get(f);
|
|
307
|
+
return b !== void 0 && t - b > i && n.push(f), n;
|
|
129
308
|
}, []);
|
|
130
|
-
return
|
|
309
|
+
return r.length ? (a().realTimeProducerActions.ingestMessages(
|
|
131
310
|
e,
|
|
132
|
-
|
|
311
|
+
r.map((n) => ({
|
|
133
312
|
payload: {},
|
|
313
|
+
resourceTypeId: e,
|
|
134
314
|
resourceSerialId: n,
|
|
135
315
|
type: "delete"
|
|
136
|
-
}))
|
|
137
|
-
|
|
316
|
+
})),
|
|
317
|
+
"cleanup"
|
|
318
|
+
), r.length) : 0;
|
|
138
319
|
}
|
|
139
320
|
}
|
|
140
321
|
})),
|
|
141
|
-
{ name: `${
|
|
322
|
+
{ name: `${L}: ${w.storeId}`, enabled: p }
|
|
142
323
|
)
|
|
143
324
|
);
|
|
144
325
|
}
|
|
145
326
|
export {
|
|
146
|
-
|
|
327
|
+
ee as createRealTimeStore
|
|
147
328
|
};
|
package/web/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../../../packages/realtime-runtime/src/web/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EACV,qBAAqB,EACtB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,iBAAiB,GACvB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../../../packages/realtime-runtime/src/web/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EACV,qBAAqB,EACtB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,iBAAiB,GACvB,qBAAqB,CAyDvB"}
|
package/web/tools.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
function
|
|
1
|
+
function b(t) {
|
|
2
2
|
return {
|
|
3
|
+
getResourceTypeSnapshot: (e) => t.getState().realTimeProducerActions.getResourceTypeSnapshot(
|
|
4
|
+
e
|
|
5
|
+
),
|
|
3
6
|
getResourceRuntimeMeta: (e) => {
|
|
4
7
|
const s = t.getState().hasResourcesTypes[e];
|
|
5
8
|
return s ? {
|
|
@@ -7,17 +10,25 @@ function i(t) {
|
|
|
7
10
|
sourceDataMechanism: s.config.sourceDataMechanism
|
|
8
11
|
} : null;
|
|
9
12
|
},
|
|
10
|
-
publishMessages: (e, s) => {
|
|
11
|
-
t.getState().realTimeProducerActions.
|
|
13
|
+
publishMessages: (e, s, r = "publish") => {
|
|
14
|
+
t.getState().realTimeProducerActions.ingestMessages(
|
|
15
|
+
e,
|
|
16
|
+
s,
|
|
17
|
+
r
|
|
18
|
+
);
|
|
12
19
|
},
|
|
13
20
|
subscribe: (e, s) => {
|
|
14
21
|
t.getState().realTimeProducerActions.subscribe(e, s);
|
|
15
22
|
},
|
|
23
|
+
subscribeResourceType: (e, s) => t.getState().realTimeProducerActions.subscribeResourceType(
|
|
24
|
+
e,
|
|
25
|
+
s
|
|
26
|
+
),
|
|
16
27
|
unsubscribe: (e, s) => {
|
|
17
28
|
t.getState().realTimeProducerActions.unsubscribe(e, s);
|
|
18
29
|
}
|
|
19
30
|
};
|
|
20
31
|
}
|
|
21
32
|
export {
|
|
22
|
-
|
|
33
|
+
b as createRealTimeProducerTools
|
|
23
34
|
};
|
package/web/types.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { ObjectQueue } from '../engine/ObjectQueue';
|
|
2
|
-
import { OnMessagesStoreCallback, OnRealTimeProducerMetricCallback, RealTimeMessage, RealTimeResourceHash, RealTimeResourceSourceMechanismConfig, RealTimeResourceTypeId, RealTimeStatus, Subscriber, SubscribeOptions } from '../contracts';
|
|
2
|
+
import { OnMessagesStoreCallback, OnRealTimeProducerMetricCallback, RealTimeMessage, RealTimeMessageIngressReason, RealTimeReadonlyResourceHash, RealTimeResourceHash, RealTimeResourceSourceMechanismConfig, RealTimeResourceTypeId, RealTimeStatus, Subscriber, SubscribeOptions, SubscribeResourceTypeOptions } from '../contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Internal queued message entry that preserves the ingress reason across async producer draining.
|
|
5
|
+
*/
|
|
6
|
+
export interface QueuedRealTimeMessage {
|
|
7
|
+
/**
|
|
8
|
+
* Realtime payload awaiting producer application.
|
|
9
|
+
*/
|
|
10
|
+
message: RealTimeMessage;
|
|
11
|
+
/**
|
|
12
|
+
* Why the current payload entered the producer pipeline.
|
|
13
|
+
*/
|
|
14
|
+
reason: RealTimeMessageIngressReason;
|
|
15
|
+
}
|
|
3
16
|
/**
|
|
4
17
|
* Realtime queue manager kept outside the reactive store state.
|
|
5
18
|
*/
|
|
6
|
-
export interface MessageQueueManager {
|
|
19
|
+
export interface MessageQueueManager<TMessage = RealTimeMessage> {
|
|
7
20
|
/**
|
|
8
21
|
* Legacy field kept for backward compatibility with the existing store shape.
|
|
9
22
|
*/
|
|
@@ -11,7 +24,7 @@ export interface MessageQueueManager {
|
|
|
11
24
|
/**
|
|
12
25
|
* Queue kept outside Zustand reconciliation so enqueue and dequeue stay O(1).
|
|
13
26
|
*/
|
|
14
|
-
messagesQueue: ObjectQueue<
|
|
27
|
+
messagesQueue: ObjectQueue<TMessage>;
|
|
15
28
|
/**
|
|
16
29
|
* Whether the resource type is currently draining its message queue.
|
|
17
30
|
*/
|
|
@@ -75,10 +88,18 @@ export interface RealTimeProducerStoreStateWithActions extends RealTimeProducerS
|
|
|
75
88
|
* Update the producer connection state.
|
|
76
89
|
*/
|
|
77
90
|
setStatus: (newState: RealTimeStatus) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Read the current resource-type hash without cloning it.
|
|
93
|
+
*/
|
|
94
|
+
getResourceTypeSnapshot: (resourceTypeId: RealTimeResourceTypeId) => RealTimeReadonlyResourceHash;
|
|
78
95
|
/**
|
|
79
96
|
* Subscribe a client to realtime updates and return the current producer hash through callbacks.
|
|
80
97
|
*/
|
|
81
98
|
subscribe: (resourceTypeId: RealTimeResourceTypeId, options: SubscribeOptions) => void;
|
|
99
|
+
/**
|
|
100
|
+
* Subscribe a client to realtime updates and return the current producer hash by reference.
|
|
101
|
+
*/
|
|
102
|
+
subscribeResourceType: (resourceTypeId: RealTimeResourceTypeId, options: SubscribeResourceTypeOptions) => RealTimeReadonlyResourceHash;
|
|
82
103
|
/**
|
|
83
104
|
* Unsubscribe a client from realtime updates.
|
|
84
105
|
*/
|
|
@@ -87,6 +108,10 @@ export interface RealTimeProducerStoreStateWithActions extends RealTimeProducerS
|
|
|
87
108
|
* Accept a raw incoming batch and enqueue it for producer-side processing.
|
|
88
109
|
*/
|
|
89
110
|
onMessages: OnMessagesStoreCallback;
|
|
111
|
+
/**
|
|
112
|
+
* Accept one batch with explicit ingress metadata before it reaches the producer queue.
|
|
113
|
+
*/
|
|
114
|
+
ingestMessages: (resourceTypeId: RealTimeResourceTypeId, messages: RealTimeMessage[], reason: RealTimeMessageIngressReason) => void;
|
|
90
115
|
/**
|
|
91
116
|
* Drain the queued messages for one resource type in arrival order.
|
|
92
117
|
*/
|
|
@@ -106,6 +131,10 @@ export type InitialRealTimeProducerStoreProps = Omit<RealTimeProducerStoreState,
|
|
|
106
131
|
*/
|
|
107
132
|
export interface CreateRealTimeStoreProps extends InitialRealTimeProducerStoreProps {
|
|
108
133
|
onPerformanceMetric?: OnRealTimeProducerMetricCallback;
|
|
134
|
+
/**
|
|
135
|
+
* Whether resource source mechanisms should start during store initialization.
|
|
136
|
+
*/
|
|
137
|
+
startSourceData?: boolean;
|
|
109
138
|
}
|
|
110
139
|
/**
|
|
111
140
|
* Input contract used to build one store-backed runtime bundle outside React ownership.
|
package/web/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/realtime-runtime/src/web/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EACV,uBAAuB,EACvB,gCAAgC,EAChC,eAAe,EACf,oBAAoB,EACpB,qCAAqC,EACrC,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/realtime-runtime/src/web/types.ts"],"names":[],"mappings":"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"}
|
package/web.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { REALTIME_PRODUCER_STORE_ID, createGetOrCreateRealtimeRuntime, createRealTimeProducerTools, createRealtimeRuntime, createRealtimeRuntimeBundle, createRealTimeStore, disposeRealtimeRuntime, } from './web/index';
|
|
2
|
-
export type { CreateRealTimeSourceData, CreateRealTimeStoreProps, CreateRealtimeRuntimeProps, GetOrCreateRealtimeRuntimeProps, InitialRealTimeProducerStoreProps, MessageQueueManager, RealtimeRuntimeBundle, RealTimeProducerStoreResourceType, RealTimeProducerStoreState, RealTimeProducerStoreStateWithActions, RealTimeProducerTools, RealTimeStoreType, } from './web/index';
|
|
2
|
+
export type { CreateRealTimeSourceData, CreateRealTimeStoreProps, CreateRealtimeRuntimeProps, GetOrCreateRealtimeRuntimeProps, InitialRealTimeProducerStoreProps, MessageQueueManager, RealtimeRuntimeBundle, RealTimeProducerStoreResourceType, RealTimeProducerStoreState, RealTimeProducerStoreStateWithActions, RealTimeProducerTools, RealTimeReadonlyResourceHash, RealTimeStoreType, SubscribeResourceTypeOptions, } from './web/index';
|
|
3
3
|
//# sourceMappingURL=web.d.ts.map
|
package/web.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../../packages/realtime-runtime/src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,2BAA2B,EAC3B,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,iCAAiC,EACjC,mBAAmB,EACnB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,qCAAqC,EACrC,qBAAqB,EACrB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../../packages/realtime-runtime/src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,2BAA2B,EAC3B,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,iCAAiC,EACjC,mBAAmB,EACnB,qBAAqB,EACrB,iCAAiC,EACjC,0BAA0B,EAC1B,qCAAqC,EACrC,qBAAqB,EACrB,4BAA4B,EAC5B,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,aAAa,CAAC"}
|