lemon-model 1.2.2 → 1.2.4

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.
Files changed (141) hide show
  1. package/dist/esm/index.js +3 -0
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/logtrace/index.js +11 -0
  4. package/dist/esm/logtrace/index.js.map +1 -0
  5. package/dist/esm/logtrace/logtrace.js +251 -0
  6. package/dist/esm/logtrace/logtrace.js.map +1 -0
  7. package/dist/esm/logtrace/testing.js +77 -0
  8. package/dist/esm/logtrace/testing.js.map +1 -0
  9. package/dist/esm/progress/index.js +9 -0
  10. package/dist/esm/progress/index.js.map +1 -0
  11. package/dist/esm/progress/progress.js +256 -0
  12. package/dist/esm/progress/progress.js.map +1 -0
  13. package/dist/esm/progress/testing.js +98 -0
  14. package/dist/esm/progress/testing.js.map +1 -0
  15. package/dist/esm/socket/decorators.js +266 -0
  16. package/dist/esm/socket/decorators.js.map +1 -0
  17. package/dist/esm/socket/index.js +2 -0
  18. package/dist/esm/socket/index.js.map +1 -1
  19. package/dist/esm/socket/multi.js +94 -0
  20. package/dist/esm/socket/multi.js.map +1 -0
  21. package/dist/esm/socket/socket.js +82 -22
  22. package/dist/esm/socket/socket.js.map +1 -1
  23. package/dist/esm/socket/transport.js +385 -3
  24. package/dist/esm/socket/transport.js.map +1 -1
  25. package/dist/esm/socket/websocket.js +18 -4
  26. package/dist/esm/socket/websocket.js.map +1 -1
  27. package/dist/esm/sync/client.js +166 -0
  28. package/dist/esm/sync/client.js.map +1 -0
  29. package/dist/esm/sync/index.js +14 -0
  30. package/dist/esm/sync/index.js.map +1 -0
  31. package/dist/esm/sync/machine.js +181 -0
  32. package/dist/esm/sync/machine.js.map +1 -0
  33. package/dist/esm/sync/network.js +273 -0
  34. package/dist/esm/sync/network.js.map +1 -0
  35. package/dist/esm/sync/testing.js +44 -0
  36. package/dist/esm/sync/testing.js.map +1 -0
  37. package/dist/esm/sync/ticker.js +53 -0
  38. package/dist/esm/sync/ticker.js.map +1 -0
  39. package/dist/esm/sync/types.js +2 -0
  40. package/dist/{proxy → esm/sync}/types.js.map +1 -1
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.js +3 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/logtrace/index.d.ts +7 -0
  45. package/dist/logtrace/index.js +27 -0
  46. package/dist/logtrace/index.js.map +1 -0
  47. package/dist/logtrace/logtrace.d.ts +99 -0
  48. package/dist/logtrace/logtrace.js +256 -0
  49. package/dist/logtrace/logtrace.js.map +1 -0
  50. package/dist/logtrace/testing.d.ts +40 -0
  51. package/dist/logtrace/testing.js +81 -0
  52. package/dist/logtrace/testing.js.map +1 -0
  53. package/dist/progress/index.d.ts +8 -0
  54. package/dist/{proxy → progress}/index.js +5 -9
  55. package/dist/progress/index.js.map +1 -0
  56. package/dist/progress/progress.d.ts +112 -0
  57. package/dist/progress/progress.js +263 -0
  58. package/dist/progress/progress.js.map +1 -0
  59. package/dist/progress/testing.d.ts +33 -0
  60. package/dist/progress/testing.js +102 -0
  61. package/dist/progress/testing.js.map +1 -0
  62. package/dist/socket/client/index.d.ts +9 -0
  63. package/dist/socket/client/index.js +26 -0
  64. package/dist/socket/client/index.js.map +1 -0
  65. package/dist/socket/client/keep-alive-controller.d.ts +35 -0
  66. package/dist/socket/client/keep-alive-controller.js +101 -0
  67. package/dist/socket/client/keep-alive-controller.js.map +1 -0
  68. package/dist/socket/client/message-router.d.ts +15 -0
  69. package/dist/socket/client/message-router.js +52 -0
  70. package/dist/socket/client/message-router.js.map +1 -0
  71. package/dist/socket/client/pending-request-store.d.ts +24 -0
  72. package/dist/socket/client/pending-request-store.js +78 -0
  73. package/dist/socket/client/pending-request-store.js.map +1 -0
  74. package/dist/socket/client/reconnect-controller.d.ts +56 -0
  75. package/dist/socket/client/reconnect-controller.js +177 -0
  76. package/dist/socket/client/reconnect-controller.js.map +1 -0
  77. package/dist/socket/client/rotation-controller.d.ts +32 -0
  78. package/dist/socket/client/rotation-controller.js +76 -0
  79. package/dist/socket/client/rotation-controller.js.map +1 -0
  80. package/dist/socket/client/shared-timer-scheduler.d.ts +17 -0
  81. package/dist/socket/client/shared-timer-scheduler.js +77 -0
  82. package/dist/socket/client/shared-timer-scheduler.js.map +1 -0
  83. package/dist/socket/client/socket-client.d.ts +2 -0
  84. package/dist/socket/client/socket-client.js +219 -0
  85. package/dist/socket/client/socket-client.js.map +1 -0
  86. package/dist/socket/client/types.d.ts +101 -0
  87. package/dist/socket/client/types.js +3 -0
  88. package/dist/socket/client/types.js.map +1 -0
  89. package/dist/socket/client/websocket-client-transport.d.ts +23 -0
  90. package/dist/socket/client/websocket-client-transport.js +152 -0
  91. package/dist/socket/client/websocket-client-transport.js.map +1 -0
  92. package/dist/socket/decorators.d.ts +38 -0
  93. package/dist/socket/decorators.js +271 -0
  94. package/dist/socket/decorators.js.map +1 -0
  95. package/dist/socket/index.d.ts +2 -0
  96. package/dist/socket/index.js +2 -0
  97. package/dist/socket/index.js.map +1 -1
  98. package/dist/socket/multi.d.ts +33 -0
  99. package/dist/socket/multi.js +98 -0
  100. package/dist/socket/multi.js.map +1 -0
  101. package/dist/socket/socket.d.ts +22 -4
  102. package/dist/socket/socket.js +82 -22
  103. package/dist/socket/socket.js.map +1 -1
  104. package/dist/socket/transport.d.ts +124 -6
  105. package/dist/socket/transport.js +389 -4
  106. package/dist/socket/transport.js.map +1 -1
  107. package/dist/socket/websocket.d.ts +14 -0
  108. package/dist/socket/websocket.js +19 -5
  109. package/dist/socket/websocket.js.map +1 -1
  110. package/dist/sync/client.d.ts +16 -0
  111. package/dist/sync/client.js +171 -0
  112. package/dist/sync/client.js.map +1 -0
  113. package/dist/sync/index.d.ts +10 -0
  114. package/dist/sync/index.js +30 -0
  115. package/dist/sync/index.js.map +1 -0
  116. package/dist/sync/machine.d.ts +3 -0
  117. package/dist/sync/machine.js +185 -0
  118. package/dist/sync/machine.js.map +1 -0
  119. package/dist/sync/network.d.ts +38 -0
  120. package/dist/sync/network.js +278 -0
  121. package/dist/sync/network.js.map +1 -0
  122. package/dist/sync/testing.d.ts +38 -0
  123. package/dist/sync/testing.js +48 -0
  124. package/dist/sync/testing.js.map +1 -0
  125. package/dist/sync/ticker.d.ts +21 -0
  126. package/dist/sync/ticker.js +57 -0
  127. package/dist/sync/ticker.js.map +1 -0
  128. package/dist/sync/types.d.ts +115 -0
  129. package/dist/sync/types.js +3 -0
  130. package/dist/sync/types.js.map +1 -0
  131. package/package.json +13 -1
  132. package/dist/proxy/index.d.ts +0 -12
  133. package/dist/proxy/index.js.map +0 -1
  134. package/dist/proxy/proxy.d.ts +0 -75
  135. package/dist/proxy/proxy.js +0 -198
  136. package/dist/proxy/proxy.js.map +0 -1
  137. package/dist/proxy/transport.d.ts +0 -123
  138. package/dist/proxy/transport.js +0 -401
  139. package/dist/proxy/transport.js.map +0 -1
  140. package/dist/proxy/types.d.ts +0 -89
  141. package/dist/proxy/types.js +0 -12
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.createProgressConsumer = exports.createProgressReporter = exports.createBufferProgressGauge = exports.createTimeProgressGauge = exports.DEFAULT_MAX_PACKET_BYTES = void 0;
15
+ const websocket_1 = require("../socket/websocket");
16
+ /** default serialized packet size limit (same family as `src/socket`) */
17
+ exports.DEFAULT_MAX_PACKET_BYTES = 64 * 1024;
18
+ /** time-flow gauge - elapsed ratio against expectedMs, capped at 99% (only done() declares completion) */
19
+ const createTimeProgressGauge = (expectedMs, now = Date.now) => {
20
+ const startedAt = now();
21
+ return () => {
22
+ if (!(expectedMs > 0))
23
+ return { percent: 99 };
24
+ const percent = Math.floor(((now() - startedAt) / expectedMs) * 100);
25
+ return { percent: Math.min(99, Math.max(0, percent)) };
26
+ };
27
+ };
28
+ exports.createTimeProgressGauge = createTimeProgressGauge;
29
+ /** buffer-fill gauge - reads percent/bufferPercent from a GenAIStreamProgress-compatible source (structural type, no src/buffer dependency) */
30
+ const createBufferProgressGauge = (source) => {
31
+ return () => {
32
+ var _a;
33
+ const snapshot = source();
34
+ const percent = (_a = snapshot === null || snapshot === void 0 ? void 0 : snapshot.percent) !== null && _a !== void 0 ? _a : snapshot === null || snapshot === void 0 ? void 0 : snapshot.bufferPercent;
35
+ return percent === undefined ? {} : { percent };
36
+ };
37
+ };
38
+ exports.createBufferProgressGauge = createBufferProgressGauge;
39
+ const GAUGE_KEYS = ['percent', 'step', 'totalSteps', 'label'];
40
+ const textEncoder = new TextEncoder();
41
+ const byteLength = (value) => textEncoder.encode(value).length;
42
+ /** assign only defined values so a partial patch never erases fields */
43
+ const assignDefined = (target, patch) => {
44
+ if (!patch)
45
+ return;
46
+ for (const key of Object.keys(patch)) {
47
+ if (patch[key] !== undefined)
48
+ target[key] = patch[key];
49
+ }
50
+ };
51
+ /** create a server-side progress reporter over an injected sink */
52
+ const createProgressReporter = (sink, options) => {
53
+ var _a, _b, _c, _d;
54
+ const type = (_a = options === null || options === void 0 ? void 0 : options.type) !== null && _a !== void 0 ? _a : 'progress:update';
55
+ const throttleMs = (_b = options === null || options === void 0 ? void 0 : options.throttleMs) !== null && _b !== void 0 ? _b : 0;
56
+ const heartbeatMs = (_c = options === null || options === void 0 ? void 0 : options.heartbeatMs) !== null && _c !== void 0 ? _c : 0;
57
+ const maxPacketBytes = (_d = options === null || options === void 0 ? void 0 : options.maxPacketBytes) !== null && _d !== void 0 ? _d : exports.DEFAULT_MAX_PACKET_BYTES;
58
+ const tasks = new Map();
59
+ let seq = 0;
60
+ let mid = 0;
61
+ const notifyError = (error, state) => { var _a; return (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error, state); };
62
+ /** the reporter never interrupts task code: sink throw/reject only reaches onError */
63
+ const dispatch = (message) => {
64
+ try {
65
+ const result = sink(message);
66
+ if (result && typeof result.then === 'function') {
67
+ result.then(undefined, error => notifyError(error, message.data));
68
+ }
69
+ }
70
+ catch (error) {
71
+ notifyError(error, message.data);
72
+ }
73
+ };
74
+ const emit = (task) => {
75
+ task.dirty = false;
76
+ const snapshot = Object.assign(Object.assign({}, task.local), { ts: Date.now(), seq: ++seq });
77
+ if (task.gauge) {
78
+ try {
79
+ const measure = task.gauge();
80
+ for (const key of GAUGE_KEYS) {
81
+ if (snapshot[key] === undefined && measure[key] !== undefined)
82
+ snapshot[key] = measure[key];
83
+ }
84
+ }
85
+ catch (error) {
86
+ notifyError(error, snapshot);
87
+ }
88
+ }
89
+ let message = { type, data: snapshot, mid: `p${++mid}` };
90
+ if (snapshot.meta !== undefined && byteLength(JSON.stringify(message)) > maxPacketBytes) {
91
+ const { meta: _meta } = snapshot, stripped = __rest(snapshot, ["meta"]);
92
+ message = Object.assign(Object.assign({}, message), { data: stripped });
93
+ notifyError(new Error(`progress packet exceeds maxPacketBytes:${maxPacketBytes}`), snapshot);
94
+ }
95
+ task.last = message.data;
96
+ dispatch(message);
97
+ };
98
+ /** trailing edge: emit the latest snapshot once per window while updates keep arriving */
99
+ const openWindow = (task) => {
100
+ task.timer = setTimeout(() => {
101
+ task.timer = undefined;
102
+ if (!task.dirty || task.closed)
103
+ return;
104
+ emit(task);
105
+ openWindow(task);
106
+ }, throttleMs);
107
+ };
108
+ const cancelWindow = (task) => {
109
+ if (!task.timer)
110
+ return;
111
+ clearTimeout(task.timer);
112
+ task.timer = undefined;
113
+ };
114
+ const finish = (task, status, patch) => {
115
+ if (task.closed)
116
+ return;
117
+ task.closed = true;
118
+ cancelWindow(task);
119
+ assignDefined(task.local, patch);
120
+ task.local.status = status;
121
+ emit(task);
122
+ };
123
+ const heartbeatTimer = heartbeatMs > 0
124
+ ? setInterval(() => {
125
+ tasks.forEach(task => {
126
+ if (!task.closed && task.local.status === 'running')
127
+ emit(task);
128
+ });
129
+ }, heartbeatMs)
130
+ : undefined;
131
+ return {
132
+ start: (id, initial, taskOptions) => {
133
+ const existing = tasks.get(id);
134
+ if (existing)
135
+ return existing.handle;
136
+ const local = { id, status: 'pending', ts: 0, seq: 0 };
137
+ assignDefined(local, initial);
138
+ const task = {
139
+ local,
140
+ last: local,
141
+ gauge: taskOptions === null || taskOptions === void 0 ? void 0 : taskOptions.gauge,
142
+ dirty: false,
143
+ closed: false,
144
+ handle: {
145
+ id,
146
+ get state() {
147
+ return task.last;
148
+ },
149
+ update: patch => {
150
+ if (task.closed)
151
+ return;
152
+ const _a = patch !== null && patch !== void 0 ? patch : {}, { status } = _a, rest = __rest(_a, ["status"]);
153
+ if (status && !(status === 'pending' && task.local.status === 'running')) {
154
+ task.local.status = status;
155
+ }
156
+ assignDefined(task.local, rest);
157
+ if (throttleMs <= 0)
158
+ return emit(task);
159
+ if (task.timer) {
160
+ task.dirty = true;
161
+ return;
162
+ }
163
+ emit(task);
164
+ openWindow(task);
165
+ },
166
+ done: patch => finish(task, 'done', patch),
167
+ error: (error, patch) => {
168
+ var _a;
169
+ task.local.error = typeof error === 'string' ? error : `${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`;
170
+ finish(task, 'error', patch);
171
+ },
172
+ },
173
+ };
174
+ tasks.set(id, task);
175
+ emit(task);
176
+ return task.handle;
177
+ },
178
+ close: () => {
179
+ if (heartbeatTimer)
180
+ clearInterval(heartbeatTimer);
181
+ tasks.forEach(task => {
182
+ cancelWindow(task);
183
+ if (task.dirty && !task.closed)
184
+ emit(task);
185
+ });
186
+ },
187
+ };
188
+ };
189
+ exports.createProgressReporter = createProgressReporter;
190
+ /** create a client-side progress consumer on a shared network */
191
+ const createProgressConsumer = (network, options) => {
192
+ var _a, _b;
193
+ const typePrefix = (_a = options === null || options === void 0 ? void 0 : options.typePrefix) !== null && _a !== void 0 ? _a : 'progress:';
194
+ const maxTasks = Math.max(1, (_b = options === null || options === void 0 ? void 0 : options.maxTasks) !== null && _b !== void 0 ? _b : 100);
195
+ const rawKey = `"type":"${typePrefix}`;
196
+ /** two-stage filter: raw substring check (no parse) then parsed type re-check */
197
+ const filtered = (0, websocket_1.createFilteredNetwork)(network, raw => raw.includes(rawKey));
198
+ const store = new Map();
199
+ const handlers = new Set();
200
+ const evict = (keepId) => {
201
+ if (store.size <= maxTasks)
202
+ return;
203
+ let evictId;
204
+ for (const [id, state] of store) {
205
+ if (id !== keepId && (state.status === 'done' || state.status === 'error')) {
206
+ evictId = id;
207
+ break;
208
+ }
209
+ }
210
+ if (evictId === undefined) {
211
+ for (const id of store.keys()) {
212
+ if (id !== keepId) {
213
+ evictId = id;
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ if (evictId !== undefined)
219
+ store.delete(evictId);
220
+ };
221
+ const unsubscribe = filtered.onMessage(raw => {
222
+ let message;
223
+ try {
224
+ message = JSON.parse(raw);
225
+ }
226
+ catch (_a) {
227
+ return;
228
+ }
229
+ if (typeof (message === null || message === void 0 ? void 0 : message.type) !== 'string' || !message.type.startsWith(typePrefix))
230
+ return;
231
+ const state = message.data;
232
+ if (!state || typeof state.id !== 'string' || typeof state.seq !== 'number')
233
+ return;
234
+ const existing = store.get(state.id);
235
+ if (existing && state.seq <= existing.seq)
236
+ return;
237
+ store.set(state.id, state);
238
+ if (!existing)
239
+ evict(state.id);
240
+ for (const handler of [...handlers]) {
241
+ try {
242
+ handler({ state, created: !existing });
243
+ }
244
+ catch (_b) {
245
+ // a subscriber error must not break other subscribers or the shared network
246
+ }
247
+ }
248
+ });
249
+ return {
250
+ get: id => store.get(id),
251
+ list: () => [...store.values()],
252
+ onChange: handler => {
253
+ handlers.add(handler);
254
+ return () => handlers.delete(handler);
255
+ },
256
+ close: () => {
257
+ unsubscribe();
258
+ handlers.clear();
259
+ },
260
+ };
261
+ };
262
+ exports.createProgressConsumer = createProgressConsumer;
263
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/progress/progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { SocketNetworkOptions } from '../socket/types';
2
+ import { ProgressConsumerOptions, ProgressReporterOptions, ProgressState } from './progress';
3
+ export interface ProgressLoopOptions {
4
+ /** update patch sequence to replay (start -> patches -> done/error). patch.id selects the task (default 'task') */
5
+ script: Array<Partial<ProgressState>>;
6
+ reporterOptions?: ProgressReporterOptions;
7
+ consumerOptions?: ProgressConsumerOptions;
8
+ /** in-memory network conditions (unordered, jitterMs, maxPacketBytes, ...) */
9
+ networkOptions?: SocketNetworkOptions & {
10
+ id?: string;
11
+ };
12
+ /** wait time for async packet delivery */
13
+ settleMs?: number;
14
+ }
15
+ export interface ProgressLoopMetrics {
16
+ elapsedMs: number;
17
+ /** raw packet count / total bytes / largest packet bytes (throttle / packet-limit checks) */
18
+ packets: number;
19
+ packetBytes: number;
20
+ maxPacketBytes: number;
21
+ /** snapshots emitted by the reporter (throttle suppression check) */
22
+ emitted: number;
23
+ /** applied by the consumer / dropped by seq judgement */
24
+ applied: number;
25
+ staleDropped: number;
26
+ /** final consumer states at loop end */
27
+ finalStates: ProgressState[];
28
+ }
29
+ /**
30
+ * Run an end-to-end loop: script -> ProgressReporter -> NetworkSupportable -> ProgressConsumer,
31
+ * and return numeric metrics for assertion (same pattern as `buffer/testing.runGenAIStreamNetworkLoop`).
32
+ */
33
+ export declare const runProgressLoop: (options: ProgressLoopOptions) => Promise<ProgressLoopMetrics>;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.runProgressLoop = void 0;
24
+ /**
25
+ * `progress/testing.ts`
26
+ * - isolated entry for the progress end-to-end loop harness.
27
+ * - kept OUT of the package root barrel so production bundles do not include the in-memory socket simulator.
28
+ *
29
+ * Usage (tests / dev only):
30
+ * import { runProgressLoop } from 'lemon-model/progress/testing';
31
+ *
32
+ * @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
33
+ */
34
+ const socket_1 = require("../socket/socket");
35
+ const progress_1 = require("./progress");
36
+ /**
37
+ * Run an end-to-end loop: script -> ProgressReporter -> NetworkSupportable -> ProgressConsumer,
38
+ * and return numeric metrics for assertion (same pattern as `buffer/testing.runGenAIStreamNetworkLoop`).
39
+ */
40
+ const runProgressLoop = (options) => __awaiter(void 0, void 0, void 0, function* () {
41
+ var _a, _b;
42
+ const startedAt = Date.now();
43
+ const network = (0, socket_1.createNetwork)(Object.assign({}, options.networkOptions));
44
+ const typePrefix = (_b = (_a = options.consumerOptions) === null || _a === void 0 ? void 0 : _a.typePrefix) !== null && _b !== void 0 ? _b : 'progress:';
45
+ // Keep wire packets so specs can compare emitted, applied, and stale counts.
46
+ const rawPackets = [];
47
+ const unsubscribeRaw = network.onMessage(raw => rawPackets.push(raw));
48
+ const consumer = (0, progress_1.createProgressConsumer)(network, options.consumerOptions);
49
+ let applied = 0;
50
+ const unsubscribeChange = consumer.onChange(() => (applied += 1));
51
+ let emitted = 0;
52
+ const reporter = (0, progress_1.createProgressReporter)(message => {
53
+ emitted += 1;
54
+ network.send(JSON.stringify(message));
55
+ }, options.reporterOptions);
56
+ try {
57
+ const tasks = new Map();
58
+ // Reuse task handles by id so each script patch models a real task update.
59
+ const taskOf = (id) => {
60
+ const existing = tasks.get(id);
61
+ if (existing)
62
+ return existing;
63
+ const started = reporter.start(id);
64
+ tasks.set(id, started);
65
+ return started;
66
+ };
67
+ for (const patch of options.script) {
68
+ const { id, ts: _ts, seq: _seq, status, error } = patch, rest = __rest(patch, ["id", "ts", "seq", "status", "error"]);
69
+ const task = taskOf(id !== null && id !== void 0 ? id : 'task');
70
+ if (status === 'done')
71
+ task.done(rest);
72
+ else if (status === 'error')
73
+ task.error(error !== null && error !== void 0 ? error : 'error', rest);
74
+ else
75
+ task.update(Object.assign(Object.assign({}, rest), { error, status }));
76
+ }
77
+ reporter.close();
78
+ yield new Promise(resolve => { var _a; return setTimeout(resolve, (_a = options.settleMs) !== null && _a !== void 0 ? _a : 50); });
79
+ // Only matching progress envelopes can become stale drops on a shared network.
80
+ const arrived = rawPackets.filter(raw => raw.includes(`"type":"${typePrefix}`)).length;
81
+ return {
82
+ elapsedMs: Date.now() - startedAt,
83
+ packets: rawPackets.length,
84
+ packetBytes: rawPackets.reduce((sum, raw) => sum + byteLength(raw), 0),
85
+ maxPacketBytes: rawPackets.reduce((max, raw) => Math.max(max, byteLength(raw)), 0),
86
+ emitted,
87
+ applied,
88
+ staleDropped: arrived - applied,
89
+ finalStates: consumer.list(),
90
+ };
91
+ }
92
+ finally {
93
+ unsubscribeRaw();
94
+ unsubscribeChange();
95
+ consumer.close();
96
+ network.close();
97
+ }
98
+ });
99
+ exports.runProgressLoop = runProgressLoop;
100
+ const textEncoder = new TextEncoder();
101
+ const byteLength = (value) => textEncoder.encode(value).length;
102
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/progress/testing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export * from './types';
2
+ export * from './shared-timer-scheduler';
3
+ export * from './message-router';
4
+ export * from './pending-request-store';
5
+ export * from './socket-client';
6
+ export * from './websocket-client-transport';
7
+ export * from './keep-alive-controller';
8
+ export * from './reconnect-controller';
9
+ export * from './rotation-controller';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./shared-timer-scheduler"), exports);
19
+ __exportStar(require("./message-router"), exports);
20
+ __exportStar(require("./pending-request-store"), exports);
21
+ __exportStar(require("./socket-client"), exports);
22
+ __exportStar(require("./websocket-client-transport"), exports);
23
+ __exportStar(require("./keep-alive-controller"), exports);
24
+ __exportStar(require("./reconnect-controller"), exports);
25
+ __exportStar(require("./rotation-controller"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/socket/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2DAAyC;AACzC,mDAAiC;AACjC,0DAAwC;AACxC,kDAAgC;AAChC,+DAA6C;AAC7C,0DAAwC;AACxC,yDAAuC;AACvC,wDAAsC"}
@@ -0,0 +1,35 @@
1
+ import type { SharedTimerScheduler, SocketRuntimePort } from './types';
2
+ export interface KeepAliveControllerOptions<TMessage> {
3
+ client: SocketRuntimePort<TMessage>;
4
+ buildMessage: () => TMessage;
5
+ intervalMs?: number;
6
+ timeoutMs?: number;
7
+ maxMissedPongs?: number;
8
+ mode?: 'send' | 'request';
9
+ timerScheduler?: SharedTimerScheduler;
10
+ timerKey?: string;
11
+ onPongTimeout?: () => unknown | Promise<unknown>;
12
+ }
13
+ export declare class KeepAliveController<TMessage> {
14
+ private readonly client;
15
+ private readonly buildMessage;
16
+ private readonly intervalMs;
17
+ private readonly timeoutMs;
18
+ private readonly maxMissedPongs;
19
+ private readonly mode;
20
+ private readonly timerScheduler;
21
+ private readonly timerKey;
22
+ private readonly onPongTimeout;
23
+ private readonly unsubs;
24
+ private running;
25
+ private inFlight;
26
+ private missedPongs;
27
+ constructor(options: KeepAliveControllerOptions<TMessage>);
28
+ start(): void;
29
+ stop(): void;
30
+ destroy(): void;
31
+ private scheduleNow;
32
+ private scheduleNext;
33
+ private clearTimer;
34
+ private tick;
35
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.KeepAliveController = void 0;
13
+ const shared_timer_scheduler_1 = require("./shared-timer-scheduler");
14
+ class KeepAliveController {
15
+ constructor(options) {
16
+ var _a, _b, _c, _d, _e, _f;
17
+ this.unsubs = [];
18
+ this.running = false;
19
+ this.inFlight = false;
20
+ this.missedPongs = 0;
21
+ this.client = options.client;
22
+ this.buildMessage = options.buildMessage;
23
+ this.intervalMs = (_a = options.intervalMs) !== null && _a !== void 0 ? _a : 30000;
24
+ this.timeoutMs = (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 10000;
25
+ this.maxMissedPongs = Math.max(1, (_c = options.maxMissedPongs) !== null && _c !== void 0 ? _c : 2);
26
+ this.mode = (_d = options.mode) !== null && _d !== void 0 ? _d : 'request';
27
+ this.timerScheduler = (_e = options.timerScheduler) !== null && _e !== void 0 ? _e : new shared_timer_scheduler_1.InMemorySharedTimerScheduler();
28
+ this.timerKey = (_f = options.timerKey) !== null && _f !== void 0 ? _f : 'keepalive';
29
+ this.onPongTimeout = options.onPongTimeout;
30
+ this.unsubs.push(options.client.onState(event => {
31
+ if (event.next === 'connected' && this.running) {
32
+ this.missedPongs = 0;
33
+ this.scheduleNow();
34
+ }
35
+ if (event.next === 'closing' || event.next === 'closed') {
36
+ this.missedPongs = 0;
37
+ this.clearTimer();
38
+ }
39
+ }));
40
+ }
41
+ start() {
42
+ this.running = true;
43
+ if (this.client.state === 'connected')
44
+ this.scheduleNow();
45
+ }
46
+ stop() {
47
+ this.running = false;
48
+ this.clearTimer();
49
+ }
50
+ destroy() {
51
+ this.stop();
52
+ this.unsubs.splice(0).forEach(unsub => unsub());
53
+ }
54
+ scheduleNow() {
55
+ this.clearTimer();
56
+ this.timerScheduler.schedule(this.timerKey, 0, () => this.tick());
57
+ }
58
+ scheduleNext() {
59
+ this.clearTimer();
60
+ if (!this.running || this.client.state !== 'connected')
61
+ return;
62
+ this.timerScheduler.schedule(this.timerKey, this.intervalMs, () => this.tick());
63
+ }
64
+ clearTimer() {
65
+ this.timerScheduler.cancel(this.timerKey);
66
+ }
67
+ tick() {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ if (!this.running || this.client.state !== 'connected' || this.inFlight)
70
+ return;
71
+ this.inFlight = true;
72
+ try {
73
+ const message = this.buildMessage();
74
+ if (this.mode === 'send') {
75
+ this.client.send(message);
76
+ return;
77
+ }
78
+ yield this.client.request(message, { timeoutMs: this.timeoutMs });
79
+ this.missedPongs = 0;
80
+ }
81
+ catch (_a) {
82
+ if (this.mode === 'request') {
83
+ this.missedPongs += 1;
84
+ if (this.missedPongs >= this.maxMissedPongs) {
85
+ this.missedPongs = 0;
86
+ if (this.onPongTimeout)
87
+ yield Promise.resolve(this.onPongTimeout()).catch(() => undefined);
88
+ else
89
+ yield this.client.disconnect(1001, 'pong-timeout').catch(() => undefined);
90
+ }
91
+ }
92
+ }
93
+ finally {
94
+ this.inFlight = false;
95
+ this.scheduleNext();
96
+ }
97
+ });
98
+ }
99
+ }
100
+ exports.KeepAliveController = KeepAliveController;
101
+ //# sourceMappingURL=keep-alive-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-alive-controller.js","sourceRoot":"","sources":["../../../src/socket/client/keep-alive-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { SocketUnsubscribe } from '../types';
2
+ export declare type MessageListener<TMessage = unknown> = (message: TMessage) => void;
3
+ export interface MessageRouterOptions<TMessage> {
4
+ getMessageType?: (message: TMessage) => string | undefined;
5
+ }
6
+ export declare class MessageRouter<TMessage = any> {
7
+ private readonly anyListeners;
8
+ private readonly typeListeners;
9
+ private readonly getMessageType;
10
+ constructor(options?: MessageRouterOptions<TMessage>);
11
+ onAny(listener: MessageListener<TMessage>): SocketUnsubscribe;
12
+ onType(type: string, listener: MessageListener<TMessage>): SocketUnsubscribe;
13
+ clear(): void;
14
+ route(message: TMessage): number;
15
+ }