@hypen-space/core 0.2.11 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -11
- package/dist/src/app.js +470 -44
- package/dist/src/app.js.map +7 -5
- package/dist/src/components/builtin.js +470 -44
- package/dist/src/components/builtin.js.map +7 -5
- package/dist/src/discovery.js +559 -65
- package/dist/src/discovery.js.map +8 -6
- package/dist/src/engine.browser.js +2 -2
- package/dist/src/engine.browser.js.map +2 -2
- package/dist/src/engine.js +18 -9
- package/dist/src/engine.js.map +3 -3
- package/dist/src/index.browser.js +863 -82
- package/dist/src/index.browser.js.map +11 -7
- package/dist/src/index.js +1591 -125
- package/dist/src/index.js.map +17 -10
- package/dist/src/remote/client.js +525 -35
- package/dist/src/remote/client.js.map +7 -4
- package/dist/src/remote/index.js +1796 -35
- package/dist/src/remote/index.js.map +13 -4
- package/dist/src/router.js +55 -29
- package/dist/src/router.js.map +3 -3
- package/dist/src/state.js +57 -29
- package/dist/src/state.js.map +3 -3
- package/package.json +8 -2
- package/src/app.ts +292 -13
- package/src/discovery.ts +123 -18
- package/src/disposable.ts +281 -0
- package/src/engine.browser.ts +1 -1
- package/src/engine.ts +29 -10
- package/src/hypen.ts +209 -0
- package/src/index.ts +147 -11
- package/src/logger.ts +338 -0
- package/src/remote/client.ts +263 -56
- package/src/remote/index.ts +25 -1
- package/src/remote/server.ts +652 -0
- package/src/remote/session.ts +256 -0
- package/src/remote/types.ts +68 -1
- package/src/result.ts +260 -0
- package/src/retry.ts +306 -0
- package/src/state.ts +103 -45
- package/wasm-browser/README.md +4 -0
- package/wasm-browser/hypen_engine_bg.wasm +0 -0
- package/wasm-browser/package.json +1 -1
- package/wasm-node/README.md +4 -0
- package/wasm-node/hypen_engine_bg.wasm +0 -0
- package/wasm-node/package.json +1 -1
- package/wasm-browser/hypen_engine_bg.js +0 -736
- package/wasm-node/hypen_engine_bg.js +0 -736
package/README.md
CHANGED
|
@@ -124,34 +124,34 @@ interface UserState {
|
|
|
124
124
|
const userModule = app
|
|
125
125
|
.defineState<UserState>({ user: null, loading: false })
|
|
126
126
|
|
|
127
|
-
//
|
|
128
|
-
.onCreated(async (
|
|
127
|
+
// Lifecycle handler: receives (state, context?)
|
|
128
|
+
.onCreated(async (state, context) => {
|
|
129
129
|
state.loading = true;
|
|
130
|
-
|
|
130
|
+
// State changes are auto-synced via Proxy
|
|
131
131
|
})
|
|
132
132
|
|
|
133
|
-
//
|
|
134
|
-
.onAction("loadUser", async ({ state, action, next }) => {
|
|
133
|
+
// Action handler: receives context object { action, state, next, context }
|
|
134
|
+
.onAction("loadUser", async ({ state, action, next, context }) => {
|
|
135
135
|
const userId = action.payload?.id;
|
|
136
136
|
state.user = await fetchUser(userId);
|
|
137
137
|
state.loading = false;
|
|
138
|
-
|
|
138
|
+
// State changes are auto-synced via Proxy
|
|
139
|
+
// next.router is available for programmatic navigation
|
|
139
140
|
})
|
|
140
141
|
|
|
141
|
-
.onAction("logout", ({ state
|
|
142
|
+
.onAction("logout", ({ state }) => {
|
|
142
143
|
state.user = null;
|
|
143
|
-
next();
|
|
144
144
|
})
|
|
145
145
|
|
|
146
|
-
//
|
|
147
|
-
.onDestroyed((
|
|
146
|
+
// Lifecycle handler: receives (state, context?)
|
|
147
|
+
.onDestroyed((state, context) => {
|
|
148
148
|
console.log("Cleanup");
|
|
149
149
|
})
|
|
150
150
|
|
|
151
151
|
.build();
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
State mutations are automatically tracked via Proxy and synced to the engine.
|
|
155
155
|
|
|
156
156
|
## State
|
|
157
157
|
|
|
@@ -346,6 +346,171 @@ const engine = new BrowserEngine();
|
|
|
346
346
|
await engine.init({ wasmPath: "/hypen_engine_bg.wasm" });
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
+
## Single-File Components
|
|
350
|
+
|
|
351
|
+
Use template literals with the `hypen`, `state`, `item`, and `index` helpers:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { app, hypen, state, item, index } from "@hypen-space/core";
|
|
355
|
+
|
|
356
|
+
export default app
|
|
357
|
+
.defineState({ items: ["A", "B", "C"] })
|
|
358
|
+
.ui(hypen`
|
|
359
|
+
Column {
|
|
360
|
+
ForEach(items: ${state.items}) {
|
|
361
|
+
Text("${index}: ${item}")
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
`);
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Error Handling
|
|
368
|
+
|
|
369
|
+
### Result Type
|
|
370
|
+
|
|
371
|
+
Type-safe error handling without exceptions:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import { Ok, Err, fromPromise, match, all, isOk, isErr } from "@hypen-space/core";
|
|
375
|
+
|
|
376
|
+
// Create results
|
|
377
|
+
const success = Ok(42);
|
|
378
|
+
const failure = Err(new Error("failed"));
|
|
379
|
+
|
|
380
|
+
// Pattern matching
|
|
381
|
+
const message = match(result, {
|
|
382
|
+
ok: (value) => `Got ${value}`,
|
|
383
|
+
err: (error) => `Failed: ${error.message}`,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Convert promises to Result
|
|
387
|
+
const result = await fromPromise(fetch("/api/data"));
|
|
388
|
+
|
|
389
|
+
// Combine multiple results
|
|
390
|
+
const combined = all([result1, result2, result3]);
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Module Error Handler
|
|
394
|
+
|
|
395
|
+
Handle errors in module actions:
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
app
|
|
399
|
+
.defineState({ error: null })
|
|
400
|
+
.onError(({ error, action, state }) => {
|
|
401
|
+
console.error(`Action ${action.name} failed:`, error);
|
|
402
|
+
state.error = error.message;
|
|
403
|
+
return { handled: true }; // Prevent error from propagating
|
|
404
|
+
})
|
|
405
|
+
.onAction("riskyAction", async ({ state }) => {
|
|
406
|
+
throw new Error("Something went wrong");
|
|
407
|
+
});
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## Session Lifecycle
|
|
411
|
+
|
|
412
|
+
Handle connection state for remote UI:
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
app
|
|
416
|
+
.defineState({ connected: true })
|
|
417
|
+
.onDisconnect(({ state, reason }) => {
|
|
418
|
+
state.connected = false;
|
|
419
|
+
console.log("Disconnected:", reason);
|
|
420
|
+
})
|
|
421
|
+
.onReconnect(({ state, wasExpired }) => {
|
|
422
|
+
state.connected = true;
|
|
423
|
+
if (wasExpired) {
|
|
424
|
+
// Session was restored from server
|
|
425
|
+
}
|
|
426
|
+
})
|
|
427
|
+
.onExpire(({ state, reason }) => {
|
|
428
|
+
// Session expired, need to re-authenticate
|
|
429
|
+
state.connected = false;
|
|
430
|
+
});
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Disposable Pattern
|
|
434
|
+
|
|
435
|
+
Resource management with automatic cleanup:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import { DisposableStack, using, disposableListener } from "@hypen-space/core";
|
|
439
|
+
|
|
440
|
+
// Automatic cleanup with using()
|
|
441
|
+
await using(new DisposableStack(), async (stack) => {
|
|
442
|
+
const listener = stack.use(
|
|
443
|
+
disposableListener(window, "resize", handleResize)
|
|
444
|
+
);
|
|
445
|
+
// listener is automatically removed when scope exits
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
// Manual stack management
|
|
449
|
+
const stack = new DisposableStack();
|
|
450
|
+
stack.use(disposableTimeout(() => {}, 1000));
|
|
451
|
+
stack.use(disposableInterval(() => {}, 100));
|
|
452
|
+
stack.dispose(); // Cleans up everything
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Retry Utilities
|
|
456
|
+
|
|
457
|
+
Retry failed operations with backoff:
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
import { retry, retryResult, RetryPresets } from "@hypen-space/core";
|
|
461
|
+
|
|
462
|
+
// Simple retry with exponential backoff
|
|
463
|
+
const data = await retry(
|
|
464
|
+
() => fetch("/api/data"),
|
|
465
|
+
{ maxAttempts: 3, backoff: "exponential" }
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
// Retry returning Result type
|
|
469
|
+
const result = await retryResult(
|
|
470
|
+
() => fetchData(),
|
|
471
|
+
RetryPresets.network // Pre-configured for network errors
|
|
472
|
+
);
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## Logger
|
|
476
|
+
|
|
477
|
+
Structured logging with levels:
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
import { createLogger, setLogLevel, Logger } from "@hypen-space/core";
|
|
481
|
+
|
|
482
|
+
const log = createLogger("MyModule");
|
|
483
|
+
|
|
484
|
+
log.debug("Detailed info");
|
|
485
|
+
log.info("Normal operation");
|
|
486
|
+
log.warn("Something unexpected");
|
|
487
|
+
log.error("Something failed", error);
|
|
488
|
+
|
|
489
|
+
// Configure globally
|
|
490
|
+
setLogLevel("warn"); // Only warn and error
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Typed Events
|
|
494
|
+
|
|
495
|
+
Type-safe event emitter:
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
import { TypedEventEmitter, createEventEmitter } from "@hypen-space/core";
|
|
499
|
+
|
|
500
|
+
interface MyEvents {
|
|
501
|
+
userLogin: { userId: string };
|
|
502
|
+
dataLoaded: { items: string[] };
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const events = createEventEmitter<MyEvents>();
|
|
506
|
+
|
|
507
|
+
events.on("userLogin", ({ userId }) => {
|
|
508
|
+
console.log("User logged in:", userId);
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
events.emit("userLogin", { userId: "123" });
|
|
512
|
+
```
|
|
513
|
+
|
|
349
514
|
## Package Exports
|
|
350
515
|
|
|
351
516
|
| Export | Description |
|
|
@@ -362,6 +527,12 @@ await engine.init({ wasmPath: "/hypen_engine_bg.wasm" });
|
|
|
362
527
|
| `@hypen-space/core/loader` | Component loader |
|
|
363
528
|
| `@hypen-space/core/discovery` | Component discovery |
|
|
364
529
|
| `@hypen-space/core/components` | Built-in Router, Route, Link |
|
|
530
|
+
| `@hypen-space/core/result` | Result type for error handling |
|
|
531
|
+
| `@hypen-space/core/disposable` | Disposable pattern utilities |
|
|
532
|
+
| `@hypen-space/core/retry` | Retry with backoff |
|
|
533
|
+
| `@hypen-space/core/logger` | Structured logging |
|
|
534
|
+
| `@hypen-space/core/events` | Typed event emitter |
|
|
535
|
+
| `@hypen-space/core/hypen` | Template helpers (hypen, state, item, index) |
|
|
365
536
|
|
|
366
537
|
## Requirements
|
|
367
538
|
|