@hypen-space/core 0.4.956 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -8
- package/dist/app.js +13 -1168
- package/dist/app.js.map +3 -9
- package/dist/chunk-00zt3w6e.js +58 -0
- package/dist/chunk-00zt3w6e.js.map +10 -0
- package/dist/chunk-3zvyth50.js +87 -0
- package/dist/chunk-3zvyth50.js.map +10 -0
- package/dist/chunk-5gtx3pza.js +11 -0
- package/dist/chunk-5gtx3pza.js.map +9 -0
- package/dist/chunk-7222131a.js +191 -0
- package/dist/chunk-7222131a.js.map +10 -0
- package/dist/chunk-avchpwhf.js +200 -0
- package/dist/chunk-avchpwhf.js.map +10 -0
- package/dist/chunk-ec0tgy9a.js +154 -0
- package/dist/chunk-ec0tgy9a.js.map +10 -0
- package/dist/chunk-fnss4dm2.js +479 -0
- package/dist/chunk-fnss4dm2.js.map +10 -0
- package/dist/chunk-g2gz9pgg.js +133 -0
- package/dist/chunk-g2gz9pgg.js.map +10 -0
- package/dist/chunk-g72v6mmf.js +341 -0
- package/dist/chunk-g72v6mmf.js.map +10 -0
- package/dist/chunk-g7g3jxty.js +351 -0
- package/dist/chunk-g7g3jxty.js.map +10 -0
- package/dist/chunk-g830re2c.js +50 -0
- package/dist/chunk-g830re2c.js.map +10 -0
- package/dist/chunk-gtwh1sg7.js +127 -0
- package/dist/chunk-gtwh1sg7.js.map +10 -0
- package/dist/chunk-k12cwfst.js +72 -0
- package/dist/chunk-k12cwfst.js.map +10 -0
- package/dist/chunk-mbqqsz6r.js +128 -0
- package/dist/chunk-mbqqsz6r.js.map +10 -0
- package/dist/chunk-ne632swm.js +209 -0
- package/dist/chunk-ne632swm.js.map +10 -0
- package/dist/chunk-p3pj1bax.js +206 -0
- package/dist/chunk-p3pj1bax.js.map +10 -0
- package/dist/chunk-vshdk2pw.js +56 -0
- package/dist/chunk-vshdk2pw.js.map +10 -0
- package/dist/chunk-wp2ebn2m.js +51 -0
- package/dist/chunk-wp2ebn2m.js.map +10 -0
- package/dist/chunk-x4qv4jm9.js +88 -0
- package/dist/chunk-x4qv4jm9.js.map +10 -0
- package/dist/chunk-ycxp4drd.js +211 -0
- package/dist/chunk-ycxp4drd.js.map +10 -0
- package/dist/components/builtin.js +14 -1246
- package/dist/components/builtin.js.map +3 -10
- package/dist/context.js +7 -362
- package/dist/context.js.map +3 -6
- package/dist/datasource.js +5 -76
- package/dist/datasource.js.map +3 -4
- package/dist/disposable.js +20 -367
- package/dist/disposable.js.map +3 -5
- package/dist/engine-base.d.ts +38 -2
- package/dist/engine-base.js +45 -412
- package/dist/engine-base.js.map +4 -6
- package/dist/events.js +7 -285
- package/dist/events.js.map +3 -5
- package/dist/hypen.js +8 -71
- package/dist/hypen.js.map +3 -4
- package/dist/index.browser.js +58 -2152
- package/dist/index.browser.js.map +3 -16
- package/dist/index.d.ts +2 -0
- package/dist/index.js +132 -3058
- package/dist/index.js.map +4 -22
- package/dist/logger.js +16 -220
- package/dist/logger.js.map +3 -4
- package/dist/managed-router.js +12 -1367
- package/dist/managed-router.js.map +3 -10
- package/dist/portable.js +6 -70
- package/dist/portable.js.map +3 -4
- package/dist/remote/client.js +9 -1010
- package/dist/remote/client.js.map +3 -8
- package/dist/remote/index.d.ts +2 -0
- package/dist/remote/index.js +511 -1066
- package/dist/remote/index.js.map +4 -9
- package/dist/remote/remote-session.d.ts +245 -0
- package/dist/remote/session.js +5 -147
- package/dist/remote/session.js.map +3 -4
- package/dist/renderer.js +7 -271
- package/dist/renderer.js.map +3 -5
- package/dist/resolver.js +5 -484
- package/dist/resolver.js.map +3 -5
- package/dist/result.js +25 -211
- package/dist/result.js.map +3 -4
- package/dist/retry.js +10 -336
- package/dist/retry.js.map +3 -5
- package/dist/router.js +9 -807
- package/dist/router.js.map +3 -8
- package/dist/state.js +10 -274
- package/dist/state.js.map +3 -5
- package/dist/validate.d.ts +19 -0
- package/package.json +13 -1
- package/src/engine-base.ts +87 -4
- package/src/index.ts +5 -0
- package/src/remote/index.ts +16 -0
- package/src/remote/remote-session.ts +998 -0
- package/src/validate.ts +37 -0
package/dist/disposable.js
CHANGED
|
@@ -1,369 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return require.apply(this, arguments);
|
|
21
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// src/logger.ts
|
|
25
|
-
var LOG_LEVEL_ORDER = {
|
|
26
|
-
debug: 0,
|
|
27
|
-
info: 1,
|
|
28
|
-
warn: 2,
|
|
29
|
-
error: 3,
|
|
30
|
-
none: 4
|
|
31
|
-
};
|
|
32
|
-
var LOG_LEVEL_COLORS = {
|
|
33
|
-
debug: "\x1B[36m",
|
|
34
|
-
info: "\x1B[32m",
|
|
35
|
-
warn: "\x1B[33m",
|
|
36
|
-
error: "\x1B[31m"
|
|
37
|
-
};
|
|
38
|
-
var RESET_COLOR = "\x1B[0m";
|
|
39
|
-
function isProduction() {
|
|
40
|
-
if (typeof process !== "undefined" && process.env) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
var config = {
|
|
46
|
-
level: isProduction() ? "error" : "info",
|
|
47
|
-
colors: true,
|
|
48
|
-
timestamps: false
|
|
49
|
-
};
|
|
50
|
-
function setLogLevel(level) {
|
|
51
|
-
config.level = level;
|
|
52
|
-
}
|
|
53
|
-
function getLogLevel() {
|
|
54
|
-
return config.level;
|
|
55
|
-
}
|
|
56
|
-
function configureLogger(options) {
|
|
57
|
-
config = { ...config, ...options };
|
|
58
|
-
}
|
|
59
|
-
function enableLogging() {
|
|
60
|
-
config.level = "debug";
|
|
61
|
-
}
|
|
62
|
-
function disableLogging() {
|
|
63
|
-
config.level = "none";
|
|
64
|
-
}
|
|
65
|
-
function setDebugMode(enabled) {
|
|
66
|
-
config.level = enabled ? "debug" : "error";
|
|
67
|
-
}
|
|
68
|
-
function isDebugMode() {
|
|
69
|
-
return config.level === "debug";
|
|
70
|
-
}
|
|
71
|
-
function shouldLog(level) {
|
|
72
|
-
return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
|
|
73
|
-
}
|
|
74
|
-
function formatTag(tag, level) {
|
|
75
|
-
const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
|
|
76
|
-
if (config.colors && level !== "none") {
|
|
77
|
-
const color = LOG_LEVEL_COLORS[level];
|
|
78
|
-
return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
|
|
79
|
-
}
|
|
80
|
-
return `${timestamp}[${tag}]`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
class Logger {
|
|
84
|
-
tag;
|
|
85
|
-
constructor(tag) {
|
|
86
|
-
this.tag = tag;
|
|
87
|
-
}
|
|
88
|
-
debug(...args) {
|
|
89
|
-
if (!shouldLog("debug"))
|
|
90
|
-
return;
|
|
91
|
-
if (config.handler) {
|
|
92
|
-
config.handler.debug(this.tag, ...args);
|
|
93
|
-
} else {
|
|
94
|
-
console.log(formatTag(this.tag, "debug"), ...args);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
info(...args) {
|
|
98
|
-
if (!shouldLog("info"))
|
|
99
|
-
return;
|
|
100
|
-
if (config.handler) {
|
|
101
|
-
config.handler.info(this.tag, ...args);
|
|
102
|
-
} else {
|
|
103
|
-
console.info(formatTag(this.tag, "info"), ...args);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
warn(...args) {
|
|
107
|
-
if (!shouldLog("warn"))
|
|
108
|
-
return;
|
|
109
|
-
if (config.handler) {
|
|
110
|
-
config.handler.warn(this.tag, ...args);
|
|
111
|
-
} else {
|
|
112
|
-
console.warn(formatTag(this.tag, "warn"), ...args);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
error(...args) {
|
|
116
|
-
if (!shouldLog("error"))
|
|
117
|
-
return;
|
|
118
|
-
if (config.handler) {
|
|
119
|
-
config.handler.error(this.tag, ...args);
|
|
120
|
-
} else {
|
|
121
|
-
console.error(formatTag(this.tag, "error"), ...args);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
time(label, fn) {
|
|
125
|
-
if (!shouldLog("debug")) {
|
|
126
|
-
return fn();
|
|
127
|
-
}
|
|
128
|
-
const start = performance.now();
|
|
129
|
-
try {
|
|
130
|
-
return fn();
|
|
131
|
-
} finally {
|
|
132
|
-
const duration = performance.now() - start;
|
|
133
|
-
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
async timeAsync(label, fn) {
|
|
137
|
-
if (!shouldLog("debug")) {
|
|
138
|
-
return fn();
|
|
139
|
-
}
|
|
140
|
-
const start = performance.now();
|
|
141
|
-
try {
|
|
142
|
-
return await fn();
|
|
143
|
-
} finally {
|
|
144
|
-
const duration = performance.now() - start;
|
|
145
|
-
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
child(subTag) {
|
|
149
|
-
return new Logger(`${this.tag}:${subTag}`);
|
|
150
|
-
}
|
|
151
|
-
debugIf(condition, ...args) {
|
|
152
|
-
if (condition)
|
|
153
|
-
this.debug(...args);
|
|
154
|
-
}
|
|
155
|
-
warnIf(condition, ...args) {
|
|
156
|
-
if (condition)
|
|
157
|
-
this.warn(...args);
|
|
158
|
-
}
|
|
159
|
-
errorIf(condition, ...args) {
|
|
160
|
-
if (condition)
|
|
161
|
-
this.error(...args);
|
|
162
|
-
}
|
|
163
|
-
loggedOnce = new Set;
|
|
164
|
-
warnOnce(key, ...args) {
|
|
165
|
-
if (this.loggedOnce.has(key))
|
|
166
|
-
return;
|
|
167
|
-
this.loggedOnce.add(key);
|
|
168
|
-
this.warn(...args);
|
|
169
|
-
}
|
|
170
|
-
debugOnce(key, ...args) {
|
|
171
|
-
if (this.loggedOnce.has(key))
|
|
172
|
-
return;
|
|
173
|
-
this.loggedOnce.add(key);
|
|
174
|
-
this.debug(...args);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
function createLogger(tag) {
|
|
178
|
-
return new Logger(tag);
|
|
179
|
-
}
|
|
180
|
-
var logger = createLogger("Hypen");
|
|
181
|
-
var log = {
|
|
182
|
-
debug: (tag, ...args) => {
|
|
183
|
-
if (!shouldLog("debug"))
|
|
184
|
-
return;
|
|
185
|
-
console.log(formatTag(tag, "debug"), ...args);
|
|
186
|
-
},
|
|
187
|
-
info: (tag, ...args) => {
|
|
188
|
-
if (!shouldLog("info"))
|
|
189
|
-
return;
|
|
190
|
-
console.info(formatTag(tag, "info"), ...args);
|
|
191
|
-
},
|
|
192
|
-
warn: (tag, ...args) => {
|
|
193
|
-
if (!shouldLog("warn"))
|
|
194
|
-
return;
|
|
195
|
-
console.warn(formatTag(tag, "warn"), ...args);
|
|
196
|
-
},
|
|
197
|
-
error: (tag, ...args) => {
|
|
198
|
-
if (!shouldLog("error"))
|
|
199
|
-
return;
|
|
200
|
-
console.error(formatTag(tag, "error"), ...args);
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
var frameworkLoggers = {
|
|
204
|
-
hypen: createLogger("Hypen"),
|
|
205
|
-
engine: createLogger("Engine"),
|
|
206
|
-
router: createLogger("Router"),
|
|
207
|
-
state: createLogger("State"),
|
|
208
|
-
events: createLogger("Events"),
|
|
209
|
-
remote: createLogger("Remote"),
|
|
210
|
-
renderer: createLogger("Renderer"),
|
|
211
|
-
module: createLogger("Module"),
|
|
212
|
-
lifecycle: createLogger("Lifecycle"),
|
|
213
|
-
loader: createLogger("Loader"),
|
|
214
|
-
context: createLogger("Context"),
|
|
215
|
-
discovery: createLogger("Discovery"),
|
|
216
|
-
plugin: createLogger("Plugin"),
|
|
217
|
-
canvas: createLogger("Canvas"),
|
|
218
|
-
debug: createLogger("Debug")
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
// src/disposable.ts
|
|
222
|
-
var log2 = frameworkLoggers.lifecycle;
|
|
223
|
-
function isDisposable(obj) {
|
|
224
|
-
return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
class DisposableStack {
|
|
228
|
-
stack = [];
|
|
229
|
-
disposed = false;
|
|
230
|
-
add(disposable) {
|
|
231
|
-
if (this.disposed) {
|
|
232
|
-
disposable.dispose();
|
|
233
|
-
return disposable;
|
|
234
|
-
}
|
|
235
|
-
this.stack.push(disposable);
|
|
236
|
-
return disposable;
|
|
237
|
-
}
|
|
238
|
-
addCallback(callback) {
|
|
239
|
-
this.add({ dispose: callback });
|
|
240
|
-
}
|
|
241
|
-
addValue(value, dispose) {
|
|
242
|
-
this.add({ dispose: () => dispose(value) });
|
|
243
|
-
return value;
|
|
244
|
-
}
|
|
245
|
-
dispose() {
|
|
246
|
-
if (this.disposed)
|
|
247
|
-
return;
|
|
248
|
-
this.disposed = true;
|
|
249
|
-
while (this.stack.length > 0) {
|
|
250
|
-
const item = this.stack.pop();
|
|
251
|
-
try {
|
|
252
|
-
item.dispose();
|
|
253
|
-
} catch (error) {
|
|
254
|
-
log2.error("Error during dispose:", error);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
get isDisposed() {
|
|
259
|
-
return this.disposed;
|
|
260
|
-
}
|
|
261
|
-
get size() {
|
|
262
|
-
return this.stack.length;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
function disposableListener(target, event, handler, options) {
|
|
266
|
-
target.addEventListener(event, handler, options);
|
|
267
|
-
return {
|
|
268
|
-
dispose: () => target.removeEventListener(event, handler, options)
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
function disposableTimeout(callback, ms) {
|
|
272
|
-
const id = setTimeout(callback, ms);
|
|
273
|
-
return {
|
|
274
|
-
id,
|
|
275
|
-
dispose: () => clearTimeout(id)
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
function disposableInterval(callback, ms) {
|
|
279
|
-
const id = setInterval(callback, ms);
|
|
280
|
-
return {
|
|
281
|
-
id,
|
|
282
|
-
dispose: () => clearInterval(id)
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
function disposableWebSocket(ws) {
|
|
286
|
-
return {
|
|
287
|
-
dispose: () => {
|
|
288
|
-
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
289
|
-
ws.close();
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
function disposableAbortController() {
|
|
295
|
-
const controller = new AbortController;
|
|
296
|
-
return {
|
|
297
|
-
controller,
|
|
298
|
-
signal: controller.signal,
|
|
299
|
-
dispose: () => controller.abort()
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
function disposableSubscription(unsubscribe) {
|
|
303
|
-
return { dispose: unsubscribe };
|
|
304
|
-
}
|
|
305
|
-
var ELEMENT_DISPOSABLES = Symbol("hypen.disposables");
|
|
306
|
-
function getElementDisposables(element) {
|
|
307
|
-
const existing = element[ELEMENT_DISPOSABLES];
|
|
308
|
-
if (existing instanceof DisposableStack) {
|
|
309
|
-
return existing;
|
|
310
|
-
}
|
|
311
|
-
const stack = new DisposableStack;
|
|
312
|
-
element[ELEMENT_DISPOSABLES] = stack;
|
|
313
|
-
return stack;
|
|
314
|
-
}
|
|
315
|
-
function disposeElement(element) {
|
|
316
|
-
const stack = element[ELEMENT_DISPOSABLES];
|
|
317
|
-
if (stack instanceof DisposableStack) {
|
|
318
|
-
stack.dispose();
|
|
319
|
-
delete element[ELEMENT_DISPOSABLES];
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
function hasElementDisposables(element) {
|
|
323
|
-
return element[ELEMENT_DISPOSABLES] instanceof DisposableStack;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
class DisposableMixin {
|
|
327
|
-
disposables = new DisposableStack;
|
|
328
|
-
track(disposable) {
|
|
329
|
-
return this.disposables.add(disposable);
|
|
330
|
-
}
|
|
331
|
-
onDispose(callback) {
|
|
332
|
-
this.disposables.addCallback(callback);
|
|
333
|
-
}
|
|
334
|
-
dispose() {
|
|
335
|
-
this.disposables.dispose();
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
function compositeDisposable(...disposables) {
|
|
339
|
-
return {
|
|
340
|
-
dispose: () => {
|
|
341
|
-
for (const d of disposables) {
|
|
342
|
-
try {
|
|
343
|
-
d.dispose();
|
|
344
|
-
} catch (error) {
|
|
345
|
-
log2.error("Error during dispose:", error);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
async function using(resource, fn) {
|
|
352
|
-
const r = typeof resource === "function" ? resource() : resource;
|
|
353
|
-
try {
|
|
354
|
-
return await fn(r);
|
|
355
|
-
} finally {
|
|
356
|
-
r.dispose();
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
function usingSync(resource, fn) {
|
|
360
|
-
const r = typeof resource === "function" ? resource() : resource;
|
|
361
|
-
try {
|
|
362
|
-
return fn(r);
|
|
363
|
-
} finally {
|
|
364
|
-
r.dispose();
|
|
365
|
-
}
|
|
366
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
DisposableMixin,
|
|
3
|
+
DisposableStack,
|
|
4
|
+
compositeDisposable,
|
|
5
|
+
disposableAbortController,
|
|
6
|
+
disposableInterval,
|
|
7
|
+
disposableListener,
|
|
8
|
+
disposableSubscription,
|
|
9
|
+
disposableTimeout,
|
|
10
|
+
disposableWebSocket,
|
|
11
|
+
disposeElement,
|
|
12
|
+
getElementDisposables,
|
|
13
|
+
hasElementDisposables,
|
|
14
|
+
isDisposable,
|
|
15
|
+
using,
|
|
16
|
+
usingSync
|
|
17
|
+
} from "./chunk-ec0tgy9a.js";
|
|
18
|
+
import"./chunk-avchpwhf.js";
|
|
19
|
+
import"./chunk-5gtx3pza.js";
|
|
367
20
|
export {
|
|
368
21
|
usingSync,
|
|
369
22
|
using,
|
|
@@ -382,4 +35,4 @@ export {
|
|
|
382
35
|
DisposableMixin
|
|
383
36
|
};
|
|
384
37
|
|
|
385
|
-
//# debugId=
|
|
38
|
+
//# debugId=EE0648936A38884E64756E2164756E21
|
package/dist/disposable.js.map
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": [
|
|
3
|
+
"sources": [],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Configurable Debug Logger\n *\n * Provides environment-aware logging that can be disabled in production.\n * Supports log levels, tagged output, and performance timing.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\";\n\nexport interface LoggerConfig {\n /** Minimum log level (default: \"debug\" in dev, \"error\" in prod) */\n level: LogLevel;\n /** Enable colored output (default: true) */\n colors: boolean;\n /** Include timestamps (default: false) */\n timestamps: boolean;\n /** Custom log handler (default: console) */\n handler?: LogHandler;\n}\n\nexport interface LogHandler {\n debug(tag: string, ...args: unknown[]): void;\n info(tag: string, ...args: unknown[]): void;\n warn(tag: string, ...args: unknown[]): void;\n error(tag: string, ...args: unknown[]): void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n none: 4,\n};\n\nconst LOG_LEVEL_COLORS: Record<Exclude<LogLevel, \"none\">, string> = {\n debug: \"\\x1b[36m\", // Cyan\n info: \"\\x1b[32m\", // Green\n warn: \"\\x1b[33m\", // Yellow\n error: \"\\x1b[31m\", // Red\n};\n\nconst RESET_COLOR = \"\\x1b[0m\";\n\n// ============================================================================\n// Global Configuration\n// ============================================================================\n\n/**\n * Detect if running in production environment\n */\nfunction isProduction(): boolean {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env.NODE_ENV === \"production\";\n }\n return false;\n}\n\n/**\n * Default configuration\n */\nlet config: LoggerConfig = {\n level: isProduction() ? \"error\" : \"info\",\n colors: true,\n timestamps: false,\n};\n\n// ============================================================================\n// Configuration API\n// ============================================================================\n\n/**\n * Set the global log level\n */\nexport function setLogLevel(level: LogLevel): void {\n config.level = level;\n}\n\n/**\n * Get the current log level\n */\nexport function getLogLevel(): LogLevel {\n return config.level;\n}\n\n/**\n * Configure the logger\n */\nexport function configureLogger(options: Partial<LoggerConfig>): void {\n config = { ...config, ...options };\n}\n\n/**\n * Enable all logging (sets level to \"debug\")\n */\nexport function enableLogging(): void {\n config.level = \"debug\";\n}\n\n/**\n * Disable all logging (sets level to \"none\")\n */\nexport function disableLogging(): void {\n config.level = \"none\";\n}\n\n/**\n * Enable debug mode - alias for enableLogging()\n * Call this at app startup to see all debug logs\n *\n * @example\n * ```typescript\n * import { setDebugMode } from \"@hypen-space/core\";\n * setDebugMode(true);\n * ```\n */\nexport function setDebugMode(enabled: boolean): void {\n config.level = enabled ? \"debug\" : \"error\";\n}\n\n/**\n * Check if debug mode is enabled\n */\nexport function isDebugMode(): boolean {\n return config.level === \"debug\";\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];\n}\n\nfunction formatTag(tag: string, level: LogLevel): string {\n const timestamp = config.timestamps ? `${new Date().toISOString()} ` : \"\";\n\n if (config.colors && level !== \"none\") {\n const color = LOG_LEVEL_COLORS[level as Exclude<LogLevel, \"none\">];\n return `${timestamp}${color}[${tag}]${RESET_COLOR}`;\n }\n\n return `${timestamp}[${tag}]`;\n}\n\n// ============================================================================\n// Logger Class\n// ============================================================================\n\n/**\n * Tagged logger instance\n *\n * @example\n * ```typescript\n * const log = createLogger(\"MyComponent\");\n * log.debug(\"initialized with\", { props });\n * log.error(\"failed to load\", error);\n * ```\n */\nexport class Logger {\n private readonly tag: string;\n\n constructor(tag: string) {\n this.tag = tag;\n }\n\n debug(...args: unknown[]): void {\n if (!shouldLog(\"debug\")) return;\n\n if (config.handler) {\n config.handler.debug(this.tag, ...args);\n } else {\n console.log(formatTag(this.tag, \"debug\"), ...args);\n }\n }\n\n info(...args: unknown[]): void {\n if (!shouldLog(\"info\")) return;\n\n if (config.handler) {\n config.handler.info(this.tag, ...args);\n } else {\n console.info(formatTag(this.tag, \"info\"), ...args);\n }\n }\n\n warn(...args: unknown[]): void {\n if (!shouldLog(\"warn\")) return;\n\n if (config.handler) {\n config.handler.warn(this.tag, ...args);\n } else {\n console.warn(formatTag(this.tag, \"warn\"), ...args);\n }\n }\n\n error(...args: unknown[]): void {\n if (!shouldLog(\"error\")) return;\n\n if (config.handler) {\n config.handler.error(this.tag, ...args);\n } else {\n console.error(formatTag(this.tag, \"error\"), ...args);\n }\n }\n\n /**\n * Time a function execution\n */\n time<T>(label: string, fn: () => T): T {\n if (!shouldLog(\"debug\")) {\n return fn();\n }\n\n const start = performance.now();\n try {\n return fn();\n } finally {\n const duration = performance.now() - start;\n this.debug(`${label}: ${duration.toFixed(2)}ms`);\n }\n }\n\n /**\n * Time an async function execution\n */\n async timeAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!shouldLog(\"debug\")) {\n return fn();\n }\n\n const start = performance.now();\n try {\n return await fn();\n } finally {\n const duration = performance.now() - start;\n this.debug(`${label}: ${duration.toFixed(2)}ms`);\n }\n }\n\n /**\n * Create a child logger with additional context\n */\n child(subTag: string): Logger {\n return new Logger(`${this.tag}:${subTag}`);\n }\n\n /**\n * Conditionally log based on a condition\n */\n debugIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.debug(...args);\n }\n\n warnIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.warn(...args);\n }\n\n errorIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.error(...args);\n }\n\n /**\n * Log once (useful for deprecation warnings)\n */\n private loggedOnce = new Set<string>();\n\n warnOnce(key: string, ...args: unknown[]): void {\n if (this.loggedOnce.has(key)) return;\n this.loggedOnce.add(key);\n this.warn(...args);\n }\n\n debugOnce(key: string, ...args: unknown[]): void {\n if (this.loggedOnce.has(key)) return;\n this.loggedOnce.add(key);\n this.debug(...args);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a tagged logger\n *\n * @example\n * ```typescript\n * const log = createLogger(\"Router\");\n * log.info(\"navigating to\", path);\n * ```\n */\nexport function createLogger(tag: string): Logger {\n return new Logger(tag);\n}\n\n// ============================================================================\n// Default Logger Instance\n// ============================================================================\n\n/**\n * Default logger for general use\n */\nexport const logger = createLogger(\"Hypen\");\n\n// ============================================================================\n// Shorthand Functions (untagged)\n// ============================================================================\n\n/**\n * Shorthand logging functions for quick use\n * Prefer createLogger() for component-specific logging\n */\nexport const log = {\n debug: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"debug\")) return;\n console.log(formatTag(tag, \"debug\"), ...args);\n },\n\n info: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"info\")) return;\n console.info(formatTag(tag, \"info\"), ...args);\n },\n\n warn: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"warn\")) return;\n console.warn(formatTag(tag, \"warn\"), ...args);\n },\n\n error: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"error\")) return;\n console.error(formatTag(tag, \"error\"), ...args);\n },\n};\n\n// ============================================================================\n// Predefined Loggers for Framework Components\n// ============================================================================\n\nexport const frameworkLoggers = {\n hypen: createLogger(\"Hypen\"),\n engine: createLogger(\"Engine\"),\n router: createLogger(\"Router\"),\n state: createLogger(\"State\"),\n events: createLogger(\"Events\"),\n remote: createLogger(\"Remote\"),\n renderer: createLogger(\"Renderer\"),\n module: createLogger(\"Module\"),\n lifecycle: createLogger(\"Lifecycle\"),\n loader: createLogger(\"Loader\"),\n context: createLogger(\"Context\"),\n discovery: createLogger(\"Discovery\"),\n plugin: createLogger(\"Plugin\"),\n canvas: createLogger(\"Canvas\"),\n debug: createLogger(\"Debug\"),\n};\n",
|
|
6
|
-
"/**\n * Disposable Pattern for Resource Management\n *\n * Provides a consistent way to manage and clean up resources like\n * event listeners, timers, WebSocket connections, etc.\n */\n\nimport { frameworkLoggers } from \"./logger.js\";\n\nconst log = frameworkLoggers.lifecycle;\n\n/**\n * Interface for objects that can be disposed\n */\nexport interface Disposable {\n dispose(): void;\n}\n\n/**\n * Check if an object is Disposable\n */\nexport function isDisposable(obj: unknown): obj is Disposable {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dispose' in obj &&\n typeof (obj as Disposable).dispose === 'function'\n );\n}\n\n/**\n * A stack of disposables that are disposed in LIFO order\n */\nexport class DisposableStack implements Disposable {\n private stack: Disposable[] = [];\n private disposed = false;\n\n /**\n * Add a disposable to the stack and return it\n */\n add<T extends Disposable>(disposable: T): T {\n if (this.disposed) {\n // If already disposed, immediately dispose the new item\n disposable.dispose();\n return disposable;\n }\n this.stack.push(disposable);\n return disposable;\n }\n\n /**\n * Add a cleanup callback to the stack\n */\n addCallback(callback: () => void): void {\n this.add({ dispose: callback });\n }\n\n /**\n * Add a value with a custom dispose function\n */\n addValue<T>(value: T, dispose: (value: T) => void): T {\n this.add({ dispose: () => dispose(value) });\n return value;\n }\n\n /**\n * Dispose all items in reverse order (LIFO)\n */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n\n while (this.stack.length > 0) {\n const item = this.stack.pop()!;\n try {\n item.dispose();\n } catch (error) {\n // Log but continue disposing other items\n log.error('Error during dispose:', error);\n }\n }\n }\n\n /**\n * Check if this stack has been disposed\n */\n get isDisposed(): boolean {\n return this.disposed;\n }\n\n /**\n * Get the number of items in the stack\n */\n get size(): number {\n return this.stack.length;\n }\n}\n\n/**\n * Create a disposable from an event listener\n */\nexport function disposableListener(\n target: EventTarget,\n event: string,\n handler: EventListenerOrEventListenerObject,\n options?: AddEventListenerOptions\n): Disposable {\n target.addEventListener(event, handler, options);\n return {\n dispose: () => target.removeEventListener(event, handler, options),\n };\n}\n\n/**\n * Create a disposable from a timeout\n */\nexport function disposableTimeout(\n callback: () => void,\n ms: number\n): Disposable & { id: ReturnType<typeof setTimeout> } {\n const id = setTimeout(callback, ms);\n return {\n id,\n dispose: () => clearTimeout(id),\n };\n}\n\n/**\n * Create a disposable from an interval\n */\nexport function disposableInterval(\n callback: () => void,\n ms: number\n): Disposable & { id: ReturnType<typeof setInterval> } {\n const id = setInterval(callback, ms);\n return {\n id,\n dispose: () => clearInterval(id),\n };\n}\n\n/**\n * Create a disposable from a WebSocket\n */\nexport function disposableWebSocket(ws: WebSocket): Disposable {\n return {\n dispose: () => {\n if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {\n ws.close();\n }\n },\n };\n}\n\n/**\n * Create a disposable from an AbortController\n */\nexport function disposableAbortController(): Disposable & { controller: AbortController; signal: AbortSignal } {\n const controller = new AbortController();\n return {\n controller,\n signal: controller.signal,\n dispose: () => controller.abort(),\n };\n}\n\n/**\n * Create a disposable subscription (for event emitters, observables, etc.)\n */\nexport function disposableSubscription(unsubscribe: () => void): Disposable {\n return { dispose: unsubscribe };\n}\n\n/**\n * Symbol used to store disposables on DOM elements\n */\nconst ELEMENT_DISPOSABLES = Symbol('hypen.disposables');\n\n/**\n * Get or create a DisposableStack for an HTML element\n */\nexport function getElementDisposables(element: HTMLElement): DisposableStack {\n const existing = (element as any)[ELEMENT_DISPOSABLES];\n if (existing instanceof DisposableStack) {\n return existing;\n }\n const stack = new DisposableStack();\n (element as any)[ELEMENT_DISPOSABLES] = stack;\n return stack;\n}\n\n/**\n * Dispose all disposables attached to an element\n */\nexport function disposeElement(element: HTMLElement): void {\n const stack = (element as any)[ELEMENT_DISPOSABLES];\n if (stack instanceof DisposableStack) {\n stack.dispose();\n delete (element as any)[ELEMENT_DISPOSABLES];\n }\n}\n\n/**\n * Check if an element has disposables\n */\nexport function hasElementDisposables(element: HTMLElement): boolean {\n return (element as any)[ELEMENT_DISPOSABLES] instanceof DisposableStack;\n}\n\n/**\n * Decorator/helper to make a class disposable\n * Tracks all resources and disposes them when dispose() is called\n */\nexport class DisposableMixin {\n protected disposables = new DisposableStack();\n\n /**\n * Register a disposable to be cleaned up\n */\n protected track<T extends Disposable>(disposable: T): T {\n return this.disposables.add(disposable);\n }\n\n /**\n * Register a cleanup callback\n */\n protected onDispose(callback: () => void): void {\n this.disposables.addCallback(callback);\n }\n\n /**\n * Dispose all tracked resources\n */\n dispose(): void {\n this.disposables.dispose();\n }\n}\n\n/**\n * Create a composite disposable that disposes multiple items together\n */\nexport function compositeDisposable(...disposables: Disposable[]): Disposable {\n return {\n dispose: () => {\n for (const d of disposables) {\n try {\n d.dispose();\n } catch (error) {\n log.error('Error during dispose:', error);\n }\n }\n },\n };\n}\n\n/**\n * Run a function with automatic cleanup on exit\n * Similar to Python's context managers or C#'s using statement\n */\nexport async function using<T extends Disposable, R>(\n resource: T | (() => T),\n fn: (resource: T) => R | Promise<R>\n): Promise<R> {\n const r = typeof resource === 'function' ? resource() : resource;\n try {\n return await fn(r);\n } finally {\n r.dispose();\n }\n}\n\n/**\n * Synchronous version of using()\n */\nexport function usingSync<T extends Disposable, R>(\n resource: T | (() => T),\n fn: (resource: T) => R\n): R {\n const r = typeof resource === 'function' ? resource() : resource;\n try {\n return fn(r);\n } finally {\n r.dispose();\n }\n}\n"
|
|
7
5
|
],
|
|
8
|
-
"mappings": "
|
|
9
|
-
"debugId": "
|
|
6
|
+
"mappings": "",
|
|
7
|
+
"debugId": "EE0648936A38884E64756E2164756E21",
|
|
10
8
|
"names": []
|
|
11
9
|
}
|
package/dist/engine-base.d.ts
CHANGED
|
@@ -44,6 +44,15 @@ import type { Action, RenderCallback, ActionHandler, ComponentResolver } from ".
|
|
|
44
44
|
export declare abstract class BaseEngine {
|
|
45
45
|
protected wasmEngine: any;
|
|
46
46
|
protected initialized: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Component names the resolver was asked for and returned `null` on — i.e.
|
|
49
|
+
* names that are neither a registered primitive (the engine checks those
|
|
50
|
+
* first and never consults the resolver for them) nor resolvable to a
|
|
51
|
+
* template. Each such name produces an opaque `Create` patch the renderer
|
|
52
|
+
* drops. Tracked so a miss is warned about once and can be asserted on in
|
|
53
|
+
* tests. See `getUnresolvedComponents`.
|
|
54
|
+
*/
|
|
55
|
+
private unresolvedComponents;
|
|
47
56
|
/**
|
|
48
57
|
* Initialize the WASM module. Platform-specific.
|
|
49
58
|
*
|
|
@@ -71,8 +80,23 @@ export declare abstract class BaseEngine {
|
|
|
71
80
|
setRenderCallback(callback: RenderCallback): void;
|
|
72
81
|
/**
|
|
73
82
|
* Set the component resolver for dynamic component composition.
|
|
83
|
+
*
|
|
84
|
+
* The resolver is wrapped to detect "resolver misses": the engine only
|
|
85
|
+
* consults the resolver for element types that are NOT registered
|
|
86
|
+
* primitives, so a `null` return means the name resolves to nothing and
|
|
87
|
+
* the engine will emit an opaque `Create` the renderer silently drops
|
|
88
|
+
* (e.g. an anonymous component that never got registered). The first miss
|
|
89
|
+
* for each unique name is logged with actionable guidance; every miss is
|
|
90
|
+
* recorded for `getUnresolvedComponents()` / test assertions.
|
|
74
91
|
*/
|
|
75
92
|
setComponentResolver(resolver: ComponentResolver): void;
|
|
93
|
+
/**
|
|
94
|
+
* Names the component resolver has been asked for and failed to resolve
|
|
95
|
+
* this session (see `setComponentResolver`). Useful as a CI / smoke-test
|
|
96
|
+
* assertion — an empty array means every referenced component resolved to
|
|
97
|
+
* a primitive or a template.
|
|
98
|
+
*/
|
|
99
|
+
getUnresolvedComponents(): string[];
|
|
76
100
|
/**
|
|
77
101
|
* Parse and render Hypen DSL source code.
|
|
78
102
|
* @throws {ParseError} if the source fails to parse
|
|
@@ -122,8 +146,20 @@ export declare abstract class BaseEngine {
|
|
|
122
146
|
onAction(actionName: string, handler: ActionHandler): void;
|
|
123
147
|
/**
|
|
124
148
|
* Platform hook: normalize an incoming action before the user handler
|
|
125
|
-
* sees it.
|
|
126
|
-
*
|
|
149
|
+
* sees it.
|
|
150
|
+
*
|
|
151
|
+
* The default converts any `Map` instances in the payload into plain
|
|
152
|
+
* objects (deeply). This is the landmine the wasm-bindgen **web** target
|
|
153
|
+
* sets: it returns structured action payloads as JS `Map`s, so a handler
|
|
154
|
+
* reading `payload.to` gets `undefined` and `@router.push, to: "/x"`
|
|
155
|
+
* silently no-ops. Every consumer of the web-target WASM — the browser
|
|
156
|
+
* engine, a Cloudflare `CFEngine`, any future runtime — inherits the fix
|
|
157
|
+
* here instead of rediscovering it.
|
|
158
|
+
*
|
|
159
|
+
* The wasm-bindgen **bundler** (node) target already returns plain
|
|
160
|
+
* objects, so for it this is a harmless deep walk. Subclasses on that
|
|
161
|
+
* target may override with an identity to skip the walk (see
|
|
162
|
+
* `@hypen-space/server`).
|
|
127
163
|
*/
|
|
128
164
|
protected normalizeAction(action: Action): Action;
|
|
129
165
|
/**
|