@hypen-space/web 0.3.12 → 0.4.1
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/dist/canvas/index.js.map +2 -2
- package/dist/canvas/renderer.js.map +2 -2
- package/dist/client.js +3819 -0
- package/dist/client.js.map +62 -0
- package/dist/dom/components/hypenapp.js.map +1 -1
- package/dist/dom/components/index.js.map +1 -1
- package/dist/dom/index.js.map +2 -2
- package/dist/dom/renderer.js.map +2 -2
- package/dist/hypen.js +8 -13
- package/dist/hypen.js.map +5 -5
- package/dist/index.js +20 -329
- package/dist/index.js.map +7 -8
- package/package.json +9 -2
- package/src/canvas/QUICKSTART.md +1 -1
- package/src/canvas/README.md +2 -2
- package/src/canvas/layout.ts +21 -10
- package/src/canvas/paint.ts +1 -0
- package/src/canvas/renderer.ts +3 -2
- package/src/canvas/text.ts +1 -1
- package/src/client.ts +20 -0
- package/src/dom/applicators/advanced-layout.ts +0 -8
- package/src/dom/applicators/events.ts +2 -1
- package/src/dom/components/app.ts +20 -0
- package/src/dom/components/hypenapp.ts +4 -6
- package/src/dom/components/index.ts +2 -0
- package/src/dom/components/route.ts +1 -1
- package/src/dom/debug.ts +1 -1
- package/src/dom/events.ts +1 -1
- package/src/dom/renderer.ts +5 -5
- package/src/hypen.ts +10 -16
- package/src/index.ts +10 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypen-space/web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Hypen web renderers - DOM and Canvas rendering for browsers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,6 +29,13 @@
|
|
|
29
29
|
"import": "./dist/canvas/index.js",
|
|
30
30
|
"default": "./dist/canvas/index.js"
|
|
31
31
|
},
|
|
32
|
+
"./client": {
|
|
33
|
+
"types": "./dist/client.d.ts",
|
|
34
|
+
"browser": "./dist/client.js",
|
|
35
|
+
"bun": "./src/client.ts",
|
|
36
|
+
"import": "./dist/client.js",
|
|
37
|
+
"default": "./dist/client.js"
|
|
38
|
+
},
|
|
32
39
|
"./hypen": {
|
|
33
40
|
"types": "./dist/hypen.d.ts",
|
|
34
41
|
"browser": "./dist/hypen.js",
|
|
@@ -48,7 +55,7 @@
|
|
|
48
55
|
"clean": "rm -rf dist"
|
|
49
56
|
},
|
|
50
57
|
"dependencies": {
|
|
51
|
-
"@hypen-space/core": "^0.
|
|
58
|
+
"@hypen-space/core": "^0.4.1"
|
|
52
59
|
},
|
|
53
60
|
"devDependencies": {
|
|
54
61
|
"@types/bun": "latest",
|
package/src/canvas/QUICKSTART.md
CHANGED
package/src/canvas/README.md
CHANGED
|
@@ -89,8 +89,8 @@ Implements a flexbox-like layout system:
|
|
|
89
89
|
|
|
90
90
|
**Supported Properties:**
|
|
91
91
|
- `flexDirection`: "row" | "column"
|
|
92
|
-
- `
|
|
93
|
-
- `
|
|
92
|
+
- `verticalAlignment`: "start" | "center" | "end" | "space-between" | "space-around" (main axis for Column, cross axis for Row)
|
|
93
|
+
- `horizontalAlignment`: "start" | "center" | "end" | "space-between" | "space-around" (cross axis for Column, main axis for Row)
|
|
94
94
|
- `gap`: spacing between children
|
|
95
95
|
- `padding`, `margin`: box spacing
|
|
96
96
|
- `width`, `height`, `minWidth`, `maxWidth`, etc.
|
package/src/canvas/layout.ts
CHANGED
|
@@ -53,7 +53,11 @@ export function computeLayout(
|
|
|
53
53
|
// Default sizing for specific component types
|
|
54
54
|
const type = node.type.toLowerCase();
|
|
55
55
|
|
|
56
|
-
if (type === "
|
|
56
|
+
if (type === "app") {
|
|
57
|
+
// App fills the full available space by default
|
|
58
|
+
if (width === null) width = availableAfterMargin.width;
|
|
59
|
+
if (height === null) height = availableAfterMargin.height;
|
|
60
|
+
} else if (type === "spacer") {
|
|
57
61
|
// Spacer fills available space by default
|
|
58
62
|
if (width === null) width = availableAfterMargin.width;
|
|
59
63
|
if (height === null) height = availableAfterMargin.height;
|
|
@@ -169,11 +173,17 @@ function layoutChildren(ctx: CanvasRenderingContext2D, parent: VirtualNode): voi
|
|
|
169
173
|
}
|
|
170
174
|
|
|
171
175
|
const flexDirection = props.flexDirection || (parent.type === "column" ? "column" : "row");
|
|
172
|
-
const
|
|
173
|
-
|
|
176
|
+
const isColumn = flexDirection === "column";
|
|
177
|
+
|
|
178
|
+
// Resolve verticalAlignment/horizontalAlignment to main/cross axis based on direction
|
|
179
|
+
const justifyContent = isColumn
|
|
180
|
+
? (props.verticalAlignment || "flex-start")
|
|
181
|
+
: (props.horizontalAlignment || "flex-start");
|
|
182
|
+
const alignItems = isColumn
|
|
183
|
+
? (props.horizontalAlignment || "flex-start")
|
|
184
|
+
: (props.verticalAlignment || "flex-start");
|
|
174
185
|
const gap = parseFloat(props.gap) || 0;
|
|
175
186
|
|
|
176
|
-
const isColumn = flexDirection === "column";
|
|
177
187
|
const availableWidth = layout.contentWidth;
|
|
178
188
|
const availableHeight = layout.contentHeight;
|
|
179
189
|
|
|
@@ -345,8 +355,9 @@ function layoutStackChildren(ctx: CanvasRenderingContext2D, parent: VirtualNode)
|
|
|
345
355
|
const layout = parent.layout!;
|
|
346
356
|
const props = parent.props;
|
|
347
357
|
|
|
348
|
-
|
|
349
|
-
const
|
|
358
|
+
// Stack uses horizontalAlignment/verticalAlignment directly
|
|
359
|
+
const horizontalAlignment = props.horizontalAlignment || "flex-start";
|
|
360
|
+
const verticalAlignment = props.verticalAlignment || "flex-start";
|
|
350
361
|
|
|
351
362
|
const availableWidth = layout.contentWidth;
|
|
352
363
|
const availableHeight = layout.contentHeight;
|
|
@@ -370,16 +381,16 @@ function layoutStackChildren(ctx: CanvasRenderingContext2D, parent: VirtualNode)
|
|
|
370
381
|
let y = 0;
|
|
371
382
|
|
|
372
383
|
// Horizontal alignment
|
|
373
|
-
if (
|
|
384
|
+
if (horizontalAlignment === "center") {
|
|
374
385
|
x = (availableWidth - childLayout.width) / 2;
|
|
375
|
-
} else if (
|
|
386
|
+
} else if (horizontalAlignment === "flex-end") {
|
|
376
387
|
x = availableWidth - childLayout.width;
|
|
377
388
|
}
|
|
378
389
|
|
|
379
390
|
// Vertical alignment
|
|
380
|
-
if (
|
|
391
|
+
if (verticalAlignment === "center") {
|
|
381
392
|
y = (availableHeight - childLayout.height) / 2;
|
|
382
|
-
} else if (
|
|
393
|
+
} else if (verticalAlignment === "flex-end") {
|
|
383
394
|
y = availableHeight - childLayout.height;
|
|
384
395
|
}
|
|
385
396
|
|
package/src/canvas/paint.ts
CHANGED
package/src/canvas/renderer.ts
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Main renderer class that orchestrates layout, painting, and events
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { Renderer
|
|
8
|
-
import {
|
|
7
|
+
import type { Renderer } from "@hypen-space/core/renderer";
|
|
8
|
+
import type { Patch } from "@hypen-space/core/types";
|
|
9
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
9
10
|
|
|
10
11
|
const log = frameworkLoggers.canvas;
|
|
11
12
|
|
package/src/canvas/text.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { FontStyle, TextMetrics, TextStyle } from "./types.js";
|
|
8
8
|
import { createFontString } from "./utils.js";
|
|
9
|
-
import { frameworkLoggers } from "@hypen-space/core";
|
|
9
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
10
10
|
|
|
11
11
|
const log = frameworkLoggers.canvas;
|
|
12
12
|
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hypen-space/web/client - Client-side rendering with WASM engine
|
|
3
|
+
*
|
|
4
|
+
* This entry point includes the Hypen orchestrator which connects the
|
|
5
|
+
* BrowserEngine (WASM) with the DOM renderer. Use this when you want
|
|
6
|
+
* to run the engine client-side in the browser.
|
|
7
|
+
*
|
|
8
|
+
* For remote UI (server-side engine, no WASM in browser), use the
|
|
9
|
+
* default import from "@hypen-space/web" instead.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { render } from "@hypen-space/web/client";
|
|
14
|
+
*
|
|
15
|
+
* await render("Counter", "#app");
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { Hypen, render, renderWithComponents } from "./hypen.js";
|
|
20
|
+
export type { HypenConfig } from "./hypen.js";
|
|
@@ -19,14 +19,6 @@ export const advancedLayoutHandlers: Record<string, ApplicatorHandler> = {
|
|
|
19
19
|
el.style.flexBasis = typeof value === "number" ? `${value}px` : String(value);
|
|
20
20
|
},
|
|
21
21
|
|
|
22
|
-
justifyContent: (el, value) => {
|
|
23
|
-
el.style.justifyContent = mapAlignmentValue(String(value));
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
alignItems: (el, value) => {
|
|
27
|
-
el.style.alignItems = mapAlignmentValue(String(value));
|
|
28
|
-
},
|
|
29
|
-
|
|
30
22
|
alignContent: (el, value) => {
|
|
31
23
|
el.style.alignContent = String(value);
|
|
32
24
|
},
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
disposableTimeout,
|
|
13
13
|
type Disposable,
|
|
14
14
|
} from "@hypen-space/core/disposable";
|
|
15
|
-
import { frameworkLoggers } from "@hypen-space/core";
|
|
15
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
16
16
|
import {
|
|
17
17
|
type IEngine,
|
|
18
18
|
getEngine,
|
|
@@ -483,6 +483,7 @@ export const eventHandlers: Record<string, ApplicatorHandler> = {
|
|
|
483
483
|
|
|
484
484
|
// Long click/press
|
|
485
485
|
onLongClick: createLongClickHandler(500),
|
|
486
|
+
onLongPress: createLongClickHandler(500), // Alias for mobile-style naming
|
|
486
487
|
|
|
487
488
|
// Focus events
|
|
488
489
|
onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Component - Root application container
|
|
3
|
+
*
|
|
4
|
+
* Full-screen vertical flex container. This is the default root component
|
|
5
|
+
* created by `hypen init` and referenced in docs/examples.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ComponentHandler } from "./index.js";
|
|
9
|
+
|
|
10
|
+
export const appHandler: ComponentHandler = {
|
|
11
|
+
create(): HTMLElement {
|
|
12
|
+
const el = document.createElement("div");
|
|
13
|
+
el.style.display = "flex";
|
|
14
|
+
el.style.flexDirection = "column";
|
|
15
|
+
el.style.minHeight = "100vh";
|
|
16
|
+
el.style.width = "100%";
|
|
17
|
+
el.dataset.hypenType = "app";
|
|
18
|
+
return el;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
import type { ComponentHandler } from "./index.js";
|
|
16
16
|
import { RemoteEngine } from "@hypen-space/core/remote/client";
|
|
17
|
-
import type { Patch } from "@hypen-space/core/
|
|
18
|
-
import { frameworkLoggers } from "@hypen-space/core";
|
|
17
|
+
import type { Patch } from "@hypen-space/core/types";
|
|
18
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
19
19
|
|
|
20
20
|
const log = frameworkLoggers.remote;
|
|
21
21
|
|
|
@@ -158,7 +158,7 @@ function applyPatches(
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
case "insert": {
|
|
161
|
-
const parentId = patch.parentId
|
|
161
|
+
const parentId = patch.parentId!;
|
|
162
162
|
const parent = parentId === "root" ? container : nodes.get(parentId);
|
|
163
163
|
const child = nodes.get(patch.id!);
|
|
164
164
|
const beforeId = patch.beforeId;
|
|
@@ -183,7 +183,7 @@ function applyPatches(
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
case "move": {
|
|
186
|
-
const parentId = patch.parentId
|
|
186
|
+
const parentId = patch.parentId!;
|
|
187
187
|
const parent = parentId === "root" ? container : nodes.get(parentId);
|
|
188
188
|
const child = nodes.get(patch.id!);
|
|
189
189
|
const beforeId = patch.beforeId;
|
|
@@ -311,8 +311,6 @@ function applyProp(el: HTMLElement, name: string, value: any): void {
|
|
|
311
311
|
border: "border",
|
|
312
312
|
gap: "gap",
|
|
313
313
|
flex: "flex",
|
|
314
|
-
alignItems: "alignItems",
|
|
315
|
-
justifyContent: "justifyContent",
|
|
316
314
|
opacity: "opacity",
|
|
317
315
|
overflow: "overflow",
|
|
318
316
|
};
|
|
@@ -80,7 +80,9 @@ export class ComponentRegistry {
|
|
|
80
80
|
const { routerHandler } = require("./router.js");
|
|
81
81
|
const { routeHandler } = require("./route.js");
|
|
82
82
|
const { hypenAppHandler } = require("./hypenapp.js");
|
|
83
|
+
const { appHandler } = require("./app.js");
|
|
83
84
|
|
|
85
|
+
this.register("app", appHandler);
|
|
84
86
|
this.register("column", columnHandler);
|
|
85
87
|
this.register("row", rowHandler);
|
|
86
88
|
this.register("text", textHandler);
|
package/src/dom/debug.ts
CHANGED
package/src/dom/events.ts
CHANGED
package/src/dom/renderer.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Renders Hypen patches to the DOM
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { Patch } from "@hypen-space/core";
|
|
8
|
-
import type { HypenModuleInstance, RouterContext } from "@hypen-space/core";
|
|
9
|
-
import type { HypenRouter } from "@hypen-space/core";
|
|
10
|
-
import type { HypenGlobalContext } from "@hypen-space/core";
|
|
11
|
-
import { frameworkLoggers } from "@hypen-space/core";
|
|
7
|
+
import type { Patch } from "@hypen-space/core/types";
|
|
8
|
+
import type { HypenModuleInstance, RouterContext } from "@hypen-space/core/app";
|
|
9
|
+
import type { HypenRouter } from "@hypen-space/core/router";
|
|
10
|
+
import type { HypenGlobalContext } from "@hypen-space/core/context";
|
|
11
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
12
12
|
|
|
13
13
|
const log = frameworkLoggers.renderer;
|
|
14
14
|
import { ComponentRegistry } from "./components/index.js";
|
package/src/hypen.ts
CHANGED
|
@@ -4,20 +4,14 @@
|
|
|
4
4
|
* Simple API for rendering Hypen applications (like ReactDOM.render)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Link,
|
|
16
|
-
frameworkLoggers,
|
|
17
|
-
setDebugMode,
|
|
18
|
-
type RouterContext,
|
|
19
|
-
type HypenModuleDefinition,
|
|
20
|
-
} from "@hypen-space/core";
|
|
7
|
+
import { Engine } from "@hypen-space/core/engine/browser";
|
|
8
|
+
import { HypenModuleInstance } from "@hypen-space/core/app";
|
|
9
|
+
import type { RouterContext, HypenModuleDefinition } from "@hypen-space/core/app";
|
|
10
|
+
import { HypenRouter } from "@hypen-space/core/router";
|
|
11
|
+
import { HypenGlobalContext } from "@hypen-space/core/context";
|
|
12
|
+
import { componentLoader } from "@hypen-space/core/loader";
|
|
13
|
+
import { Router, Route, Link } from "@hypen-space/core/components";
|
|
14
|
+
import { frameworkLoggers, setDebugMode } from "@hypen-space/core/logger";
|
|
21
15
|
import { DOMRenderer } from "./dom/renderer.js";
|
|
22
16
|
import type { DebugConfig } from "./dom/debug.js";
|
|
23
17
|
|
|
@@ -519,7 +513,7 @@ export class Hypen {
|
|
|
519
513
|
*
|
|
520
514
|
* @example
|
|
521
515
|
* ```typescript
|
|
522
|
-
* import { render } from "@hypen-space/web";
|
|
516
|
+
* import { render } from "@hypen-space/web/client";
|
|
523
517
|
*
|
|
524
518
|
* await render("HomePage", "#app");
|
|
525
519
|
* ```
|
|
@@ -541,7 +535,7 @@ export async function render(
|
|
|
541
535
|
*
|
|
542
536
|
* @example
|
|
543
537
|
* ```typescript
|
|
544
|
-
* import { renderWithComponents } from "@hypen-space/web";
|
|
538
|
+
* import { renderWithComponents } from "@hypen-space/web/client";
|
|
545
539
|
* import HomePage from "./components/HomePage/component";
|
|
546
540
|
* import homePageTemplate from "./components/HomePage/component.hypen";
|
|
547
541
|
*
|
package/src/index.ts
CHANGED
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @hypen/web - Hypen Web Renderers
|
|
2
|
+
* @hypen-space/web - Hypen Web Renderers
|
|
3
3
|
*
|
|
4
4
|
* Browser-only package providing DOM and Canvas rendering for Hypen applications.
|
|
5
|
-
*
|
|
5
|
+
* This entry point is WASM-free — it only contains renderers and the remote UI
|
|
6
|
+
* embed component.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
+
* For client-side rendering (with WASM engine), use "@hypen-space/web/client":
|
|
8
9
|
*
|
|
9
10
|
* ```typescript
|
|
10
|
-
* import {
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* // Initialize engine
|
|
14
|
-
* const engine = new Engine();
|
|
15
|
-
* await engine.init({ wasmPath: "/hypen_engine_bg.wasm" });
|
|
16
|
-
*
|
|
17
|
-
* // Create renderer
|
|
18
|
-
* const container = document.getElementById("app")!;
|
|
19
|
-
* const renderer = new DOMRenderer(container, engine);
|
|
11
|
+
* import { render } from "@hypen-space/web/client";
|
|
12
|
+
* await render("Counter", "#app");
|
|
13
|
+
* ```
|
|
20
14
|
*
|
|
21
|
-
*
|
|
22
|
-
* engine.setRenderCallback((patches) => {
|
|
23
|
-
* renderer.applyPatches(patches);
|
|
24
|
-
* });
|
|
15
|
+
* For remote UI (no WASM needed in the browser):
|
|
25
16
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { DOMRenderer } from "@hypen-space/web";
|
|
28
19
|
* ```
|
|
29
20
|
*/
|
|
30
21
|
|
|
@@ -47,20 +38,3 @@ export { hypenAppHandler, disconnectHypenApp } from "./dom/components/hypenapp.j
|
|
|
47
38
|
|
|
48
39
|
export { CanvasRenderer } from "./canvas/renderer.js";
|
|
49
40
|
export { canvasHandler, canvasApplicators } from "./dom/canvas/index.js";
|
|
50
|
-
|
|
51
|
-
// ============================================================================
|
|
52
|
-
// HIGH-LEVEL API
|
|
53
|
-
// ============================================================================
|
|
54
|
-
|
|
55
|
-
export { Hypen, render, renderWithComponents } from "./hypen.js";
|
|
56
|
-
export type { HypenConfig } from "./hypen.js";
|
|
57
|
-
|
|
58
|
-
// Re-export core types that web users commonly need
|
|
59
|
-
export type {
|
|
60
|
-
Patch,
|
|
61
|
-
Action,
|
|
62
|
-
Renderer,
|
|
63
|
-
RouterContext,
|
|
64
|
-
HypenModuleInstance,
|
|
65
|
-
HypenGlobalContext,
|
|
66
|
-
} from "@hypen-space/core";
|