@hypen-space/core 0.4.46 → 0.4.82
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 +8 -9
- package/dist/app.d.ts +56 -6
- package/dist/app.js +77 -8
- package/dist/app.js.map +4 -4
- package/dist/components/builtin.js +77 -8
- package/dist/components/builtin.js.map +4 -4
- package/dist/datasource.d.ts +4 -4
- package/dist/datasource.js.map +1 -1
- package/dist/engine-base.d.ts +193 -0
- package/dist/engine-base.js +540 -0
- package/dist/engine-base.js.map +12 -0
- package/dist/hypen.d.ts +24 -19
- package/dist/hypen.js +7 -7
- package/dist/hypen.js.map +3 -3
- package/dist/index.browser.js +86 -14
- package/dist/index.browser.js.map +6 -6
- package/dist/index.d.ts +3 -2
- package/dist/index.js +92 -20
- package/dist/index.js.map +7 -7
- package/dist/persistence.d.ts +21 -0
- package/dist/remote/client.d.ts +2 -0
- package/dist/remote/client.js +3 -2
- package/dist/remote/client.js.map +3 -3
- package/dist/remote/index.js +3 -2
- package/dist/remote/index.js.map +3 -3
- package/dist/remote/types.d.ts +2 -0
- package/dist/router.js +8 -6
- package/dist/router.js.map +3 -3
- package/package.json +7 -1
- package/src/app.ts +177 -29
- package/src/datasource.ts +4 -4
- package/src/engine-base.ts +358 -0
- package/src/hypen.ts +34 -28
- package/src/index.ts +8 -2
- package/src/persistence.ts +25 -0
- package/src/remote/client.ts +3 -0
- package/src/remote/types.ts +2 -0
- package/src/router.ts +13 -6
- package/src/types.ts +1 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for Hypen WASM engine wrappers.
|
|
3
|
+
*
|
|
4
|
+
* The Hypen engine is distributed as a wasm-bindgen module — two builds:
|
|
5
|
+
*
|
|
6
|
+
* - `wasm-node` (bundler target) — used by `@hypen-space/server` on Node/Bun
|
|
7
|
+
* - `wasm-browser` (web target) — used by `@hypen-space/web-engine` in browsers
|
|
8
|
+
*
|
|
9
|
+
* Both builds expose an identical `WasmEngine` class; the only genuine
|
|
10
|
+
* platform differences are:
|
|
11
|
+
*
|
|
12
|
+
* 1. How the WASM module is *instantiated*. Node can synchronously `new
|
|
13
|
+
* WasmEngine()` (the bundler target auto-initializes); the browser
|
|
14
|
+
* target needs an async dynamic import of the JS glue code and an
|
|
15
|
+
* explicit `wasm_init(url)` call before any `new WasmEngine()`.
|
|
16
|
+
*
|
|
17
|
+
* 2. How host state is *unwrapped* before it crosses the WASM boundary.
|
|
18
|
+
* Node can use `structuredClone` (with a `__getSnapshot` fast path for
|
|
19
|
+
* Hypen's proxy-backed state); the browser path does a
|
|
20
|
+
* `JSON.parse(JSON.stringify())` round-trip plus a Map-to-Object
|
|
21
|
+
* conversion for the native Map values that the wasm-bindgen browser
|
|
22
|
+
* target returns in action payloads.
|
|
23
|
+
*
|
|
24
|
+
* Everything else — method wrappers, error classification, callback wiring,
|
|
25
|
+
* revision plumbing — is identical between the two. That shared surface
|
|
26
|
+
* lives here.
|
|
27
|
+
*
|
|
28
|
+
* Subclasses implement two abstract hooks:
|
|
29
|
+
*
|
|
30
|
+
* - `init(options?): Promise<void>` — platform-specific WASM setup. Must
|
|
31
|
+
* assign `this.wasmEngine` and set `this.initialized = true` on success.
|
|
32
|
+
*
|
|
33
|
+
* - `unwrapForWasm<T>(value: T): T` — platform-specific proxy-to-plain
|
|
34
|
+
* conversion. Called before any value crosses into WASM.
|
|
35
|
+
*/
|
|
36
|
+
import type { Action, RenderCallback, ActionHandler, ComponentResolver } from "./types.js";
|
|
37
|
+
/**
|
|
38
|
+
* Shared base wrapping a wasm-bindgen `WasmEngine`. `any` here is load-
|
|
39
|
+
* bearing: the concrete type is `WasmEngine` from either the `wasm-node`
|
|
40
|
+
* or `wasm-browser` build, and those are separate generated `.d.ts`
|
|
41
|
+
* files that core cannot (and should not) depend on. Subclasses keep
|
|
42
|
+
* their own typed reference if they want stricter checking locally.
|
|
43
|
+
*/
|
|
44
|
+
export declare abstract class BaseEngine {
|
|
45
|
+
protected wasmEngine: any;
|
|
46
|
+
protected initialized: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Initialize the WASM module. Platform-specific.
|
|
49
|
+
*
|
|
50
|
+
* Must assign `this.wasmEngine` and set `this.initialized = true`.
|
|
51
|
+
* Idempotent: must early-return if already initialized.
|
|
52
|
+
*/
|
|
53
|
+
abstract init(options?: unknown): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Convert a host value (possibly a Proxy, possibly containing Maps,
|
|
56
|
+
* possibly wrapped in Hypen's observable state) into a plain-object
|
|
57
|
+
* form safe to pass across the WASM boundary.
|
|
58
|
+
*
|
|
59
|
+
* Called on every `updateState` / `updateStateSparse` / `renderInto`
|
|
60
|
+
* / `setContext` / `registerModule` entry point.
|
|
61
|
+
*/
|
|
62
|
+
protected abstract unwrapForWasm<T>(value: T): T;
|
|
63
|
+
/**
|
|
64
|
+
* Guard that throws if the engine hasn't been initialized.
|
|
65
|
+
* Returns the underlying WASM engine for chained access.
|
|
66
|
+
*/
|
|
67
|
+
protected ensureInitialized(): any;
|
|
68
|
+
/**
|
|
69
|
+
* Set the render callback that receives patches.
|
|
70
|
+
*/
|
|
71
|
+
setRenderCallback(callback: RenderCallback): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set the component resolver for dynamic component composition.
|
|
74
|
+
*/
|
|
75
|
+
setComponentResolver(resolver: ComponentResolver): void;
|
|
76
|
+
/**
|
|
77
|
+
* Parse and render Hypen DSL source code.
|
|
78
|
+
* @throws {ParseError} if the source fails to parse
|
|
79
|
+
* @throws {RenderError} if rendering fails
|
|
80
|
+
*/
|
|
81
|
+
renderSource(source: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Render a lazy component (for lazy route loading).
|
|
84
|
+
*/
|
|
85
|
+
renderLazyComponent(source: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Render a component into a specific parent node (subtree rendering).
|
|
88
|
+
* @throws {ParseError} if the source fails to parse
|
|
89
|
+
* @throws {RenderError} if the parent node is not found or rendering fails
|
|
90
|
+
*/
|
|
91
|
+
renderInto(source: string, parentNodeId: string, state: Record<string, any>): void;
|
|
92
|
+
/**
|
|
93
|
+
* Apply a sparse state update.
|
|
94
|
+
*
|
|
95
|
+
* @param scope Lowercase module name to target a named module registered
|
|
96
|
+
* via `registerModule`. Pass `null` (or empty string) to
|
|
97
|
+
* target the primary module set via `setModule`.
|
|
98
|
+
* @param paths Changed state paths (relative to the targeted module).
|
|
99
|
+
* @param values Map of `path -> new value`.
|
|
100
|
+
* @throws {StateError} if the state patch is invalid
|
|
101
|
+
*/
|
|
102
|
+
updateStateSparse(scope: string | null, paths: string[], values: Record<string, any>): void;
|
|
103
|
+
/**
|
|
104
|
+
* Apply a full-state patch. See [updateStateSparse] for `scope` semantics.
|
|
105
|
+
* Prefer the sparse form when only a few paths changed.
|
|
106
|
+
*/
|
|
107
|
+
updateState(scope: string | null, statePatch: Record<string, any>): void;
|
|
108
|
+
/**
|
|
109
|
+
* Dispatch an action.
|
|
110
|
+
* @throws {HypenError} if the action dispatch fails
|
|
111
|
+
*/
|
|
112
|
+
dispatchAction(name: string, payload?: any): void;
|
|
113
|
+
/**
|
|
114
|
+
* Register an action handler. Errors thrown synchronously or via rejected
|
|
115
|
+
* promises are caught and logged at the framework level; caller-side error
|
|
116
|
+
* recovery should happen inside `handler`.
|
|
117
|
+
*
|
|
118
|
+
* Action payloads may contain platform-specific native values (e.g. Maps
|
|
119
|
+
* in the browser target). Subclasses can override `normalizeAction` to
|
|
120
|
+
* pre-process the action before calling the user handler.
|
|
121
|
+
*/
|
|
122
|
+
onAction(actionName: string, handler: ActionHandler): void;
|
|
123
|
+
/**
|
|
124
|
+
* Platform hook: normalize an incoming action before the user handler
|
|
125
|
+
* sees it. Default identity; subclasses can override to unwrap native
|
|
126
|
+
* values (e.g. browser Maps in action payloads).
|
|
127
|
+
*/
|
|
128
|
+
protected normalizeAction(action: Action): Action;
|
|
129
|
+
/**
|
|
130
|
+
* Initialize the primary module.
|
|
131
|
+
*/
|
|
132
|
+
setModule(name: string, actions: string[], stateKeys: string[], initialState: Record<string, any>): void;
|
|
133
|
+
/**
|
|
134
|
+
* Register a named module for multi-module apps.
|
|
135
|
+
*
|
|
136
|
+
* Unlike setModule which sets the primary module, this registers an
|
|
137
|
+
* additional module whose state is scoped to `module <name> { ... }`
|
|
138
|
+
* blocks in the DSL.
|
|
139
|
+
*/
|
|
140
|
+
registerModule(name: string, actions: string[], stateKeys: string[], initialState: Record<string, any>): void;
|
|
141
|
+
/**
|
|
142
|
+
* Get the current revision number.
|
|
143
|
+
*
|
|
144
|
+
* Note: the underlying WASM builder returns `bigint` in some targets
|
|
145
|
+
* and `number` in others; this normalizes to `number` for consumer
|
|
146
|
+
* ergonomics (revision counts don't exceed 2^53).
|
|
147
|
+
*/
|
|
148
|
+
getRevision(): number;
|
|
149
|
+
/**
|
|
150
|
+
* Clear resolved components and caches, preserving primitives and resolver.
|
|
151
|
+
* Call before renderSource() during hot-reload so components are re-resolved
|
|
152
|
+
* from fresh source files.
|
|
153
|
+
*/
|
|
154
|
+
clearResolvedComponents(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Clear the engine tree.
|
|
157
|
+
*/
|
|
158
|
+
clearTree(): void;
|
|
159
|
+
/**
|
|
160
|
+
* Full reset: clears tree, module, component registry, dependencies,
|
|
161
|
+
* and revision. Render callback and component resolver are preserved.
|
|
162
|
+
*/
|
|
163
|
+
reset(): void;
|
|
164
|
+
/**
|
|
165
|
+
* Debug method to inspect parsed components.
|
|
166
|
+
*/
|
|
167
|
+
debugParseComponent(source: string): string;
|
|
168
|
+
/**
|
|
169
|
+
* Set (or replace) a named data source context.
|
|
170
|
+
*
|
|
171
|
+
* Registers the provider in the dependency graph, stores the data,
|
|
172
|
+
* and re-renders every node bound to `$name.*`.
|
|
173
|
+
*
|
|
174
|
+
* @param name - Provider name (e.g., "spacetime", "firebase")
|
|
175
|
+
* @param data - Full state object for this provider
|
|
176
|
+
*/
|
|
177
|
+
setContext(name: string, data: Record<string, unknown>): void;
|
|
178
|
+
/**
|
|
179
|
+
* Remove a data source context entirely.
|
|
180
|
+
* Drops the provider's state and re-renders bound nodes (they resolve to null).
|
|
181
|
+
*/
|
|
182
|
+
removeContext(name: string): void;
|
|
183
|
+
/**
|
|
184
|
+
* Register resources (name → raw SVG string) with the engine.
|
|
185
|
+
*
|
|
186
|
+
* Each SVG is parsed by the WASM engine. When the engine encounters
|
|
187
|
+
* `Icon(@resources.heart)` in the DSL, it resolves the name from registered
|
|
188
|
+
* resources and injects SVG path data into the Create patch props.
|
|
189
|
+
*
|
|
190
|
+
* @param map - Flat map of resource name to raw SVG string
|
|
191
|
+
*/
|
|
192
|
+
registerResources(map: Record<string, string>): void;
|
|
193
|
+
}
|