@hypen-space/core 0.4.980 → 0.5.3

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 (100) hide show
  1. package/README.md +5 -8
  2. package/dist/a11y.d.ts +82 -0
  3. package/dist/app.js +13 -1168
  4. package/dist/app.js.map +3 -9
  5. package/dist/chunk-00zt3w6e.js +58 -0
  6. package/dist/chunk-00zt3w6e.js.map +10 -0
  7. package/dist/chunk-3zvyth50.js +87 -0
  8. package/dist/chunk-3zvyth50.js.map +10 -0
  9. package/dist/chunk-5gtx3pza.js +11 -0
  10. package/dist/chunk-5gtx3pza.js.map +9 -0
  11. package/dist/chunk-7222131a.js +191 -0
  12. package/dist/chunk-7222131a.js.map +10 -0
  13. package/dist/chunk-avchpwhf.js +200 -0
  14. package/dist/chunk-avchpwhf.js.map +10 -0
  15. package/dist/chunk-ec0tgy9a.js +154 -0
  16. package/dist/chunk-ec0tgy9a.js.map +10 -0
  17. package/dist/chunk-fnss4dm2.js +479 -0
  18. package/dist/chunk-fnss4dm2.js.map +10 -0
  19. package/dist/chunk-g2gz9pgg.js +133 -0
  20. package/dist/chunk-g2gz9pgg.js.map +10 -0
  21. package/dist/chunk-g72v6mmf.js +341 -0
  22. package/dist/chunk-g72v6mmf.js.map +10 -0
  23. package/dist/chunk-g7g3jxty.js +351 -0
  24. package/dist/chunk-g7g3jxty.js.map +10 -0
  25. package/dist/chunk-g830re2c.js +50 -0
  26. package/dist/chunk-g830re2c.js.map +10 -0
  27. package/dist/chunk-gtwh1sg7.js +127 -0
  28. package/dist/chunk-gtwh1sg7.js.map +10 -0
  29. package/dist/chunk-k12cwfst.js +72 -0
  30. package/dist/chunk-k12cwfst.js.map +10 -0
  31. package/dist/chunk-mbqqsz6r.js +128 -0
  32. package/dist/chunk-mbqqsz6r.js.map +10 -0
  33. package/dist/chunk-ne632swm.js +209 -0
  34. package/dist/chunk-ne632swm.js.map +10 -0
  35. package/dist/chunk-p3pj1bax.js +206 -0
  36. package/dist/chunk-p3pj1bax.js.map +10 -0
  37. package/dist/chunk-vshdk2pw.js +56 -0
  38. package/dist/chunk-vshdk2pw.js.map +10 -0
  39. package/dist/chunk-wp2ebn2m.js +51 -0
  40. package/dist/chunk-wp2ebn2m.js.map +10 -0
  41. package/dist/chunk-x4qv4jm9.js +88 -0
  42. package/dist/chunk-x4qv4jm9.js.map +10 -0
  43. package/dist/chunk-ycxp4drd.js +211 -0
  44. package/dist/chunk-ycxp4drd.js.map +10 -0
  45. package/dist/components/builtin.js +14 -1246
  46. package/dist/components/builtin.js.map +3 -10
  47. package/dist/context.js +7 -362
  48. package/dist/context.js.map +3 -6
  49. package/dist/datasource.js +5 -76
  50. package/dist/datasource.js.map +3 -4
  51. package/dist/disposable.js +20 -367
  52. package/dist/disposable.js.map +3 -5
  53. package/dist/engine-base.d.ts +38 -2
  54. package/dist/engine-base.js +45 -412
  55. package/dist/engine-base.js.map +4 -6
  56. package/dist/events.js +7 -285
  57. package/dist/events.js.map +3 -5
  58. package/dist/hypen.js +8 -71
  59. package/dist/hypen.js.map +3 -4
  60. package/dist/index.browser.js +58 -2152
  61. package/dist/index.browser.js.map +3 -16
  62. package/dist/index.d.ts +4 -0
  63. package/dist/index.js +175 -3057
  64. package/dist/index.js.map +5 -22
  65. package/dist/logger.js +16 -220
  66. package/dist/logger.js.map +3 -4
  67. package/dist/managed-router.js +12 -1367
  68. package/dist/managed-router.js.map +3 -10
  69. package/dist/portable.js +6 -70
  70. package/dist/portable.js.map +3 -4
  71. package/dist/remote/client.js +9 -1010
  72. package/dist/remote/client.js.map +3 -8
  73. package/dist/remote/index.d.ts +2 -0
  74. package/dist/remote/index.js +511 -1066
  75. package/dist/remote/index.js.map +4 -9
  76. package/dist/remote/remote-session.d.ts +245 -0
  77. package/dist/remote/session.js +5 -147
  78. package/dist/remote/session.js.map +3 -4
  79. package/dist/renderer.js +7 -271
  80. package/dist/renderer.js.map +3 -5
  81. package/dist/resolver.js +5 -484
  82. package/dist/resolver.js.map +3 -5
  83. package/dist/result.js +25 -211
  84. package/dist/result.js.map +3 -4
  85. package/dist/retry.js +10 -336
  86. package/dist/retry.js.map +3 -5
  87. package/dist/router.js +9 -807
  88. package/dist/router.js.map +3 -8
  89. package/dist/state.js +10 -274
  90. package/dist/state.js.map +3 -5
  91. package/dist/types.d.ts +129 -1
  92. package/dist/validate.d.ts +19 -0
  93. package/package.json +13 -1
  94. package/src/a11y.ts +127 -0
  95. package/src/engine-base.ts +87 -4
  96. package/src/index.ts +10 -0
  97. package/src/remote/index.ts +16 -0
  98. package/src/remote/remote-session.ts +998 -0
  99. package/src/types.ts +131 -1
  100. package/src/validate.ts +37 -0
@@ -1,1014 +1,13 @@
1
- var __defProp = Object.defineProperty;
2
- var __returnValue = (v) => v;
3
- function __exportSetter(name, newValue) {
4
- this[name] = __returnValue.bind(null, newValue);
5
- }
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true,
11
- configurable: true,
12
- set: __exportSetter.bind(all, name)
13
- });
14
- };
15
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
16
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
17
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
18
- }) : x)(function(x) {
19
- if (typeof require !== "undefined")
20
- return require.apply(this, arguments);
21
- throw Error('Dynamic require of "' + x + '" is not supported');
22
- });
23
-
24
- // src/result.ts
25
- function Ok(value) {
26
- return { ok: true, value };
27
- }
28
- function Err(error) {
29
- return { ok: false, error };
30
- }
31
- function isOk(result) {
32
- return result.ok;
33
- }
34
- function isErr(result) {
35
- return !result.ok;
36
- }
37
- async function fromPromise(promise, mapError) {
38
- try {
39
- const value = await promise;
40
- return Ok(value);
41
- } catch (e) {
42
- if (mapError) {
43
- return Err(mapError(e));
44
- }
45
- return Err(e);
46
- }
47
- }
48
- function fromTry(fn, mapError) {
49
- try {
50
- return Ok(fn());
51
- } catch (e) {
52
- if (mapError) {
53
- return Err(mapError(e));
54
- }
55
- return Err(e);
56
- }
57
- }
58
- function map(result, fn) {
59
- if (result.ok) {
60
- return Ok(fn(result.value));
61
- }
62
- return result;
63
- }
64
- function mapErr(result, fn) {
65
- if (!result.ok) {
66
- return Err(fn(result.error));
67
- }
68
- return result;
69
- }
70
- function flatMap(result, fn) {
71
- if (result.ok) {
72
- return fn(result.value);
73
- }
74
- return result;
75
- }
76
- function unwrap(result) {
77
- if (result.ok) {
78
- return result.value;
79
- }
80
- throw result.error;
81
- }
82
- function unwrapOr(result, defaultValue) {
83
- if (result.ok) {
84
- return result.value;
85
- }
86
- return defaultValue;
87
- }
88
- function unwrapOrElse(result, fn) {
89
- if (result.ok) {
90
- return result.value;
91
- }
92
- return fn(result.error);
93
- }
94
- function match(result, handlers) {
95
- if (result.ok) {
96
- return handlers.ok(result.value);
97
- }
98
- return handlers.err(result.error);
99
- }
100
- function all(results) {
101
- const values = [];
102
- for (const result of results) {
103
- if (!result.ok) {
104
- return result;
105
- }
106
- values.push(result.value);
107
- }
108
- return Ok(values);
109
- }
110
-
111
- class HypenError extends Error {
112
- code;
113
- context;
114
- cause;
115
- constructor(code, message, options) {
116
- super(message);
117
- this.name = "HypenError";
118
- this.code = code;
119
- this.context = options?.context;
120
- this.cause = options?.cause;
121
- Object.setPrototypeOf(this, new.target.prototype);
122
- }
123
- }
124
-
125
- class ActionError extends HypenError {
126
- actionName;
127
- constructor(actionName, cause) {
128
- super("ACTION_ERROR", `Action handler "${actionName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`, {
129
- context: { actionName },
130
- cause: cause instanceof Error ? cause : undefined
131
- });
132
- this.name = "ActionError";
133
- this.actionName = actionName;
134
- }
135
- }
136
-
137
- class ConnectionError extends HypenError {
138
- url;
139
- attempt;
140
- constructor(url, cause, attempt) {
141
- super("CONNECTION_ERROR", `Connection to "${url}" failed${attempt ? ` (attempt ${attempt})` : ""}: ${cause instanceof Error ? cause.message : String(cause)}`, {
142
- context: { url, attempt },
143
- cause: cause instanceof Error ? cause : undefined
144
- });
145
- this.name = "ConnectionError";
146
- this.url = url;
147
- this.attempt = attempt;
148
- }
149
- }
150
-
151
- class StateError extends HypenError {
152
- path;
153
- constructor(message, path, cause) {
154
- super("STATE_ERROR", message, {
155
- context: { path },
156
- cause: cause instanceof Error ? cause : undefined
157
- });
158
- this.name = "StateError";
159
- this.path = path;
160
- }
161
- }
162
-
163
- class ParseError extends HypenError {
164
- source;
165
- constructor(message, source, cause) {
166
- super("PARSE_ERROR", message, {
167
- context: { source },
168
- cause: cause instanceof Error ? cause : undefined
169
- });
170
- this.name = "ParseError";
171
- this.source = source;
172
- }
173
- }
174
-
175
- class RenderError extends HypenError {
176
- constructor(message, cause) {
177
- super("RENDER_ERROR", message, {
178
- cause: cause instanceof Error ? cause : undefined
179
- });
180
- this.name = "RenderError";
181
- }
182
- }
183
- function classifyEngineError(err) {
184
- if (err && typeof err === "object" && "message" in err && "type" in err) {
185
- const structured = err;
186
- switch (structured.type) {
187
- case "parseError":
188
- return new ParseError(structured.message);
189
- case "stateError":
190
- return new StateError(structured.message);
191
- case "renderError":
192
- return new RenderError(structured.message);
193
- case "actionError":
194
- return new HypenError("ACTION_ERROR", structured.message);
195
- default:
196
- return new HypenError("UNKNOWN_ERROR", structured.message);
197
- }
198
- }
199
- const message = err instanceof Error ? err.message : String(err);
200
- if (message.startsWith("Parse error:")) {
201
- return new ParseError(message);
202
- }
203
- if (message.startsWith("Invalid state:") || message.startsWith("Invalid state patch:")) {
204
- return new StateError(message);
205
- }
206
- if (message.startsWith("Parent node not found:")) {
207
- return new RenderError(message);
208
- }
209
- return new RenderError(message);
210
- }
211
-
212
- // src/logger.ts
213
- var LOG_LEVEL_ORDER = {
214
- debug: 0,
215
- info: 1,
216
- warn: 2,
217
- error: 3,
218
- none: 4
219
- };
220
- var LOG_LEVEL_COLORS = {
221
- debug: "\x1B[36m",
222
- info: "\x1B[32m",
223
- warn: "\x1B[33m",
224
- error: "\x1B[31m"
225
- };
226
- var RESET_COLOR = "\x1B[0m";
227
- function isProduction() {
228
- if (typeof process !== "undefined" && process.env) {
229
- return false;
230
- }
231
- return false;
232
- }
233
- var config = {
234
- level: isProduction() ? "error" : "info",
235
- colors: true,
236
- timestamps: false
237
- };
238
- function setLogLevel(level) {
239
- config.level = level;
240
- }
241
- function getLogLevel() {
242
- return config.level;
243
- }
244
- function configureLogger(options) {
245
- config = { ...config, ...options };
246
- }
247
- function enableLogging() {
248
- config.level = "debug";
249
- }
250
- function disableLogging() {
251
- config.level = "none";
252
- }
253
- function setDebugMode(enabled) {
254
- config.level = enabled ? "debug" : "error";
255
- }
256
- function isDebugMode() {
257
- return config.level === "debug";
258
- }
259
- function shouldLog(level) {
260
- return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
261
- }
262
- function formatTag(tag, level) {
263
- const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
264
- if (config.colors && level !== "none") {
265
- const color = LOG_LEVEL_COLORS[level];
266
- return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
267
- }
268
- return `${timestamp}[${tag}]`;
269
- }
270
-
271
- class Logger {
272
- tag;
273
- constructor(tag) {
274
- this.tag = tag;
275
- }
276
- debug(...args) {
277
- if (!shouldLog("debug"))
278
- return;
279
- if (config.handler) {
280
- config.handler.debug(this.tag, ...args);
281
- } else {
282
- console.log(formatTag(this.tag, "debug"), ...args);
283
- }
284
- }
285
- info(...args) {
286
- if (!shouldLog("info"))
287
- return;
288
- if (config.handler) {
289
- config.handler.info(this.tag, ...args);
290
- } else {
291
- console.info(formatTag(this.tag, "info"), ...args);
292
- }
293
- }
294
- warn(...args) {
295
- if (!shouldLog("warn"))
296
- return;
297
- if (config.handler) {
298
- config.handler.warn(this.tag, ...args);
299
- } else {
300
- console.warn(formatTag(this.tag, "warn"), ...args);
301
- }
302
- }
303
- error(...args) {
304
- if (!shouldLog("error"))
305
- return;
306
- if (config.handler) {
307
- config.handler.error(this.tag, ...args);
308
- } else {
309
- console.error(formatTag(this.tag, "error"), ...args);
310
- }
311
- }
312
- time(label, fn) {
313
- if (!shouldLog("debug")) {
314
- return fn();
315
- }
316
- const start = performance.now();
317
- try {
318
- return fn();
319
- } finally {
320
- const duration = performance.now() - start;
321
- this.debug(`${label}: ${duration.toFixed(2)}ms`);
322
- }
323
- }
324
- async timeAsync(label, fn) {
325
- if (!shouldLog("debug")) {
326
- return fn();
327
- }
328
- const start = performance.now();
329
- try {
330
- return await fn();
331
- } finally {
332
- const duration = performance.now() - start;
333
- this.debug(`${label}: ${duration.toFixed(2)}ms`);
334
- }
335
- }
336
- child(subTag) {
337
- return new Logger(`${this.tag}:${subTag}`);
338
- }
339
- debugIf(condition, ...args) {
340
- if (condition)
341
- this.debug(...args);
342
- }
343
- warnIf(condition, ...args) {
344
- if (condition)
345
- this.warn(...args);
346
- }
347
- errorIf(condition, ...args) {
348
- if (condition)
349
- this.error(...args);
350
- }
351
- loggedOnce = new Set;
352
- warnOnce(key, ...args) {
353
- if (this.loggedOnce.has(key))
354
- return;
355
- this.loggedOnce.add(key);
356
- this.warn(...args);
357
- }
358
- debugOnce(key, ...args) {
359
- if (this.loggedOnce.has(key))
360
- return;
361
- this.loggedOnce.add(key);
362
- this.debug(...args);
363
- }
364
- }
365
- function createLogger(tag) {
366
- return new Logger(tag);
367
- }
368
- var logger = createLogger("Hypen");
369
- var log = {
370
- debug: (tag, ...args) => {
371
- if (!shouldLog("debug"))
372
- return;
373
- console.log(formatTag(tag, "debug"), ...args);
374
- },
375
- info: (tag, ...args) => {
376
- if (!shouldLog("info"))
377
- return;
378
- console.info(formatTag(tag, "info"), ...args);
379
- },
380
- warn: (tag, ...args) => {
381
- if (!shouldLog("warn"))
382
- return;
383
- console.warn(formatTag(tag, "warn"), ...args);
384
- },
385
- error: (tag, ...args) => {
386
- if (!shouldLog("error"))
387
- return;
388
- console.error(formatTag(tag, "error"), ...args);
389
- }
390
- };
391
- var frameworkLoggers = {
392
- hypen: createLogger("Hypen"),
393
- engine: createLogger("Engine"),
394
- router: createLogger("Router"),
395
- state: createLogger("State"),
396
- events: createLogger("Events"),
397
- remote: createLogger("Remote"),
398
- renderer: createLogger("Renderer"),
399
- module: createLogger("Module"),
400
- lifecycle: createLogger("Lifecycle"),
401
- loader: createLogger("Loader"),
402
- context: createLogger("Context"),
403
- discovery: createLogger("Discovery"),
404
- plugin: createLogger("Plugin"),
405
- canvas: createLogger("Canvas"),
406
- debug: createLogger("Debug")
407
- };
408
-
409
- // src/disposable.ts
410
- var log2 = frameworkLoggers.lifecycle;
411
- function isDisposable(obj) {
412
- return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
413
- }
414
-
415
- class DisposableStack {
416
- stack = [];
417
- disposed = false;
418
- add(disposable) {
419
- if (this.disposed) {
420
- disposable.dispose();
421
- return disposable;
422
- }
423
- this.stack.push(disposable);
424
- return disposable;
425
- }
426
- addCallback(callback) {
427
- this.add({ dispose: callback });
428
- }
429
- addValue(value, dispose) {
430
- this.add({ dispose: () => dispose(value) });
431
- return value;
432
- }
433
- dispose() {
434
- if (this.disposed)
435
- return;
436
- this.disposed = true;
437
- while (this.stack.length > 0) {
438
- const item = this.stack.pop();
439
- try {
440
- item.dispose();
441
- } catch (error) {
442
- log2.error("Error during dispose:", error);
443
- }
444
- }
445
- }
446
- get isDisposed() {
447
- return this.disposed;
448
- }
449
- get size() {
450
- return this.stack.length;
451
- }
452
- }
453
- function disposableListener(target, event, handler, options) {
454
- target.addEventListener(event, handler, options);
455
- return {
456
- dispose: () => target.removeEventListener(event, handler, options)
457
- };
458
- }
459
- function disposableTimeout(callback, ms) {
460
- const id = setTimeout(callback, ms);
461
- return {
462
- id,
463
- dispose: () => clearTimeout(id)
464
- };
465
- }
466
- function disposableInterval(callback, ms) {
467
- const id = setInterval(callback, ms);
468
- return {
469
- id,
470
- dispose: () => clearInterval(id)
471
- };
472
- }
473
- function disposableWebSocket(ws) {
474
- return {
475
- dispose: () => {
476
- if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
477
- ws.close();
478
- }
479
- }
480
- };
481
- }
482
- function disposableAbortController() {
483
- const controller = new AbortController;
484
- return {
485
- controller,
486
- signal: controller.signal,
487
- dispose: () => controller.abort()
488
- };
489
- }
490
- function disposableSubscription(unsubscribe) {
491
- return { dispose: unsubscribe };
492
- }
493
- var ELEMENT_DISPOSABLES = Symbol("hypen.disposables");
494
- function getElementDisposables(element) {
495
- const existing = element[ELEMENT_DISPOSABLES];
496
- if (existing instanceof DisposableStack) {
497
- return existing;
498
- }
499
- const stack = new DisposableStack;
500
- element[ELEMENT_DISPOSABLES] = stack;
501
- return stack;
502
- }
503
- function disposeElement(element) {
504
- const stack = element[ELEMENT_DISPOSABLES];
505
- if (stack instanceof DisposableStack) {
506
- stack.dispose();
507
- delete element[ELEMENT_DISPOSABLES];
508
- }
509
- }
510
- function hasElementDisposables(element) {
511
- return element[ELEMENT_DISPOSABLES] instanceof DisposableStack;
512
- }
513
-
514
- class DisposableMixin {
515
- disposables = new DisposableStack;
516
- track(disposable) {
517
- return this.disposables.add(disposable);
518
- }
519
- onDispose(callback) {
520
- this.disposables.addCallback(callback);
521
- }
522
- dispose() {
523
- this.disposables.dispose();
524
- }
525
- }
526
- function compositeDisposable(...disposables) {
527
- return {
528
- dispose: () => {
529
- for (const d of disposables) {
530
- try {
531
- d.dispose();
532
- } catch (error) {
533
- log2.error("Error during dispose:", error);
534
- }
535
- }
536
- }
537
- };
538
- }
539
- async function using(resource, fn) {
540
- const r = typeof resource === "function" ? resource() : resource;
541
- try {
542
- return await fn(r);
543
- } finally {
544
- r.dispose();
545
- }
546
- }
547
- function usingSync(resource, fn) {
548
- const r = typeof resource === "function" ? resource() : resource;
549
- try {
550
- return fn(r);
551
- } finally {
552
- r.dispose();
553
- }
554
- }
555
-
556
- // src/retry.ts
557
- var DEFAULT_OPTIONS = {
558
- maxAttempts: 3,
559
- delayMs: 1000,
560
- backoff: "exponential",
561
- maxDelayMs: 30000,
562
- jitter: 0.1
563
- };
564
- function calculateDelay(attempt, options) {
565
- let delay;
566
- switch (options.backoff) {
567
- case "exponential":
568
- delay = options.delayMs * Math.pow(2, attempt - 1);
569
- break;
570
- case "linear":
571
- delay = options.delayMs * attempt;
572
- break;
573
- case "none":
574
- delay = options.delayMs;
575
- break;
576
- }
577
- if (options.jitter > 0) {
578
- const jitterRange = delay * options.jitter;
579
- delay += (Math.random() * 2 - 1) * jitterRange;
580
- }
581
- return Math.min(delay, options.maxDelayMs);
582
- }
583
- function sleep(ms, signal) {
584
- return new Promise((resolve, reject) => {
585
- if (signal?.aborted) {
586
- reject(new Error("Retry aborted"));
587
- return;
588
- }
589
- const timeoutId = setTimeout(resolve, ms);
590
- signal?.addEventListener("abort", () => {
591
- clearTimeout(timeoutId);
592
- reject(new Error("Retry aborted"));
593
- });
594
- });
595
- }
596
- async function retry(fn, options = {}) {
597
- const opts = { ...DEFAULT_OPTIONS, ...options };
598
- let lastError = new Error("No attempts made");
599
- for (let attempt = 1;attempt <= opts.maxAttempts; attempt++) {
600
- try {
601
- if (opts.signal?.aborted) {
602
- throw new Error("Retry aborted");
603
- }
604
- return await fn();
605
- } catch (e) {
606
- lastError = e instanceof Error ? e : new Error(String(e));
607
- if (opts.shouldRetry && !opts.shouldRetry(lastError)) {
608
- throw lastError;
609
- }
610
- if (attempt === opts.maxAttempts) {
611
- break;
612
- }
613
- const delayMs = calculateDelay(attempt, opts);
614
- opts.onRetry?.(attempt, lastError, delayMs);
615
- await sleep(delayMs, opts.signal);
616
- }
617
- }
618
- throw lastError;
619
- }
620
- async function retryResult(fn, options = {}) {
621
- try {
622
- const value = await retry(fn, options);
623
- return Ok(value);
624
- } catch (e) {
625
- return Err(e instanceof Error ? e : new Error(String(e)));
626
- }
627
- }
628
- function withRetry(fn, options = {}) {
629
- return (...args) => retry(() => fn(...args), options);
630
- }
631
- var RetryConditions = {
632
- networkErrors: (error) => {
633
- const message = error.message.toLowerCase();
634
- return message.includes("network") || message.includes("fetch") || message.includes("timeout") || message.includes("econnrefused") || message.includes("econnreset") || message.includes("socket");
635
- },
636
- httpRetryable: (error) => {
637
- const status = error.status;
638
- if (!status)
639
- return false;
640
- return [408, 429, 500, 502, 503, 504].includes(status);
641
- },
642
- websocketErrors: (error) => {
643
- const message = error.message.toLowerCase();
644
- return message.includes("websocket") || message.includes("connection") || message.includes("close");
645
- },
646
- any: (...conditions) => (error) => conditions.some((c) => c(error)),
647
- all: (...conditions) => (error) => conditions.every((c) => c(error))
648
- };
649
- var RetryPresets = {
650
- aggressive: {
651
- maxAttempts: 10,
652
- delayMs: 500,
653
- backoff: "exponential",
654
- maxDelayMs: 60000,
655
- jitter: 0.2
656
- },
657
- conservative: {
658
- maxAttempts: 3,
659
- delayMs: 2000,
660
- backoff: "linear",
661
- maxDelayMs: 1e4,
662
- jitter: 0.1
663
- },
664
- fast: {
665
- maxAttempts: 5,
666
- delayMs: 100,
667
- backoff: "exponential",
668
- maxDelayMs: 2000,
669
- jitter: 0
670
- },
671
- websocket: {
672
- maxAttempts: 10,
673
- delayMs: 1000,
674
- backoff: "exponential",
675
- maxDelayMs: 30000,
676
- jitter: 0.1,
677
- shouldRetry: RetryConditions.websocketErrors
678
- }
679
- };
680
-
681
- // src/remote/client.ts
682
- var log3 = frameworkLoggers.remote;
683
-
684
- class RemoteEngine {
685
- ws = null;
686
- url;
687
- state = "disconnected";
688
- options;
689
- reconnectAttempts = 0;
690
- disposables = new DisposableStack;
691
- reconnectDisposable = null;
692
- currentSessionId = null;
693
- sessionOptions;
694
- patchCallbacks = [];
695
- stateCallbacks = [];
696
- connectionCallbacks = [];
697
- disconnectionCallbacks = [];
698
- errorCallbacks = [];
699
- sessionEstablishedCallbacks = [];
700
- sessionExpiredCallbacks = [];
701
- currentState = null;
702
- currentRevision = 0;
703
- moduleName = "";
704
- navigationDisposable = null;
705
- lastViewValue = null;
706
- handlingPopState = false;
707
- constructor(url, options = {}) {
708
- this.url = url;
709
- const navOpt = options.navigation;
710
- const navigation = navOpt ? {
711
- backAction: (typeof navOpt === "object" ? navOpt.backAction : undefined) ?? "navigateBack",
712
- viewStateKey: (typeof navOpt === "object" ? navOpt.viewStateKey : undefined) ?? "currentView"
713
- } : undefined;
714
- this.options = {
715
- autoReconnect: options.autoReconnect ?? true,
716
- reconnectInterval: options.reconnectInterval ?? 3000,
717
- maxReconnectAttempts: options.maxReconnectAttempts ?? 10,
718
- session: options.session,
719
- navigation
720
- };
721
- this.sessionOptions = options.session;
722
- if (options.session?.id) {
723
- this.currentSessionId = options.session.id;
724
- }
725
- }
726
- async connect() {
727
- if (this.state === "connected" || this.state === "connecting") {
728
- return Ok(undefined);
729
- }
730
- this.state = "connecting";
731
- return new Promise((resolve) => {
732
- try {
733
- this.ws = new WebSocket(this.url);
734
- this.disposables.add(disposableWebSocket(this.ws));
735
- const messageHandler = (event) => {
736
- this.handleMessage(event.data);
737
- };
738
- this.disposables.add(disposableListener(this.ws, "message", messageHandler));
739
- const errorHandler = () => {
740
- this.state = "error";
741
- const error = new ConnectionError(this.url, new Error("WebSocket error"));
742
- this.errorCallbacks.forEach((cb) => cb(error));
743
- resolve(Err(error));
744
- };
745
- this.disposables.add(disposableListener(this.ws, "error", errorHandler));
746
- const closeHandler = () => {
747
- this.state = "disconnected";
748
- this.disconnectionCallbacks.forEach((cb) => cb());
749
- this.attemptReconnect();
750
- };
751
- this.disposables.add(disposableListener(this.ws, "close", closeHandler));
752
- this.ws.onopen = () => {
753
- this.state = "connected";
754
- this.reconnectAttempts = 0;
755
- if (this.reconnectDisposable) {
756
- this.reconnectDisposable.dispose();
757
- this.reconnectDisposable = null;
758
- }
759
- this.sendHello();
760
- this.connectionCallbacks.forEach((cb) => cb());
761
- resolve(Ok(undefined));
762
- };
763
- } catch (e) {
764
- this.state = "error";
765
- const error = new ConnectionError(this.url, e);
766
- resolve(Err(error));
767
- }
768
- });
769
- }
770
- sendHello() {
771
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
772
- return;
773
- const hello = {
774
- type: "hello",
775
- sessionId: this.currentSessionId ?? this.sessionOptions?.id,
776
- props: this.sessionOptions?.props,
777
- persistKey: this.sessionOptions?.persistKey
778
- };
779
- this.ws.send(JSON.stringify(hello));
780
- }
781
- disconnect() {
782
- if (this.reconnectDisposable) {
783
- this.reconnectDisposable.dispose();
784
- this.reconnectDisposable = null;
785
- }
786
- if (this.ws) {
787
- if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {
788
- this.ws.close();
789
- }
790
- this.ws = null;
791
- }
792
- this.state = "disconnected";
793
- }
794
- dispose() {
795
- this.disconnect();
796
- if (this.navigationDisposable) {
797
- this.navigationDisposable.dispose();
798
- this.navigationDisposable = null;
799
- }
800
- this.disposables.dispose();
801
- }
802
- setupNavigation() {
803
- const nav = this.options.navigation;
804
- if (!nav || typeof window === "undefined")
805
- return;
806
- if (this.navigationDisposable)
807
- return;
808
- this.navigationDisposable = disposableListener(window, "popstate", () => {
809
- if (this.handlingPopState)
810
- return;
811
- log3.debug("Back navigation detected, dispatching:", nav.backAction);
812
- this.handlingPopState = true;
813
- this.dispatchAction(nav.backAction);
814
- });
815
- }
816
- trackViewChange(state) {
817
- const nav = this.options.navigation;
818
- if (!nav || typeof window === "undefined")
819
- return;
820
- const viewValue = this.resolveStateKey(state, nav.viewStateKey);
821
- if (viewValue === undefined || viewValue === this.lastViewValue)
822
- return;
823
- if (this.handlingPopState) {
824
- this.handlingPopState = false;
825
- this.lastViewValue = viewValue;
826
- return;
827
- }
828
- if (this.lastViewValue !== null) {
829
- window.history.pushState({ view: viewValue }, "", "");
830
- }
831
- this.lastViewValue = viewValue;
832
- }
833
- resolveStateKey(state, key) {
834
- if (!state || typeof state !== "object")
835
- return;
836
- const parts = key.split(".");
837
- let current = state;
838
- for (const part of parts) {
839
- if (current == null || typeof current !== "object")
840
- return;
841
- current = current[part];
842
- }
843
- return typeof current === "string" ? current : undefined;
844
- }
845
- dispatchAction(action, payload) {
846
- if (this.state !== "connected" || !this.ws) {
847
- log3.warn("Cannot dispatch action: not connected");
848
- return;
849
- }
850
- const message = {
851
- type: "dispatchAction",
852
- module: this.moduleName,
853
- action,
854
- payload
855
- };
856
- this.ws.send(JSON.stringify(message));
857
- }
858
- subscribeState() {
859
- if (this.state !== "connected" || !this.ws) {
860
- log3.warn("Cannot subscribe to state: not connected");
861
- return;
862
- }
863
- const message = { type: "subscribeState" };
864
- this.ws.send(JSON.stringify(message));
865
- }
866
- updateState(state) {
867
- if (this.state !== "connected" || !this.ws) {
868
- log3.warn("Cannot update state: not connected");
869
- return;
870
- }
871
- const message = {
872
- type: "updateState",
873
- module: this.moduleName,
874
- state
875
- };
876
- this.ws.send(JSON.stringify(message));
877
- }
878
- onPatches(callback) {
879
- this.patchCallbacks.push(callback);
880
- return this;
881
- }
882
- onStateUpdate(callback) {
883
- this.stateCallbacks.push(callback);
884
- return this;
885
- }
886
- onConnect(callback) {
887
- this.connectionCallbacks.push(callback);
888
- return this;
889
- }
890
- onDisconnect(callback) {
891
- this.disconnectionCallbacks.push(callback);
892
- return this;
893
- }
894
- onError(callback) {
895
- this.errorCallbacks.push(callback);
896
- return this;
897
- }
898
- onSessionEstablished(callback) {
899
- this.sessionEstablishedCallbacks.push(callback);
900
- return this;
901
- }
902
- onSessionExpired(callback) {
903
- this.sessionExpiredCallbacks.push(callback);
904
- return this;
905
- }
906
- getConnectionState() {
907
- return this.state;
908
- }
909
- getCurrentState() {
910
- return this.currentState;
911
- }
912
- getRevision() {
913
- return this.currentRevision;
914
- }
915
- getSessionId() {
916
- return this.currentSessionId;
917
- }
918
- handleMessage(data) {
919
- try {
920
- const message = JSON.parse(data);
921
- switch (message.type) {
922
- case "sessionAck":
923
- this.handleSessionAck(message);
924
- break;
925
- case "sessionExpired":
926
- this.handleSessionExpired(message);
927
- break;
928
- case "initialTree":
929
- this.handleInitialTree(message);
930
- break;
931
- case "patch":
932
- this.handlePatch(message);
933
- break;
934
- case "stateUpdate":
935
- this.currentState = message.state;
936
- this.trackViewChange(this.currentState);
937
- this.stateCallbacks.forEach((cb) => cb(this.currentState));
938
- break;
939
- }
940
- } catch (e) {
941
- log3.error("Error handling remote message:", e);
942
- const error = e instanceof Error ? e : new Error(String(e));
943
- this.errorCallbacks.forEach((cb) => cb(error));
944
- }
945
- }
946
- handleSessionAck(message) {
947
- this.currentSessionId = message.sessionId;
948
- const info = {
949
- sessionId: message.sessionId,
950
- isNew: message.isNew,
951
- isRestored: message.isRestored
952
- };
953
- this.sessionEstablishedCallbacks.forEach((cb) => cb(info));
954
- }
955
- handleSessionExpired(message) {
956
- this.currentSessionId = null;
957
- this.sessionExpiredCallbacks.forEach((cb) => cb(message.reason));
958
- }
959
- handleInitialTree(message) {
960
- this.moduleName = message.module;
961
- this.currentState = message.state;
962
- this.currentRevision = message.revision;
963
- if (message.patches.length > 0) {
964
- this.patchCallbacks.forEach((cb) => cb(message.patches));
965
- }
966
- this.trackViewChange(message.state);
967
- this.setupNavigation();
968
- if (this.options.navigation) {
969
- this.subscribeState();
970
- }
971
- this.stateCallbacks.forEach((cb) => cb(message.state));
972
- }
973
- handlePatch(message) {
974
- if (message.revision <= this.currentRevision) {
975
- log3.warn(`Out of order patch: expected > ${this.currentRevision}, got ${message.revision}`);
976
- return;
977
- }
978
- this.currentRevision = message.revision;
979
- if (message.patches.length > 0) {
980
- this.patchCallbacks.forEach((cb) => cb(message.patches));
981
- }
982
- }
983
- attemptReconnect() {
984
- if (!this.options.autoReconnect) {
985
- return;
986
- }
987
- this.reconnectDisposable = disposableTimeout(() => {
988
- this.reconnectDisposable = null;
989
- retry(async () => {
990
- const result = await this.connect();
991
- if (!result.ok) {
992
- throw result.error;
993
- }
994
- }, {
995
- maxAttempts: this.options.maxReconnectAttempts,
996
- delayMs: this.options.reconnectInterval,
997
- backoff: "exponential",
998
- maxDelayMs: 30000,
999
- jitter: 0.1,
1000
- onRetry: (attempt, error) => {
1001
- log3.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
1002
- }
1003
- }).catch((error) => {
1004
- log3.error("Max reconnection attempts reached:", error.message);
1005
- this.errorCallbacks.forEach((cb) => cb(new ConnectionError(this.url, error, this.options.maxReconnectAttempts)));
1006
- });
1007
- }, this.options.reconnectInterval);
1008
- }
1009
- }
1
+ import {
2
+ RemoteEngine
3
+ } from "../chunk-g7g3jxty.js";
4
+ import"../chunk-g2gz9pgg.js";
5
+ import"../chunk-ec0tgy9a.js";
6
+ import"../chunk-7222131a.js";
7
+ import"../chunk-avchpwhf.js";
8
+ import"../chunk-5gtx3pza.js";
1010
9
  export {
1011
10
  RemoteEngine
1012
11
  };
1013
12
 
1014
- //# debugId=7CE0CEEA482DB8C464756E2164756E21
13
+ //# debugId=BA4CEBABB9B7D50364756E2164756E21