@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
package/dist/app.js CHANGED
@@ -1,1170 +1,15 @@
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/datasource.ts
213
- class DataSourceManager {
214
- plugins = new Map;
215
- configs = new Map;
216
- state = new Map;
217
- engine;
218
- constructor(engine) {
219
- this.engine = engine;
220
- }
221
- async use(plugin, config) {
222
- const { name } = plugin;
223
- this.state.set(name, {});
224
- this.plugins.set(name, plugin);
225
- this.configs.set(name, config);
226
- await plugin.connect(config, (change) => {
227
- const current = this.state.get(name) ?? {};
228
- for (const path of change.paths) {
229
- if (path in change.values) {
230
- current[path] = change.values[path];
231
- }
232
- }
233
- this.state.set(name, current);
234
- this.engine.setContext(name, current);
235
- });
236
- }
237
- get(name) {
238
- return this.plugins.get(name);
239
- }
240
- has(name) {
241
- return this.plugins.has(name);
242
- }
243
- getNames() {
244
- return Array.from(this.plugins.keys());
245
- }
246
- getStatus(name) {
247
- return this.plugins.get(name)?.status;
248
- }
249
- async remove(name) {
250
- const plugin = this.plugins.get(name);
251
- if (plugin) {
252
- await plugin.disconnect();
253
- this.plugins.delete(name);
254
- this.configs.delete(name);
255
- this.state.delete(name);
256
- this.engine.removeContext(name);
257
- }
258
- }
259
- async disconnectAll() {
260
- const names = Array.from(this.plugins.keys());
261
- await Promise.all(names.map((name) => this.remove(name)));
262
- }
263
- }
264
-
265
- // src/portable.ts
266
- function notInstalled(name) {
267
- throw new Error(`[@hypen-space/core] Portable helper "${name}" called before the engine was installed. ` + `Import @hypen-space/server, @hypen-space/web-engine, or call setPortableImpl() before use.`);
268
- }
269
- var current = {
270
- diffState: () => notInstalled("diffState"),
271
- matchPath: () => notInstalled("matchPath"),
272
- pathGet: () => notInstalled("pathGet"),
273
- pathHas: () => notInstalled("pathHas"),
274
- pathSet: () => notInstalled("pathSet"),
275
- pathDelete: () => notInstalled("pathDelete"),
276
- encodeUriComponent: () => notInstalled("encodeUriComponent"),
277
- decodeUriComponent: () => notInstalled("decodeUriComponent"),
278
- parseQuery: () => notInstalled("parseQuery"),
279
- buildUrl: () => notInstalled("buildUrl")
280
- };
281
- function setPortableImpl(impl) {
282
- if (impl === null) {
283
- current = {
284
- diffState: () => notInstalled("diffState"),
285
- matchPath: () => notInstalled("matchPath"),
286
- pathGet: () => notInstalled("pathGet"),
287
- pathHas: () => notInstalled("pathHas"),
288
- pathSet: () => notInstalled("pathSet"),
289
- pathDelete: () => notInstalled("pathDelete"),
290
- encodeUriComponent: () => notInstalled("encodeUriComponent"),
291
- decodeUriComponent: () => notInstalled("decodeUriComponent"),
292
- parseQuery: () => notInstalled("parseQuery"),
293
- buildUrl: () => notInstalled("buildUrl")
294
- };
295
- return;
296
- }
297
- current = impl;
298
- }
299
- var portable = {
300
- diffState: (o, n, b) => current.diffState(o, n, b),
301
- matchPath: (p, path) => current.matchPath(p, path),
302
- pathGet: (v, p) => current.pathGet(v, p),
303
- pathHas: (v, p) => current.pathHas(v, p),
304
- pathSet: (v, p, nv) => current.pathSet(v, p, nv),
305
- pathDelete: (v, p) => current.pathDelete(v, p),
306
- encodeUriComponent: (s) => current.encodeUriComponent(s),
307
- decodeUriComponent: (s) => current.decodeUriComponent(s),
308
- parseQuery: (f) => current.parseQuery(f),
309
- buildUrl: (p, q) => current.buildUrl(p, q)
310
- };
311
-
312
- // src/state.ts
313
- var IS_PROXY = Symbol.for("hypen.isProxy");
314
- var RAW_TARGET = Symbol.for("hypen.rawTarget");
315
- function deepClone(obj) {
316
- if (obj === null || typeof obj !== "object") {
317
- return obj;
318
- }
319
- if (typeof obj === "function") {
320
- return obj;
321
- }
322
- if (typeof obj.__getSnapshot === "function") {
323
- return obj.__getSnapshot();
324
- }
325
- if (obj instanceof WeakMap || obj instanceof WeakSet) {
326
- return obj;
327
- }
328
- const visited = new WeakMap;
329
- function cloneInternal(value) {
330
- if (value === null || typeof value !== "object") {
331
- return value;
332
- }
333
- if (typeof value === "function") {
334
- return value;
335
- }
336
- if (visited.has(value)) {
337
- return visited.get(value);
338
- }
339
- if (value instanceof WeakMap || value instanceof WeakSet) {
340
- return value;
341
- }
342
- if (value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
343
- try {
344
- return structuredClone(value);
345
- } catch {}
346
- }
347
- if (Array.isArray(value)) {
348
- const arrClone = [];
349
- visited.set(value, arrClone);
350
- for (let i = 0;i < value.length; i++) {
351
- arrClone[i] = cloneInternal(value[i]);
352
- }
353
- return arrClone;
354
- }
355
- const objClone = {};
356
- visited.set(value, objClone);
357
- for (const key in value) {
358
- if (Object.prototype.hasOwnProperty.call(value, key)) {
359
- objClone[key] = cloneInternal(value[key]);
360
- }
361
- }
362
- const symbolKeys = Object.getOwnPropertySymbols(value);
363
- for (const sym of symbolKeys) {
364
- objClone[sym] = cloneInternal(value[sym]);
365
- }
366
- return objClone;
367
- }
368
- return cloneInternal(obj);
369
- }
370
- function diffState(oldState, newState, basePath = "") {
371
- return portable.diffState(oldState, newState, basePath);
372
- }
373
- function createObservableState(initialState, options) {
374
- const opts = options || { onChange: () => {} };
375
- if (initialState === null || initialState === undefined) {
376
- initialState = {};
377
- }
378
- if (initialState instanceof Number || initialState instanceof String || initialState instanceof Boolean) {
379
- throw new TypeError("Cannot create observable state from primitive wrapper objects (Number, String, Boolean). " + "Use plain primitives or regular objects instead.");
380
- }
381
- initialState = deepClone(initialState);
382
- let lastSnapshot = deepClone(initialState);
383
- const pathPrefix = opts.pathPrefix || "";
384
- let batchDepth = 0;
385
- let pendingChange = null;
386
- function notifyChange() {
387
- if (batchDepth > 0)
388
- return;
389
- const change = diffState(lastSnapshot, state, pathPrefix);
390
- if (change.paths.length > 0) {
391
- lastSnapshot = deepClone(state);
392
- if (pendingChange) {
393
- change.paths.push(...pendingChange.paths);
394
- Object.assign(change.newValues, pendingChange.newValues);
395
- pendingChange = null;
396
- }
397
- opts.onChange(change);
398
- }
399
- }
400
- let notificationPending = false;
401
- function scheduleBatch() {
402
- if (batchDepth === 0) {
403
- if (!notificationPending) {
404
- notificationPending = true;
405
- queueMicrotask(() => {
406
- notificationPending = false;
407
- if (batchDepth === 0) {
408
- notifyChange();
409
- } else {}
410
- });
411
- }
412
- } else {
413
- pendingChange = pendingChange || { paths: [], newValues: {} };
414
- }
415
- }
416
- const proxyCache = new WeakMap;
417
- function createProxy(target, basePath) {
418
- const cached = proxyCache.get(target);
419
- if (cached)
420
- return cached;
421
- const proxy = new Proxy(target, {
422
- get(obj, prop) {
423
- if (prop === IS_PROXY)
424
- return true;
425
- if (prop === RAW_TARGET)
426
- return obj;
427
- if (prop === "__beginBatch") {
428
- return () => {
429
- batchDepth++;
430
- };
431
- }
432
- if (prop === "__endBatch") {
433
- return () => {
434
- batchDepth--;
435
- if (batchDepth === 0) {
436
- notifyChange();
437
- }
438
- };
439
- }
440
- if (prop === "__getSnapshot") {
441
- return () => deepClone(obj);
442
- }
443
- const value = obj[prop];
444
- if (value && typeof value === "object") {
445
- if (value[IS_PROXY]) {
446
- return value;
447
- }
448
- if (value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet) {
449
- return value;
450
- }
451
- const cachedNested = proxyCache.get(value);
452
- if (cachedNested) {
453
- return cachedNested;
454
- }
455
- const nestedProxy = createProxy(value, basePath ? `${basePath}.${String(prop)}` : String(prop));
456
- return nestedProxy;
457
- }
458
- return value;
459
- },
460
- set(obj, prop, value) {
461
- const oldValue = obj[prop];
462
- if (value && typeof value === "object" && value[IS_PROXY]) {
463
- value = value[RAW_TARGET];
464
- }
465
- obj[prop] = value;
466
- if (oldValue !== value) {
467
- scheduleBatch();
468
- }
469
- return true;
470
- },
471
- deleteProperty(obj, prop) {
472
- const existed = Object.prototype.hasOwnProperty.call(obj, prop);
473
- const result = delete obj[prop];
474
- if (existed) {
475
- scheduleBatch();
476
- }
477
- return result;
478
- }
479
- });
480
- proxyCache.set(target, proxy);
481
- return proxy;
482
- }
483
- const state = createProxy(initialState, pathPrefix);
484
- return state;
485
- }
486
- function batchStateUpdates(state, fn) {
487
- const s = state;
488
- if (s.__beginBatch && s.__endBatch) {
489
- s.__beginBatch();
490
- try {
491
- fn();
492
- } finally {
493
- s.__endBatch();
494
- }
495
- } else {
496
- fn();
497
- }
498
- }
499
- function getStateSnapshot(state) {
500
- const s = state;
501
- if (s.__getSnapshot) {
502
- return s.__getSnapshot();
503
- }
504
- return deepClone(state);
505
- }
506
- function isStateProxy(value) {
507
- return value !== null && typeof value === "object" && value[IS_PROXY] === true;
508
- }
509
- function unwrapProxy(value) {
510
- if (value !== null && typeof value === "object" && value[IS_PROXY]) {
511
- return value[RAW_TARGET];
512
- }
513
- return value;
514
- }
515
-
516
- // src/logger.ts
517
- var LOG_LEVEL_ORDER = {
518
- debug: 0,
519
- info: 1,
520
- warn: 2,
521
- error: 3,
522
- none: 4
523
- };
524
- var LOG_LEVEL_COLORS = {
525
- debug: "\x1B[36m",
526
- info: "\x1B[32m",
527
- warn: "\x1B[33m",
528
- error: "\x1B[31m"
529
- };
530
- var RESET_COLOR = "\x1B[0m";
531
- function isProduction() {
532
- if (typeof process !== "undefined" && process.env) {
533
- return false;
534
- }
535
- return false;
536
- }
537
- var config = {
538
- level: isProduction() ? "error" : "info",
539
- colors: true,
540
- timestamps: false
541
- };
542
- function setLogLevel(level) {
543
- config.level = level;
544
- }
545
- function getLogLevel() {
546
- return config.level;
547
- }
548
- function configureLogger(options) {
549
- config = { ...config, ...options };
550
- }
551
- function enableLogging() {
552
- config.level = "debug";
553
- }
554
- function disableLogging() {
555
- config.level = "none";
556
- }
557
- function setDebugMode(enabled) {
558
- config.level = enabled ? "debug" : "error";
559
- }
560
- function isDebugMode() {
561
- return config.level === "debug";
562
- }
563
- function shouldLog(level) {
564
- return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
565
- }
566
- function formatTag(tag, level) {
567
- const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
568
- if (config.colors && level !== "none") {
569
- const color = LOG_LEVEL_COLORS[level];
570
- return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
571
- }
572
- return `${timestamp}[${tag}]`;
573
- }
574
-
575
- class Logger {
576
- tag;
577
- constructor(tag) {
578
- this.tag = tag;
579
- }
580
- debug(...args) {
581
- if (!shouldLog("debug"))
582
- return;
583
- if (config.handler) {
584
- config.handler.debug(this.tag, ...args);
585
- } else {
586
- console.log(formatTag(this.tag, "debug"), ...args);
587
- }
588
- }
589
- info(...args) {
590
- if (!shouldLog("info"))
591
- return;
592
- if (config.handler) {
593
- config.handler.info(this.tag, ...args);
594
- } else {
595
- console.info(formatTag(this.tag, "info"), ...args);
596
- }
597
- }
598
- warn(...args) {
599
- if (!shouldLog("warn"))
600
- return;
601
- if (config.handler) {
602
- config.handler.warn(this.tag, ...args);
603
- } else {
604
- console.warn(formatTag(this.tag, "warn"), ...args);
605
- }
606
- }
607
- error(...args) {
608
- if (!shouldLog("error"))
609
- return;
610
- if (config.handler) {
611
- config.handler.error(this.tag, ...args);
612
- } else {
613
- console.error(formatTag(this.tag, "error"), ...args);
614
- }
615
- }
616
- time(label, fn) {
617
- if (!shouldLog("debug")) {
618
- return fn();
619
- }
620
- const start = performance.now();
621
- try {
622
- return fn();
623
- } finally {
624
- const duration = performance.now() - start;
625
- this.debug(`${label}: ${duration.toFixed(2)}ms`);
626
- }
627
- }
628
- async timeAsync(label, fn) {
629
- if (!shouldLog("debug")) {
630
- return fn();
631
- }
632
- const start = performance.now();
633
- try {
634
- return await fn();
635
- } finally {
636
- const duration = performance.now() - start;
637
- this.debug(`${label}: ${duration.toFixed(2)}ms`);
638
- }
639
- }
640
- child(subTag) {
641
- return new Logger(`${this.tag}:${subTag}`);
642
- }
643
- debugIf(condition, ...args) {
644
- if (condition)
645
- this.debug(...args);
646
- }
647
- warnIf(condition, ...args) {
648
- if (condition)
649
- this.warn(...args);
650
- }
651
- errorIf(condition, ...args) {
652
- if (condition)
653
- this.error(...args);
654
- }
655
- loggedOnce = new Set;
656
- warnOnce(key, ...args) {
657
- if (this.loggedOnce.has(key))
658
- return;
659
- this.loggedOnce.add(key);
660
- this.warn(...args);
661
- }
662
- debugOnce(key, ...args) {
663
- if (this.loggedOnce.has(key))
664
- return;
665
- this.loggedOnce.add(key);
666
- this.debug(...args);
667
- }
668
- }
669
- function createLogger(tag) {
670
- return new Logger(tag);
671
- }
672
- var logger = createLogger("Hypen");
673
- var log = {
674
- debug: (tag, ...args) => {
675
- if (!shouldLog("debug"))
676
- return;
677
- console.log(formatTag(tag, "debug"), ...args);
678
- },
679
- info: (tag, ...args) => {
680
- if (!shouldLog("info"))
681
- return;
682
- console.info(formatTag(tag, "info"), ...args);
683
- },
684
- warn: (tag, ...args) => {
685
- if (!shouldLog("warn"))
686
- return;
687
- console.warn(formatTag(tag, "warn"), ...args);
688
- },
689
- error: (tag, ...args) => {
690
- if (!shouldLog("error"))
691
- return;
692
- console.error(formatTag(tag, "error"), ...args);
693
- }
694
- };
695
- var frameworkLoggers = {
696
- hypen: createLogger("Hypen"),
697
- engine: createLogger("Engine"),
698
- router: createLogger("Router"),
699
- state: createLogger("State"),
700
- events: createLogger("Events"),
701
- remote: createLogger("Remote"),
702
- renderer: createLogger("Renderer"),
703
- module: createLogger("Module"),
704
- lifecycle: createLogger("Lifecycle"),
705
- loader: createLogger("Loader"),
706
- context: createLogger("Context"),
707
- discovery: createLogger("Discovery"),
708
- plugin: createLogger("Plugin"),
709
- canvas: createLogger("Canvas"),
710
- debug: createLogger("Debug")
711
- };
712
-
713
- // src/app.ts
714
- var log2 = createLogger("ModuleInstance");
715
-
716
- class HypenAppBuilder {
717
- initialState;
718
- options;
719
- createdHandler;
720
- activatedHandler;
721
- deactivatedHandler;
722
- actionHandlers = new Map;
723
- destroyedHandler;
724
- disconnectHandler;
725
- reconnectHandler;
726
- expireHandler;
727
- errorHandler;
728
- template;
729
- _registry;
730
- dataSourceEntries = [];
731
- _stateStore;
732
- constructor(initialState, options, registry) {
733
- this.initialState = initialState;
734
- this.options = options || {};
735
- this._registry = registry;
736
- }
737
- onCreated(fn) {
738
- this.createdHandler = fn;
739
- return this;
740
- }
741
- onAction(name, fn) {
742
- this.actionHandlers.set(name, fn);
743
- return this;
744
- }
745
- onActivated(fn) {
746
- this.activatedHandler = fn;
747
- return this;
748
- }
749
- onDeactivated(fn) {
750
- this.deactivatedHandler = fn;
751
- return this;
752
- }
753
- onDestroyed(fn) {
754
- this.destroyedHandler = fn;
755
- return this;
756
- }
757
- onDisconnect(fn) {
758
- this.disconnectHandler = fn;
759
- return this;
760
- }
761
- onReconnect(fn) {
762
- this.reconnectHandler = fn;
763
- return this;
764
- }
765
- onExpire(fn) {
766
- this.expireHandler = fn;
767
- return this;
768
- }
769
- onError(fn) {
770
- this.errorHandler = fn;
771
- return this;
772
- }
773
- persist(store) {
774
- this._stateStore = store;
775
- return this;
776
- }
777
- useDataSource(plugin, config2) {
778
- this.dataSourceEntries.push({ plugin, config: config2 });
779
- return this;
780
- }
781
- ui(template) {
782
- this.template = template;
783
- return this.build();
784
- }
785
- uiFile(path) {
786
- const fs = (() => ({}));
787
- this.template = fs.readFileSync(path, "utf-8").trim();
788
- return this.build();
789
- }
790
- build() {
791
- const stateKeys = this.initialState !== null && typeof this.initialState === "object" ? Object.keys(this.initialState) : [];
792
- const definition = {
793
- name: this.options.name,
794
- actions: Array.from(this.actionHandlers.keys()),
795
- stateKeys,
796
- persist: this.options.persist,
797
- version: this.options.version,
798
- initialState: this.initialState,
799
- template: this.template,
800
- dataSources: this.dataSourceEntries.length > 0 ? this.dataSourceEntries : undefined,
801
- stateStore: this._stateStore,
802
- handlers: {
803
- onCreated: this.createdHandler,
804
- onActivated: this.activatedHandler,
805
- onDeactivated: this.deactivatedHandler,
806
- onAction: this.actionHandlers,
807
- onDestroyed: this.destroyedHandler,
808
- onDisconnect: this.disconnectHandler,
809
- onReconnect: this.reconnectHandler,
810
- onExpire: this.expireHandler,
811
- onError: this.errorHandler
812
- }
813
- };
814
- if (this.options.name && this._registry) {
815
- this._registry.set(this.options.name, definition);
816
- }
817
- return definition;
818
- }
819
- }
820
-
821
- class HypenApp {
822
- _registry = new Map;
823
- defineState(initial, options) {
824
- return new HypenAppBuilder(initial, options, this._registry);
825
- }
826
- module(name) {
827
- const registry = this._registry;
828
- return {
829
- defineState: (initial, options) => {
830
- return new HypenAppBuilder(initial, { ...options, name }, registry);
831
- }
832
- };
833
- }
834
- get(name) {
835
- return this._registry.get(name);
836
- }
837
- has(name) {
838
- return this._registry.has(name);
839
- }
840
- get components() {
841
- return this._registry;
842
- }
843
- getNames() {
844
- return Array.from(this._registry.keys());
845
- }
846
- get size() {
847
- return this._registry.size;
848
- }
849
- unregister(name) {
850
- this._registry.delete(name);
851
- }
852
- clear() {
853
- this._registry.clear();
854
- }
855
- }
856
- var app = new HypenApp;
857
-
858
- class HypenModuleInstance {
859
- engine;
860
- definition;
861
- state;
862
- isDestroyed = false;
863
- isActive = false;
864
- router;
865
- globalContext;
866
- stateChangeCallbacks = [];
867
- dataSourceManager;
868
- dataSourceAccessor = {};
869
- stateStore;
870
- currentPersistKey = null;
871
- persistDebounceTimer;
872
- sessionId;
873
- moduleKey = "";
874
- constructor(engine, definition, router, globalContext, sessionId) {
875
- this.engine = engine;
876
- this.definition = definition;
877
- this.router = router ?? null;
878
- this.globalContext = globalContext;
879
- this.sessionId = sessionId ?? crypto.randomUUID();
880
- this.stateStore = definition.stateStore;
881
- const moduleKey = (definition.name || "").toLowerCase();
882
- this.moduleKey = moduleKey;
883
- this.state = createObservableState(definition.initialState, {
884
- onChange: (change) => {
885
- this.engine.updateStateSparse(moduleKey || null, change.paths, change.newValues);
886
- this.stateChangeCallbacks.forEach((cb) => cb());
887
- this.persistIfNeeded();
888
- }
889
- });
890
- const snapshot = getStateSnapshot(this.state);
891
- if (moduleKey) {
892
- this.engine.registerModule(moduleKey, definition.actions, definition.stateKeys, snapshot);
893
- } else {
894
- this.engine.setModule("AnonymousModule", definition.actions, definition.stateKeys, snapshot);
895
- }
896
- for (const [actionName, handler] of definition.handlers.onAction) {
897
- log2.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
898
- this.engine.onAction(actionName, async (action) => {
899
- log2.debug(`Action handler fired: ${actionName}`, action);
900
- const actionCtx = {
901
- name: action.name,
902
- payload: action.payload,
903
- sender: action.sender
904
- };
905
- const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
906
- const result = await this.executeAction(actionName, handler, {
907
- action: actionCtx,
908
- state: this.state,
909
- context,
910
- dataSources: this.dataSourceAccessor
911
- });
912
- if (!result.ok) {
913
- const shouldRethrow = await this.handleError(result.error, { actionName });
914
- if (shouldRethrow) {
915
- throw result.error;
916
- }
917
- } else {
918
- log2.debug(`Action handler completed: ${actionName}`);
919
- }
920
- });
921
- }
922
- this.engine.onAction("__hypen_bind", (action) => {
923
- const payload = action.payload;
924
- if (!payload?.path)
925
- return;
926
- const segments = payload.path.split(".");
927
- let target = this.state;
928
- for (let i = 0;i < segments.length - 1; i++) {
929
- const seg = segments[i];
930
- target = target?.[seg];
931
- if (target == null)
932
- return;
933
- }
934
- const lastSeg = segments[segments.length - 1];
935
- target[lastSeg] = payload.value;
936
- });
937
- this._readyPromise = this.callCreatedHandler();
938
- }
939
- _readyPromise = Promise.resolve();
940
- async waitForReady() {
941
- await this._readyPromise;
942
- }
943
- async activate() {
944
- if (this.isDestroyed || this.isActive)
945
- return;
946
- await this._readyPromise;
947
- if (this.isDestroyed || this.isActive)
948
- return;
949
- this.isActive = true;
950
- if (this.definition.handlers.onActivated) {
951
- const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
952
- try {
953
- await this.definition.handlers.onActivated(this.state, context);
954
- } catch (e) {
955
- const error = e instanceof HypenError ? e : new ActionError("onActivated", e);
956
- const shouldRethrow = await this.handleError(error, { lifecycle: "activated" });
957
- if (shouldRethrow) {
958
- throw error;
959
- }
960
- }
961
- }
962
- }
963
- async deactivate() {
964
- if (this.isDestroyed || !this.isActive)
965
- return;
966
- this.isActive = false;
967
- if (this.definition.handlers.onDeactivated) {
968
- const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
969
- try {
970
- await this.definition.handlers.onDeactivated(this.state, context);
971
- } catch (e) {
972
- const error = e instanceof HypenError ? e : new ActionError("onDeactivated", e);
973
- const shouldRethrow = await this.handleError(error, { lifecycle: "deactivated" });
974
- if (shouldRethrow) {
975
- throw error;
976
- }
977
- }
978
- }
979
- }
980
- createGlobalContextAPI() {
981
- if (!this.globalContext) {
982
- throw new Error("Global context not available");
983
- }
984
- const ctx = this.globalContext;
985
- const api = {
986
- getModule: (id) => ctx.getModule(id),
987
- hasModule: (id) => ctx.hasModule(id),
988
- getModuleIds: () => ctx.getModuleIds(),
989
- getGlobalState: () => ctx.getGlobalState(),
990
- emit: (event, payload) => ctx.emit(event, payload),
991
- on: (event, handler) => ctx.on(event, handler),
992
- router: this.router
993
- };
994
- const ctxRecord = ctx;
995
- if (ctxRecord.__hypenEngine) {
996
- api.__hypenEngine = ctxRecord.__hypenEngine;
997
- }
998
- return api;
999
- }
1000
- async executeAction(actionName, handler, ctx) {
1001
- try {
1002
- const result = handler(ctx);
1003
- await result;
1004
- return Ok(undefined);
1005
- } catch (e) {
1006
- return Err(new ActionError(actionName, e));
1007
- }
1008
- }
1009
- async handleError(error, context) {
1010
- const errorCtx = {
1011
- error,
1012
- state: this.state,
1013
- actionName: context.actionName,
1014
- lifecycle: context.lifecycle
1015
- };
1016
- if (this.definition.handlers.onError) {
1017
- try {
1018
- const result = await this.definition.handlers.onError(errorCtx);
1019
- if (result && typeof result === "object") {
1020
- if ("handled" in result && result.handled) {
1021
- return false;
1022
- }
1023
- if ("rethrow" in result && result.rethrow) {
1024
- return true;
1025
- }
1026
- }
1027
- } catch (handlerError) {
1028
- log2.error("Error in onError handler:", handlerError);
1029
- }
1030
- }
1031
- if (this.globalContext) {
1032
- const eventContext = context.actionName ? `action:${context.actionName}` : context.lifecycle ? `lifecycle:${context.lifecycle}` : "unknown";
1033
- this.globalContext.emit("error", {
1034
- message: error.message,
1035
- error,
1036
- context: eventContext
1037
- });
1038
- }
1039
- log2.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
1040
- return false;
1041
- }
1042
- persistIfNeeded() {
1043
- if (!this.stateStore)
1044
- return;
1045
- const store = this.stateStore;
1046
- const newKey = store.resolveKey(this.state, this.definition.name || "AnonymousModule", this.sessionId);
1047
- if (newKey && !this.currentPersistKey) {
1048
- this.activatePersistence(newKey);
1049
- return;
1050
- }
1051
- if (!newKey && this.currentPersistKey) {
1052
- this.currentPersistKey = null;
1053
- return;
1054
- }
1055
- if (newKey && newKey !== this.currentPersistKey) {
1056
- this.activatePersistence(newKey);
1057
- return;
1058
- }
1059
- if (!this.currentPersistKey)
1060
- return;
1061
- clearTimeout(this.persistDebounceTimer);
1062
- this.persistDebounceTimer = setTimeout(() => {
1063
- const snapshot = getStateSnapshot(this.state);
1064
- store.save(this.currentPersistKey, snapshot);
1065
- }, 50);
1066
- }
1067
- async activatePersistence(key) {
1068
- this.currentPersistKey = key;
1069
- const stored = await this.stateStore.load(key);
1070
- if (stored) {
1071
- const merged = { ...this.definition.initialState, ...stored };
1072
- Object.assign(this.state, merged);
1073
- } else {
1074
- const snapshot = getStateSnapshot(this.state);
1075
- await this.stateStore.save(key, snapshot);
1076
- }
1077
- }
1078
- async callCreatedHandler() {
1079
- if (this.stateStore) {
1080
- const key = this.stateStore.resolveKey(this.state, this.definition.name || "AnonymousModule", this.sessionId);
1081
- if (key) {
1082
- this.currentPersistKey = key;
1083
- const stored = await this.stateStore.load(key);
1084
- if (stored) {
1085
- const merged = { ...this.definition.initialState, ...stored };
1086
- Object.assign(this.state, merged);
1087
- }
1088
- }
1089
- }
1090
- if (this.definition.dataSources?.length) {
1091
- const dsEngine = this.engine;
1092
- this.dataSourceManager = new DataSourceManager(dsEngine);
1093
- for (const { plugin, config: config2 } of this.definition.dataSources) {
1094
- try {
1095
- await this.dataSourceManager.use(plugin, config2);
1096
- this.dataSourceAccessor[plugin.name] = new Proxy(plugin, {
1097
- get(target, prop) {
1098
- if (typeof prop === "string" && !(prop in target)) {
1099
- return (...args) => target.call(prop, ...args);
1100
- }
1101
- return target[prop];
1102
- }
1103
- });
1104
- } catch (e) {
1105
- log2.error(`Failed to connect data source "${plugin.name}":`, e);
1106
- }
1107
- }
1108
- }
1109
- if (this.definition.handlers.onCreated) {
1110
- const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
1111
- try {
1112
- await this.definition.handlers.onCreated(this.state, context);
1113
- } catch (e) {
1114
- const error = e instanceof HypenError ? e : new ActionError("onCreated", e);
1115
- const shouldRethrow = await this.handleError(error, { lifecycle: "created" });
1116
- if (shouldRethrow) {
1117
- throw error;
1118
- }
1119
- }
1120
- }
1121
- }
1122
- onStateChange(callback) {
1123
- this.stateChangeCallbacks.push(callback);
1124
- }
1125
- async destroy() {
1126
- if (this.isDestroyed)
1127
- return;
1128
- if (this.isActive) {
1129
- await this.deactivate();
1130
- }
1131
- if (this.currentPersistKey && this.stateStore) {
1132
- clearTimeout(this.persistDebounceTimer);
1133
- const snapshot = getStateSnapshot(this.state);
1134
- await this.stateStore.save(this.currentPersistKey, snapshot);
1135
- }
1136
- if (this.dataSourceManager) {
1137
- try {
1138
- await this.dataSourceManager.disconnectAll();
1139
- } catch (e) {
1140
- log2.error("Error disconnecting data sources:", e);
1141
- }
1142
- this.dataSourceManager = undefined;
1143
- this.dataSourceAccessor = {};
1144
- }
1145
- if (this.definition.handlers.onDestroyed) {
1146
- try {
1147
- await this.definition.handlers.onDestroyed(this.state);
1148
- } catch (e) {
1149
- const error = e instanceof HypenError ? e : new ActionError("onDestroyed", e);
1150
- const shouldRethrow = await this.handleError(error, { lifecycle: "destroyed" });
1151
- if (shouldRethrow) {
1152
- throw error;
1153
- }
1154
- }
1155
- }
1156
- this.isDestroyed = true;
1157
- }
1158
- getState() {
1159
- return getStateSnapshot(this.state);
1160
- }
1161
- getLiveState() {
1162
- return this.state;
1163
- }
1164
- updateState(patch) {
1165
- Object.assign(this.state, patch);
1166
- }
1167
- }
1
+ import {
2
+ HypenApp,
3
+ HypenAppBuilder,
4
+ HypenModuleInstance,
5
+ app
6
+ } from "./chunk-fnss4dm2.js";
7
+ import"./chunk-vshdk2pw.js";
8
+ import"./chunk-7222131a.js";
9
+ import"./chunk-ycxp4drd.js";
10
+ import"./chunk-g830re2c.js";
11
+ import"./chunk-avchpwhf.js";
12
+ import"./chunk-5gtx3pza.js";
1168
13
  export {
1169
14
  app,
1170
15
  HypenModuleInstance,
@@ -1172,4 +17,4 @@ export {
1172
17
  HypenApp
1173
18
  };
1174
19
 
1175
- //# debugId=AA33473FE7991F3B64756E2164756E21
20
+ //# debugId=81E83498A0F80F4464756E2164756E21