lemon-model 1.2.3 → 1.4.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.
Files changed (141) hide show
  1. package/dist/esm/index.js +1 -0
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/socket/decorators.js +266 -0
  4. package/dist/esm/socket/decorators.js.map +1 -0
  5. package/dist/esm/socket/index.js +2 -0
  6. package/dist/esm/socket/index.js.map +1 -1
  7. package/dist/esm/socket/multi.js +94 -0
  8. package/dist/esm/socket/multi.js.map +1 -0
  9. package/dist/esm/socket/socket.js +82 -22
  10. package/dist/esm/socket/socket.js.map +1 -1
  11. package/dist/esm/socket/transport.js +385 -3
  12. package/dist/esm/socket/transport.js.map +1 -1
  13. package/dist/esm/sync/client.js +166 -0
  14. package/dist/esm/sync/client.js.map +1 -0
  15. package/dist/esm/sync/index.js +14 -0
  16. package/dist/esm/sync/index.js.map +1 -0
  17. package/dist/esm/sync/machine.js +181 -0
  18. package/dist/esm/sync/machine.js.map +1 -0
  19. package/dist/esm/sync/network.js +273 -0
  20. package/dist/esm/sync/network.js.map +1 -0
  21. package/dist/esm/sync/testing.js +44 -0
  22. package/dist/esm/sync/testing.js.map +1 -0
  23. package/dist/esm/sync/ticker.js +53 -0
  24. package/dist/esm/sync/ticker.js.map +1 -0
  25. package/dist/esm/sync/types.js +2 -0
  26. package/dist/{proxy → esm/sync}/types.js.map +1 -1
  27. package/dist/esm/upload/engine/engine.js +166 -0
  28. package/dist/esm/upload/engine/engine.js.map +1 -0
  29. package/dist/esm/upload/engine/executors.js +57 -0
  30. package/dist/esm/upload/engine/executors.js.map +1 -0
  31. package/dist/esm/upload/engine/index.js +13 -0
  32. package/dist/esm/upload/engine/index.js.map +1 -0
  33. package/dist/esm/upload/engine/progress.js +52 -0
  34. package/dist/esm/upload/engine/progress.js.map +1 -0
  35. package/dist/esm/upload/index.js +11 -0
  36. package/dist/esm/upload/index.js.map +1 -0
  37. package/dist/esm/upload/testing.js +73 -0
  38. package/dist/esm/upload/testing.js.map +1 -0
  39. package/dist/esm/upload/types.js +69 -0
  40. package/dist/esm/upload/types.js.map +1 -0
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.js +1 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/socket/client/index.d.ts +9 -0
  45. package/dist/socket/client/index.js +26 -0
  46. package/dist/socket/client/index.js.map +1 -0
  47. package/dist/socket/client/keep-alive-controller.d.ts +35 -0
  48. package/dist/socket/client/keep-alive-controller.js +101 -0
  49. package/dist/socket/client/keep-alive-controller.js.map +1 -0
  50. package/dist/socket/client/message-router.d.ts +15 -0
  51. package/dist/socket/client/message-router.js +52 -0
  52. package/dist/socket/client/message-router.js.map +1 -0
  53. package/dist/socket/client/pending-request-store.d.ts +24 -0
  54. package/dist/socket/client/pending-request-store.js +78 -0
  55. package/dist/socket/client/pending-request-store.js.map +1 -0
  56. package/dist/socket/client/reconnect-controller.d.ts +56 -0
  57. package/dist/socket/client/reconnect-controller.js +177 -0
  58. package/dist/socket/client/reconnect-controller.js.map +1 -0
  59. package/dist/socket/client/rotation-controller.d.ts +32 -0
  60. package/dist/socket/client/rotation-controller.js +76 -0
  61. package/dist/socket/client/rotation-controller.js.map +1 -0
  62. package/dist/socket/client/shared-timer-scheduler.d.ts +17 -0
  63. package/dist/socket/client/shared-timer-scheduler.js +77 -0
  64. package/dist/socket/client/shared-timer-scheduler.js.map +1 -0
  65. package/dist/socket/client/socket-client.d.ts +2 -0
  66. package/dist/socket/client/socket-client.js +219 -0
  67. package/dist/socket/client/socket-client.js.map +1 -0
  68. package/dist/socket/client/types.d.ts +101 -0
  69. package/dist/socket/client/types.js +3 -0
  70. package/dist/socket/client/types.js.map +1 -0
  71. package/dist/socket/client/websocket-client-transport.d.ts +23 -0
  72. package/dist/socket/client/websocket-client-transport.js +152 -0
  73. package/dist/socket/client/websocket-client-transport.js.map +1 -0
  74. package/dist/socket/decorators.d.ts +38 -0
  75. package/dist/socket/decorators.js +271 -0
  76. package/dist/socket/decorators.js.map +1 -0
  77. package/dist/socket/index.d.ts +2 -0
  78. package/dist/socket/index.js +2 -0
  79. package/dist/socket/index.js.map +1 -1
  80. package/dist/socket/multi.d.ts +33 -0
  81. package/dist/socket/multi.js +98 -0
  82. package/dist/socket/multi.js.map +1 -0
  83. package/dist/socket/socket.d.ts +22 -4
  84. package/dist/socket/socket.js +82 -22
  85. package/dist/socket/socket.js.map +1 -1
  86. package/dist/socket/transport.d.ts +124 -6
  87. package/dist/socket/transport.js +389 -4
  88. package/dist/socket/transport.js.map +1 -1
  89. package/dist/sync/client.d.ts +16 -0
  90. package/dist/sync/client.js +171 -0
  91. package/dist/sync/client.js.map +1 -0
  92. package/dist/sync/index.d.ts +10 -0
  93. package/dist/sync/index.js +30 -0
  94. package/dist/sync/index.js.map +1 -0
  95. package/dist/sync/machine.d.ts +3 -0
  96. package/dist/sync/machine.js +185 -0
  97. package/dist/sync/machine.js.map +1 -0
  98. package/dist/sync/network.d.ts +38 -0
  99. package/dist/sync/network.js +278 -0
  100. package/dist/sync/network.js.map +1 -0
  101. package/dist/sync/testing.d.ts +38 -0
  102. package/dist/sync/testing.js +48 -0
  103. package/dist/sync/testing.js.map +1 -0
  104. package/dist/sync/ticker.d.ts +21 -0
  105. package/dist/sync/ticker.js +57 -0
  106. package/dist/sync/ticker.js.map +1 -0
  107. package/dist/sync/types.d.ts +115 -0
  108. package/dist/sync/types.js +3 -0
  109. package/dist/sync/types.js.map +1 -0
  110. package/dist/upload/engine/engine.d.ts +52 -0
  111. package/dist/upload/engine/engine.js +172 -0
  112. package/dist/upload/engine/engine.js.map +1 -0
  113. package/dist/upload/engine/executors.d.ts +44 -0
  114. package/dist/upload/engine/executors.js +62 -0
  115. package/dist/upload/engine/executors.js.map +1 -0
  116. package/dist/upload/engine/index.d.ts +12 -0
  117. package/dist/upload/engine/index.js +29 -0
  118. package/dist/upload/engine/index.js.map +1 -0
  119. package/dist/upload/engine/progress.d.ts +48 -0
  120. package/dist/upload/engine/progress.js +57 -0
  121. package/dist/upload/engine/progress.js.map +1 -0
  122. package/dist/upload/index.d.ts +10 -0
  123. package/dist/{proxy → upload}/index.js +6 -8
  124. package/dist/upload/index.js.map +1 -0
  125. package/dist/upload/testing.d.ts +21 -0
  126. package/dist/upload/testing.js +76 -0
  127. package/dist/upload/testing.js.map +1 -0
  128. package/dist/upload/types.d.ts +230 -0
  129. package/dist/upload/types.js +74 -0
  130. package/dist/upload/types.js.map +1 -0
  131. package/package.json +26 -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,273 @@
1
+ /**
2
+ * `sync/network.ts`
3
+ * - L1 network decorators: reconnect-on-death wrapper and raw wire translator.
4
+ * - additive to `src/socket`; free to compose with `createFilteredNetwork` (translated -> filtered -> L3).
5
+ *
6
+ * @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
7
+ */
8
+ import { WEBSOCKET_NETWORK_SCOPE, } from '../socket/index.js';
9
+ /**
10
+ * default watchdog cadence for readyState-based death detection.
11
+ * needed because an in-memory `Network.close()` notifies no one (see `socket/socket.ts`); only a
12
+ * real `OwnedWebSocketNetwork`/`BrowserWebSocketNetwork` close notifies via `onError` (see below),
13
+ * so the watchdog is a fallback and can stay slow — 1s keeps idle browser cost negligible.
14
+ */
15
+ const DEFAULT_WATCHDOG_MS = 1000;
16
+ /** create the L1 reconnect decorator: swaps the internal network on death, keeping instance identity for L3 */
17
+ export const createReconnectingNetwork = (factory, options) => new ReconnectingNetwork(factory, options);
18
+ /** `NetworkSupportable` decorator that transparently swaps its internal network on death */
19
+ class ReconnectingNetwork {
20
+ constructor(factory, options) {
21
+ var _a, _b, _c, _d;
22
+ this.factory = factory;
23
+ this._generation = 0;
24
+ /** connected: 정상 감시 | connecting: 후보 open 대기 | backoff: 재시도 대기 | closed: 영구 종료 */
25
+ this.phase = 'connected';
26
+ this.retryCount = 0;
27
+ this.lastMessageAt = Date.now();
28
+ this.messageHandlers = new Set();
29
+ this.errorHandlers = new Set();
30
+ this.reconnectHandlers = new Set();
31
+ this.baseMs = (_a = options === null || options === void 0 ? void 0 : options.baseMs) !== null && _a !== void 0 ? _a : 1000;
32
+ this.factor = (_b = options === null || options === void 0 ? void 0 : options.factor) !== null && _b !== void 0 ? _b : 2;
33
+ this.maxMs = (_c = options === null || options === void 0 ? void 0 : options.maxMs) !== null && _c !== void 0 ? _c : 30000;
34
+ this.maxRetries = options === null || options === void 0 ? void 0 : options.maxRetries;
35
+ this.idleTimeoutMs = options === null || options === void 0 ? void 0 : options.idleTimeoutMs;
36
+ this.delayMs = this.baseMs;
37
+ this.current = factory();
38
+ this.attach(this.current);
39
+ this.watchdogTimer = setInterval(() => this.watch(), (_d = options === null || options === void 0 ? void 0 : options.watchdogMs) !== null && _d !== void 0 ? _d : DEFAULT_WATCHDOG_MS);
40
+ }
41
+ /** internal network generation (0 initially, +1 per reconnect) */
42
+ get generation() {
43
+ return this._generation;
44
+ }
45
+ get readyState() {
46
+ return this.phase === 'closed' ? 'closed' : this.current.readyState;
47
+ }
48
+ ready() {
49
+ var _a, _b, _c;
50
+ return (_c = (_b = (_a = this.current).ready) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : Promise.resolve();
51
+ }
52
+ onOpen(handler) {
53
+ var _a, _b, _c;
54
+ return (_c = (_b = (_a = this.current).onOpen) === null || _b === void 0 ? void 0 : _b.call(_a, handler)) !== null && _c !== void 0 ? _c : (() => undefined);
55
+ }
56
+ /** while disconnected (mid-reconnect or permanently closed) this throws synchronously; no send queuing */
57
+ send(data) {
58
+ if (this.phase === 'closed')
59
+ throw new Error(`@network is closed - reconnectingNetwork.send`);
60
+ if (this.current.readyState !== 'open') {
61
+ throw new Error(`@network is not connected - reconnectingNetwork.send`);
62
+ }
63
+ this.current.send(data);
64
+ }
65
+ onMessage(handler) {
66
+ this.messageHandlers.add(handler);
67
+ return () => this.messageHandlers.delete(handler);
68
+ }
69
+ onError(handler) {
70
+ this.errorHandlers.add(handler);
71
+ return () => this.errorHandlers.delete(handler);
72
+ }
73
+ onReconnect(handler) {
74
+ this.reconnectHandlers.add(handler);
75
+ return () => this.reconnectHandlers.delete(handler);
76
+ }
77
+ /** options are remembered and re-applied to every reconnected generation */
78
+ configure(options) {
79
+ var _a, _b;
80
+ this.configured = Object.assign(Object.assign({}, this.configured), options);
81
+ (_b = (_a = this.current).configure) === null || _b === void 0 ? void 0 : _b.call(_a, this.configured);
82
+ }
83
+ /** stop reconnecting and close the internal network for good */
84
+ close(code, reason) {
85
+ if (this.phase === 'closed')
86
+ return;
87
+ this.phase = 'closed';
88
+ clearInterval(this.watchdogTimer);
89
+ if (this.reconnectTimer)
90
+ clearTimeout(this.reconnectTimer);
91
+ this.detach();
92
+ this.current.close(code, reason);
93
+ this.messageHandlers.clear();
94
+ this.errorHandlers.clear();
95
+ this.reconnectHandlers.clear();
96
+ }
97
+ attach(network) {
98
+ this.unsubscribeMessage = network.onMessage(raw => {
99
+ this.lastMessageAt = Date.now();
100
+ for (const handler of [...this.messageHandlers])
101
+ handler(raw);
102
+ });
103
+ this.unsubscribeError = network.onError((error, context) => {
104
+ for (const handler of [...this.errorHandlers])
105
+ handler(error, Object.assign(Object.assign({}, context), { network: this }));
106
+ //! `OwnedWebSocketNetwork`/`BrowserWebSocketNetwork` notify a close via onError with this scope
107
+ //! (see `WEBSOCKET_NETWORK_SCOPE` in `socket/websocket.ts`). other onError calls (e.g. delivery
108
+ //! errors) are forwarded above but do not by themselves mean the network died.
109
+ if (context.scope === WEBSOCKET_NETWORK_SCOPE.ownedClose ||
110
+ context.scope === WEBSOCKET_NETWORK_SCOPE.browserClose) {
111
+ this.onInnerDeath();
112
+ }
113
+ });
114
+ }
115
+ detach() {
116
+ var _a, _b, _c;
117
+ (_a = this.unsubscribeMessage) === null || _a === void 0 ? void 0 : _a.call(this);
118
+ (_b = this.unsubscribeError) === null || _b === void 0 ? void 0 : _b.call(this);
119
+ (_c = this.unsubscribeCandidateOpen) === null || _c === void 0 ? void 0 : _c.call(this);
120
+ }
121
+ onInnerDeath() {
122
+ if (this.phase === 'connected')
123
+ this.beginBackoff();
124
+ else if (this.phase === 'connecting')
125
+ this.failAttempt(new Error(`@candidate network died before open - reconnectingNetwork`), 'reconnectingNetwork.connect');
126
+ }
127
+ /** watchdog fallback for networks that close without notifying (e.g. in-memory `Network.close()`) */
128
+ watch() {
129
+ const state = this.current.readyState;
130
+ if (this.phase === 'connected') {
131
+ if (state === 'closing' || state === 'closed')
132
+ return this.beginBackoff();
133
+ if (this.idleTimeoutMs && Date.now() - this.lastMessageAt > this.idleTimeoutMs)
134
+ this.beginBackoff();
135
+ return;
136
+ }
137
+ if (this.phase === 'connecting') {
138
+ if (state === 'open')
139
+ return this.settleReconnected(); // onOpen 없는 network용 fallback
140
+ if (state === 'closing' || state === 'closed')
141
+ this.onInnerDeath();
142
+ }
143
+ }
144
+ beginBackoff() {
145
+ this.detach();
146
+ this.phase = 'backoff';
147
+ this.reconnectTimer = setTimeout(() => this.attemptReconnect(), this.delayMs);
148
+ }
149
+ attemptReconnect() {
150
+ var _a, _b;
151
+ if (this.phase === 'closed')
152
+ return;
153
+ if (this.maxRetries != null && this.retryCount >= this.maxRetries) {
154
+ this.phase = 'closed';
155
+ clearInterval(this.watchdogTimer);
156
+ const error = new Error(`@network exceeded maxRetries[${this.maxRetries}] - reconnectingNetwork`);
157
+ for (const handler of [...this.errorHandlers])
158
+ handler(error, { scope: 'reconnectingNetwork.maxRetries', network: this });
159
+ this.messageHandlers.clear();
160
+ this.errorHandlers.clear();
161
+ this.reconnectHandlers.clear();
162
+ return;
163
+ }
164
+ let next;
165
+ try {
166
+ next = this.factory();
167
+ }
168
+ catch (e) {
169
+ this.failAttempt(e, 'reconnectingNetwork.factory');
170
+ return;
171
+ }
172
+ this.current = next;
173
+ this.attach(next);
174
+ if (this.configured)
175
+ (_a = next.configure) === null || _a === void 0 ? void 0 : _a.call(next, this.configured);
176
+ this.phase = 'connecting';
177
+ //! success is declared only once the candidate actually OPENS. a factory return alone is not a
178
+ //! connection (a real WebSocket constructs fine while the server is down), so resetting backoff
179
+ //! here would degrade to a constant-rate reconnect storm with an onReconnect/tick per attempt.
180
+ const state = next.readyState;
181
+ if (state === 'open')
182
+ return this.settleReconnected();
183
+ if (state === 'closing' || state === 'closed')
184
+ return this.onInnerDeath();
185
+ this.unsubscribeCandidateOpen = (_b = next.onOpen) === null || _b === void 0 ? void 0 : _b.call(next, () => {
186
+ if (this.phase === 'connecting' && this.current === next)
187
+ this.settleReconnected();
188
+ });
189
+ //! a candidate stuck in 'connecting' is bounded by the inner network's own connect timeout
190
+ //! (e.g. `OwnedWebSocketNetwork.connectTimeoutMs`), which actual-closes and lands in onInnerDeath.
191
+ }
192
+ /** a reconnect attempt failed (factory throw, or candidate died before open): keep growing the backoff */
193
+ failAttempt(error, scope) {
194
+ this.detach();
195
+ this.retryCount++;
196
+ this.delayMs = Math.min(this.delayMs * this.factor, this.maxMs);
197
+ for (const handler of [...this.errorHandlers])
198
+ handler(error, { scope, network: this });
199
+ this.phase = 'backoff';
200
+ this.reconnectTimer = setTimeout(() => this.attemptReconnect(), this.delayMs);
201
+ }
202
+ /** the candidate opened: only now reset the backoff/retry budget and notify onReconnect */
203
+ settleReconnected() {
204
+ var _a;
205
+ (_a = this.unsubscribeCandidateOpen) === null || _a === void 0 ? void 0 : _a.call(this);
206
+ this.unsubscribeCandidateOpen = undefined;
207
+ this.phase = 'connected';
208
+ this._generation++;
209
+ this.retryCount = 0;
210
+ this.delayMs = this.baseMs;
211
+ this.lastMessageAt = Date.now();
212
+ for (const handler of [...this.reconnectHandlers])
213
+ handler();
214
+ }
215
+ }
216
+ /** create the L1 wire translator decorator over a raw string, same slot as `createFilteredNetwork` */
217
+ export const createTranslatedNetwork = (source, translator) => new TranslatedNetwork(source, translator);
218
+ /** `NetworkSupportable` decorator that translates raw strings at the wire boundary */
219
+ class TranslatedNetwork {
220
+ constructor(source, translator) {
221
+ this.source = source;
222
+ this.translator = translator;
223
+ this.errorHandlers = new Set();
224
+ this.unsubscribeSourceError = source.onError((error, context) => this.emitError(error, context));
225
+ }
226
+ get readyState() {
227
+ return this.source.readyState;
228
+ }
229
+ ready() {
230
+ var _a, _b, _c;
231
+ return (_c = (_b = (_a = this.source).ready) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : Promise.resolve();
232
+ }
233
+ onOpen(handler) {
234
+ var _a, _b, _c;
235
+ return (_c = (_b = (_a = this.source).onOpen) === null || _b === void 0 ? void 0 : _b.call(_a, handler)) !== null && _c !== void 0 ? _c : (() => undefined);
236
+ }
237
+ send(data) {
238
+ this.source.send(this.translator.outbound ? this.translator.outbound(data) : data);
239
+ }
240
+ onMessage(handler) {
241
+ return this.source.onMessage(raw => {
242
+ let translated;
243
+ try {
244
+ translated = this.translator.inbound ? this.translator.inbound(raw) : raw;
245
+ }
246
+ catch (e) {
247
+ this.emitError(e, { scope: 'translatedNetwork.inbound' });
248
+ return;
249
+ }
250
+ if (translated === undefined)
251
+ return; // dropped by translator
252
+ handler(translated);
253
+ });
254
+ }
255
+ configure(options) {
256
+ var _a, _b;
257
+ (_b = (_a = this.source).configure) === null || _b === void 0 ? void 0 : _b.call(_a, options);
258
+ }
259
+ onError(handler) {
260
+ this.errorHandlers.add(handler);
261
+ return () => this.errorHandlers.delete(handler);
262
+ }
263
+ close(code, reason) {
264
+ this.unsubscribeSourceError();
265
+ this.errorHandlers.clear();
266
+ this.source.close(code, reason);
267
+ }
268
+ emitError(error, context) {
269
+ for (const handler of [...this.errorHandlers])
270
+ handler(error, Object.assign(Object.assign({}, context), { network: this }));
271
+ }
272
+ }
273
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/sync/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `sync/testing.ts`
3
+ * - bridges the in-memory `Peer` simulator into a single `NetworkSupportable` for L3/L4 specs.
4
+ * - test/dev only; kept OUT of `sync/index.ts` so production bundles never pull in the simulator runtime.
5
+ *
6
+ * @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
7
+ */
8
+ //! simulator runtime lives in the isolated `../socket/testing` module (kept out of the root barrel).
9
+ import { createNetwork, createPeer } from '../socket/testing.js';
10
+ /**
11
+ * create a connected client/server `Peer` pair and expose the client side as one `NetworkSupportable`.
12
+ *
13
+ * `Peer.dispatch` settles an envelope against its own pending map, and otherwise fans every remaining
14
+ * envelope out to `Peer.onMessage()` listeners whose return value becomes an automatic `result` reply
15
+ * (regardless of whether the listener actually returns anything). A client-side bridge built on
16
+ * `clientPeer.post()` + `clientPeer.onMessage()` therefore echoes every pull result and every server
17
+ * event straight back to the server as an empty `result`, and — since the server has no pending for
18
+ * that mid either — the server echoes it right back, forever. `send()` and `onMessage()` below instead
19
+ * talk to the raw uplink/downlink `Network` instances directly, bypassing `Peer` dispatch on the client
20
+ * side entirely, so no such reply is ever produced. The `server` `Peer` itself is untouched and keeps
21
+ * its normal `onMessage()`/`post()` contract for the simulated server band.
22
+ */
23
+ export const createPeerBridge = (options) => {
24
+ let serverNetwork;
25
+ const server = createPeer(Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.server), { networkFactory: context => (serverNetwork = createNetwork(Object.assign({ id: context.id, fromPeerId: context.fromPeerId, toPeerId: context.toPeerId, logger: context.logger }, context.options))) }));
26
+ const client = createPeer(options === null || options === void 0 ? void 0 : options.client);
27
+ const clientId = client.connect(server);
28
+ const clientNetwork = client.network;
29
+ if (!clientNetwork || !serverNetwork) {
30
+ throw new Error(`@peer bridge network capture failed - sync.testing.createPeerBridge`);
31
+ }
32
+ const network = {
33
+ get readyState() {
34
+ return client.readyState;
35
+ },
36
+ ready: () => client.ready(),
37
+ send: (data) => clientNetwork.send(data),
38
+ onMessage: handler => serverNetwork.onMessage(handler),
39
+ onError: handler => client.onError(handler),
40
+ close: () => client.close(),
41
+ };
42
+ return { network, server, serverNetwork, clientId };
43
+ };
44
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/sync/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,qGAAqG;AACrG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAC;AAoB3E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA2B,EAAc,EAAE;IACxE,IAAI,aAA6C,CAAC;IAClD,MAAM,MAAM,GAAoB,UAAU,iCACnC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,KAClB,cAAc,EAAE,OAAO,CAAC,EAAE,CACtB,CAAC,aAAa,GAAG,aAAa,iBAC1B,EAAE,EAAE,OAAO,CAAC,EAAE,EACd,UAAU,EAAE,OAAO,CAAC,UAAU,EAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IACnB,OAAO,CAAC,OAAO,EACpB,CAAC,IACT,CAAC;IACH,MAAM,MAAM,GAAoB,UAAU,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC;IACrC,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;KAC1F;IAED,MAAM,OAAO,GAAuB;QAChC,IAAI,UAAU;YACV,OAAO,MAAM,CAAC,UAAU,CAAC;QAC7B,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE;QAC3B,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,aAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACjD,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,aAAc,CAAC,SAAS,CAAC,OAAO,CAAC;QACvD,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAC3C,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE;KAC9B,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AACxD,CAAC,CAAC"}
@@ -0,0 +1,53 @@
1
+ /** create a self-rescheduling ticker: no overlap, backoff on failure, restore on success */
2
+ export const createSyncTicker = (tick, options) => new SyncTicker(tick, options);
3
+ class SyncTicker {
4
+ constructor(tick, options) {
5
+ var _a, _b;
6
+ this.tick = tick;
7
+ this.options = options;
8
+ this._running = false;
9
+ /** bumped on every start()/stop(): an in-flight tick from an old epoch must not reschedule a second chain */
10
+ this.epoch = 0;
11
+ this.factor = (_a = options.factor) !== null && _a !== void 0 ? _a : 2;
12
+ this.maxMs = (_b = options.maxMs) !== null && _b !== void 0 ? _b : 60000;
13
+ this.delayMs = options.intervalMs;
14
+ }
15
+ get running() {
16
+ return this._running;
17
+ }
18
+ start() {
19
+ if (this._running)
20
+ return; // re-entrant start() is a no-op
21
+ this._running = true;
22
+ this.epoch++;
23
+ this.delayMs = this.options.intervalMs;
24
+ this.schedule(this.epoch);
25
+ }
26
+ stop() {
27
+ this._running = false;
28
+ this.epoch++;
29
+ if (this.timer)
30
+ clearTimeout(this.timer);
31
+ this.timer = undefined;
32
+ }
33
+ schedule(epoch) {
34
+ if (!this._running || epoch !== this.epoch)
35
+ return;
36
+ this.timer = setTimeout(() => this.run(epoch), this.delayMs);
37
+ }
38
+ /** the next tick is scheduled only after this one settles (setTimeout chain) - no overlap */
39
+ run(epoch) {
40
+ this.tick().then(() => {
41
+ if (epoch !== this.epoch)
42
+ return; // stale chain (stopped/restarted while in flight)
43
+ this.delayMs = this.options.intervalMs;
44
+ this.schedule(epoch);
45
+ }, () => {
46
+ if (epoch !== this.epoch)
47
+ return; // stale chain (stopped/restarted while in flight)
48
+ this.delayMs = Math.min(this.delayMs * this.factor, this.maxMs);
49
+ this.schedule(epoch);
50
+ });
51
+ }
52
+ }
53
+ //# sourceMappingURL=ticker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticker.js","sourceRoot":"","sources":["../../../src/sync/ticker.ts"],"names":[],"mappings":"AAqBA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAA4B,EAAE,OAA0B,EAAyB,EAAE,CAChH,IAAI,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAElC,MAAM,UAAU;IASZ,YAAoC,IAA4B,EAAmB,OAA0B;;QAAzE,SAAI,GAAJ,IAAI,CAAwB;QAAmB,YAAO,GAAP,OAAO,CAAmB;QAJrG,aAAQ,GAAG,KAAK,CAAC;QACzB,6GAA6G;QACrG,UAAK,GAAG,CAAC,CAAC;QAGd,IAAI,CAAC,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,mCAAI,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,MAAA,OAAO,CAAC,KAAK,mCAAI,KAAM,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,KAAK;QACR,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,gCAAgC;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAEM,IAAI;QACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,KAAK;YAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAC3B,CAAC;IAEO,QAAQ,CAAC,KAAa;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;YAAE,OAAO;QACnD,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAED,6FAA6F;IACrF,GAAG,CAAC,KAAa;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CACZ,GAAG,EAAE;YACD,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,kDAAkD;YACpF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,EACD,GAAG,EAAE;YACD,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,kDAAkD;YACpF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAChE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CACJ,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sync/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,166 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { UPLOAD_FAILURE_CODE, UPLOAD_FAILURE_SOURCE } from '../types.js';
11
+ import { UploadProgressTracker } from './progress.js';
12
+ /**
13
+ * transfers in flight at once.
14
+ * - a browser queues beyond ~6 per origin, and a queued presigned url burns its `expiresAt` while it waits.
15
+ * - override per engine when a shell measures something better.
16
+ */
17
+ export const UPLOAD_DEFAULT_CONCURRENCY = 3;
18
+ /** run `task` over 0..count-1 with at most `limit` in flight; results keep input order */
19
+ const runPooled = (count, limit, task) => __awaiter(void 0, void 0, void 0, function* () {
20
+ const results = new Array(count);
21
+ let next = 0;
22
+ const worker = () => __awaiter(void 0, void 0, void 0, function* () {
23
+ for (;;) {
24
+ const index = next++;
25
+ if (index >= count)
26
+ return;
27
+ results[index] = yield task(index);
28
+ }
29
+ });
30
+ const size = Math.max(1, Math.min(limit, count));
31
+ yield Promise.all(new Array(size).fill(0).map(() => worker()));
32
+ return results;
33
+ });
34
+ const asBody = (source) => __awaiter(void 0, void 0, void 0, function* () {
35
+ return ({
36
+ name: source.name,
37
+ contentType: source.contentType,
38
+ contentSize: source.contentSize,
39
+ hash: source.hash ? yield source.hash() : undefined,
40
+ });
41
+ });
42
+ export class UploadEngine {
43
+ constructor(service, executors, options) {
44
+ this.service = service;
45
+ this.executors = executors;
46
+ this.options = options;
47
+ this.kinds = executors.map(executor => executor.kind);
48
+ }
49
+ /** returns one view per source, in order: `stored`, or `failed` with the reason. `onProgress` gets a snapshot per change */
50
+ upload(sources, onProgress) {
51
+ var _a, _b;
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ const tracker = new UploadProgressTracker(sources.map(source => source.contentSize), onProgress);
54
+ tracker.publish();
55
+ const list = yield Promise.all(sources.map(asBody));
56
+ const { list: tickets } = yield this.service.start({ list, transfers: this.kinds });
57
+ const limit = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.concurrency) !== null && _b !== void 0 ? _b : UPLOAD_DEFAULT_CONCURRENCY;
58
+ const receipts = yield runPooled(tickets.length, limit, i => this.transferTracked(tickets[i], sources[i], tracker, i));
59
+ // a server that broke rule 1 (shorter list) must not leave the bar hanging
60
+ sources.forEach((_, i) => tracker.settle(i));
61
+ const pending = receipts.filter((item) => !!item);
62
+ const settled = pending.length ? (yield this.service.complete({ list: pending })).list : [];
63
+ const byId = new Map(settled.filter(view => !!view.id).map((view) => [view.id, view]));
64
+ return tickets.map(ticket => (ticket.upload.id && byId.get(ticket.upload.id)) || ticket.upload);
65
+ });
66
+ }
67
+ transferTracked(ticket, source, tracker, index) {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ try {
70
+ return yield this.transfer(ticket, source, tracker.sink(index));
71
+ }
72
+ catch (error) {
73
+ // an executor that throws (a CORS preflight failure surfaces as one) must not take the batch down
74
+ const id = ticket.upload.id;
75
+ if (!id)
76
+ return undefined;
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ return {
79
+ id,
80
+ failure: { source: UPLOAD_FAILURE_SOURCE.client, code: UPLOAD_FAILURE_CODE.unknown, message },
81
+ };
82
+ }
83
+ finally {
84
+ tracker.settle(index);
85
+ }
86
+ });
87
+ }
88
+ transfer(ticket, source, onProgress) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ const id = ticket.upload.id;
91
+ // rejected at start: nothing was created, nothing to complete
92
+ if (!id)
93
+ return undefined;
94
+ // no instruction: already stored (dedup) — still confirmed through complete
95
+ if (!ticket.transfer)
96
+ return { id };
97
+ const executor = this.executors.find(candidate => { var _a; return candidate.kind === ((_a = ticket.transfer) === null || _a === void 0 ? void 0 : _a.kind); });
98
+ if (!executor)
99
+ return { id, failure: { source: UPLOAD_FAILURE_SOURCE.client, code: UPLOAD_FAILURE_CODE.notAcceptable } };
100
+ // NOTE: `ticket.transfer` must not be logged or stored — it may carry a credential url
101
+ return executor.run(id, ticket.transfer, source, onProgress);
102
+ });
103
+ }
104
+ }
105
+ /** lemon-core error convention: "<status> <LABEL> - <detail>" (status 0 = no response, XHR convention) */
106
+ const API_ERROR = /^(\d{1,3}) ([A-Z][A-Z ]*?) - ([\s\S]*)$/;
107
+ const codeOfApiStatus = (status) => {
108
+ switch (status) {
109
+ case 0:
110
+ return UPLOAD_FAILURE_CODE.network;
111
+ case 400:
112
+ return UPLOAD_FAILURE_CODE.invalid;
113
+ case 404:
114
+ return UPLOAD_FAILURE_CODE.notFound;
115
+ case 406:
116
+ return UPLOAD_FAILURE_CODE.notAcceptable;
117
+ case 409:
118
+ return UPLOAD_FAILURE_CODE.conflict;
119
+ case 410:
120
+ return UPLOAD_FAILURE_CODE.expired;
121
+ case 413:
122
+ return UPLOAD_FAILURE_CODE.tooLarge;
123
+ case 415:
124
+ return UPLOAD_FAILURE_CODE.unsupported;
125
+ default:
126
+ return UPLOAD_FAILURE_CODE.unknown;
127
+ }
128
+ };
129
+ /** normalize an error thrown by the API adapter */
130
+ export const asApiFailure = (error) => {
131
+ const message = error instanceof Error ? error.message : String(error);
132
+ const match = API_ERROR.exec(message);
133
+ if (!match)
134
+ return { source: UPLOAD_FAILURE_SOURCE.api, code: UPLOAD_FAILURE_CODE.unknown, message };
135
+ const status = Number(match[1]);
136
+ return {
137
+ source: UPLOAD_FAILURE_SOURCE.api,
138
+ code: codeOfApiStatus(status),
139
+ status,
140
+ reason: match[2],
141
+ message: match[3],
142
+ };
143
+ };
144
+ /** S3 error `<Code>` -> normalized code (roadmap 2). unknown codes fall back by status */
145
+ const STORAGE_CODES = {
146
+ SignatureDoesNotMatch: UPLOAD_FAILURE_CODE.signature,
147
+ AccessDenied: UPLOAD_FAILURE_CODE.expired,
148
+ ExpiredToken: UPLOAD_FAILURE_CODE.expired,
149
+ BadDigest: UPLOAD_FAILURE_CODE.checksum,
150
+ XAmzContentSHA256Mismatch: UPLOAD_FAILURE_CODE.checksum,
151
+ EntityTooLarge: UPLOAD_FAILURE_CODE.tooLarge,
152
+ RequestTimeout: UPLOAD_FAILURE_CODE.network,
153
+ };
154
+ /** normalize a non-2xx answer from the storage endpoint (status 0 = no response) */
155
+ export const asStorageFailure = (status, code) => {
156
+ const known = code ? STORAGE_CODES[code] : undefined;
157
+ const byStatus = status === 0
158
+ ? UPLOAD_FAILURE_CODE.network
159
+ : status === 403
160
+ ? UPLOAD_FAILURE_CODE.signature
161
+ : status === 413
162
+ ? UPLOAD_FAILURE_CODE.tooLarge
163
+ : UPLOAD_FAILURE_CODE.unknown;
164
+ return { source: UPLOAD_FAILURE_SOURCE.storage, code: known !== null && known !== void 0 ? known : byStatus, status, reason: code };
165
+ };
166
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../../src/upload/engine/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { UPLOAD_FAILURE_CODE, UPLOAD_FAILURE_SOURCE, UPLOAD_TRANSFER_KIND } from '../types.js';
11
+ import { asApiFailure, asStorageFailure } from './engine.js';
12
+ import { asContentBytes } from './progress.js';
13
+ /** roadmap 1 — the only place that knows bytes go to our API as base64 */
14
+ export class InlineExecutor {
15
+ constructor(send,
16
+ /** shell-specific base64 encoder (btoa / Buffer / RN polyfill) */
17
+ toBase64) {
18
+ this.send = send;
19
+ this.toBase64 = toBase64;
20
+ this.kind = UPLOAD_TRANSFER_KIND.inline;
21
+ }
22
+ run(id, transfer, source, onProgress) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ if (source.contentSize > transfer.maxBytes) {
25
+ return { id, failure: { source: UPLOAD_FAILURE_SOURCE.client, code: UPLOAD_FAILURE_CODE.tooLarge } };
26
+ }
27
+ try {
28
+ const body = { content: this.toBase64(yield source.bytes()) };
29
+ // wire bytes are base64 JSON (~4/3 of the send): report in send bytes
30
+ yield this.send(id, body, (loaded, total) => onProgress(asContentBytes(loaded, total, source.contentSize)));
31
+ return { id };
32
+ }
33
+ catch (error) {
34
+ return { id, failure: asApiFailure(error) };
35
+ }
36
+ });
37
+ }
38
+ }
39
+ /** roadmap 2 — added next to `InlineExecutor`; `UploadEngine` is untouched */
40
+ export class PresignedPutExecutor {
41
+ constructor(put) {
42
+ this.put = put;
43
+ this.kind = UPLOAD_TRANSFER_KIND.presignedPut;
44
+ }
45
+ run(id, transfer, source, onProgress) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ const res = yield this.put(transfer.url, transfer.headers, yield source.bytes(), (loaded, total) => onProgress(asContentBytes(loaded, total, source.contentSize)));
48
+ if (res.status >= 200 && res.status < 300)
49
+ return { id };
50
+ // 412 = object already exists under this key; the server decides at complete
51
+ if (res.status === 412)
52
+ return { id };
53
+ return { id, failure: asStorageFailure(res.status, res.code) };
54
+ });
55
+ }
56
+ }
57
+ //# sourceMappingURL=executors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executors.js","sourceRoot":"","sources":["../../../../src/upload/engine/executors.ts"],"names":[],"mappings":";;;;;;;;;AAgBA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAE5F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS5C,0EAA0E;AAC1E,MAAM,OAAO,cAAc;IAGvB,YACqB,IAAoB;IACrC,kEAAkE;IACjD,QAAuC;QAFvC,SAAI,GAAJ,IAAI,CAAgB;QAEpB,aAAQ,GAAR,QAAQ,CAA+B;QAL5C,SAAI,GAAG,oBAAoB,CAAC,MAAM,CAAC;IAMhD,CAAC;IAES,GAAG,CACZ,EAAU,EACV,QAA8B,EAC9B,MAAoB,EACpB,UAA8B;;YAE9B,IAAI,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,QAAQ,EAAE;gBACxC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,CAAC,MAAM,EAAE,IAAI,EAAE,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC;aACxG;YACD,IAAI;gBACA,MAAM,IAAI,GAAmB,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;gBAC9E,sEAAsE;gBACtE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC5G,OAAO,EAAE,EAAE,EAAE,CAAC;aACjB;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;aAC/C;QACL,CAAC;KAAA;CACJ;AAaD,8EAA8E;AAC9E,MAAM,OAAO,oBAAoB;IAG7B,YAAoC,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;QAF/B,SAAI,GAAG,oBAAoB,CAAC,YAAY,CAAC;IAEP,CAAC;IAEtC,GAAG,CACZ,EAAU,EACV,QAAoC,EACpC,MAAoB,EACpB,UAA8B;;YAE9B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAC/F,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAChE,CAAC;YACF,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;gBAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,6EAA6E;YAC7E,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACtC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACnE,CAAC;KAAA;CACJ"}