@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypen-space/web",
3
- "version": "0.3.12",
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.3.10"
58
+ "@hypen-space/core": "^0.4.1"
52
59
  },
53
60
  "devDependencies": {
54
61
  "@types/bun": "latest",
@@ -118,7 +118,7 @@ Column {
118
118
  // Horizontal layout
119
119
  Row {
120
120
  gap: 5
121
- justifyContent: center
121
+ horizontalAlignment: center
122
122
 
123
123
  Text("Left")
124
124
  Text("Right")
@@ -89,8 +89,8 @@ Implements a flexbox-like layout system:
89
89
 
90
90
  **Supported Properties:**
91
91
  - `flexDirection`: "row" | "column"
92
- - `justifyContent`: "flex-start" | "center" | "flex-end" | "space-between" | "space-around"
93
- - `alignItems`: "flex-start" | "center" | "flex-end" | "stretch"
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.
@@ -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 === "spacer") {
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 justifyContent = props.justifyContent || "flex-start";
173
- const alignItems = props.alignItems || "flex-start";
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
- const alignItems = props.alignItems || "flex-start";
349
- const justifyContent = props.justifyContent || "flex-start";
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 (alignItems === "center") {
384
+ if (horizontalAlignment === "center") {
374
385
  x = (availableWidth - childLayout.width) / 2;
375
- } else if (alignItems === "flex-end") {
386
+ } else if (horizontalAlignment === "flex-end") {
376
387
  x = availableWidth - childLayout.width;
377
388
  }
378
389
 
379
390
  // Vertical alignment
380
- if (justifyContent === "center") {
391
+ if (verticalAlignment === "center") {
381
392
  y = (availableHeight - childLayout.height) / 2;
382
- } else if (justifyContent === "flex-end") {
393
+ } else if (verticalAlignment === "flex-end") {
383
394
  y = availableHeight - childLayout.height;
384
395
  }
385
396
 
@@ -105,6 +105,7 @@ export function paintNode(ctx: CanvasRenderingContext2D, node: VirtualNode): voi
105
105
  case "link":
106
106
  paintLink(ctx, node);
107
107
  break;
108
+ case "app":
108
109
  case "container":
109
110
  case "box":
110
111
  paintContainer(ctx, node);
@@ -4,8 +4,9 @@
4
4
  * Main renderer class that orchestrates layout, painting, and events
5
5
  */
6
6
 
7
- import type { Renderer, Patch } from "@hypen-space/core";
8
- import { frameworkLoggers } from "@hypen-space/core";
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
 
@@ -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/remote";
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);
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { ComponentHandler } from "./index.js";
7
- import { frameworkLoggers } from "@hypen-space/core";
7
+ import { frameworkLoggers } from "@hypen-space/core/logger";
8
8
 
9
9
  const log = frameworkLoggers.router;
10
10
 
package/src/dom/debug.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Provides heatmap overlays to visualize re-renders
5
5
  */
6
6
 
7
- import { frameworkLoggers } from "@hypen-space/core";
7
+ import { frameworkLoggers } from "@hypen-space/core/logger";
8
8
 
9
9
  const log = frameworkLoggers.debug;
10
10
 
package/src/dom/events.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Handles DOM event binding and action dispatching
5
5
  */
6
6
 
7
- import { frameworkLoggers } from "@hypen-space/core";
7
+ import { frameworkLoggers } from "@hypen-space/core/logger";
8
8
 
9
9
  const log = frameworkLoggers.events;
10
10
 
@@ -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
- BrowserEngine as Engine,
9
- HypenModuleInstance,
10
- HypenRouter,
11
- HypenGlobalContext,
12
- componentLoader,
13
- Router,
14
- Route,
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
- * Requires @hypen-space/core for the engine and state management.
5
+ * This entry point is WASM-free it only contains renderers and the remote UI
6
+ * embed component.
6
7
  *
7
- * ## Quick Start
8
+ * For client-side rendering (with WASM engine), use "@hypen-space/web/client":
8
9
  *
9
10
  * ```typescript
10
- * import { Engine, app } from "@hypen-space/core";
11
- * import { DOMRenderer } from "@hypen/web";
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
- * // Set up patch callback
22
- * engine.setRenderCallback((patches) => {
23
- * renderer.applyPatches(patches);
24
- * });
15
+ * For remote UI (no WASM needed in the browser):
25
16
  *
26
- * // Render your app
27
- * engine.renderSource(`Column { Text("Hello Hypen!") }`);
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";