@hypen-space/core 0.2.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.
Files changed (49) hide show
  1. package/dist/chunk-5va59f7m.js +22 -0
  2. package/dist/chunk-5va59f7m.js.map +9 -0
  3. package/dist/engine.d.ts +101 -0
  4. package/dist/events.d.ts +78 -0
  5. package/dist/index.browser.d.ts +13 -0
  6. package/dist/index.d.ts +33 -0
  7. package/dist/remote/index.d.ts +6 -0
  8. package/dist/router.d.ts +93 -0
  9. package/dist/src/app.js +160 -0
  10. package/dist/src/app.js.map +10 -0
  11. package/dist/src/context.js +114 -0
  12. package/dist/src/context.js.map +10 -0
  13. package/dist/src/engine.browser.js +130 -0
  14. package/dist/src/engine.browser.js.map +10 -0
  15. package/dist/src/engine.js +101 -0
  16. package/dist/src/engine.js.map +10 -0
  17. package/dist/src/events.js +72 -0
  18. package/dist/src/events.js.map +10 -0
  19. package/dist/src/index.browser.js +51 -0
  20. package/dist/src/index.browser.js.map +9 -0
  21. package/dist/src/index.js +55 -0
  22. package/dist/src/index.js.map +9 -0
  23. package/dist/src/remote/client.js +176 -0
  24. package/dist/src/remote/client.js.map +10 -0
  25. package/dist/src/remote/index.js +9 -0
  26. package/dist/src/remote/index.js.map +9 -0
  27. package/dist/src/remote/types.js +2 -0
  28. package/dist/src/remote/types.js.map +9 -0
  29. package/dist/src/renderer.js +58 -0
  30. package/dist/src/renderer.js.map +10 -0
  31. package/dist/src/router.js +189 -0
  32. package/dist/src/router.js.map +10 -0
  33. package/dist/src/state.js +226 -0
  34. package/dist/src/state.js.map +10 -0
  35. package/dist/state.d.ts +30 -0
  36. package/package.json +124 -0
  37. package/src/app.ts +330 -0
  38. package/src/context.ts +201 -0
  39. package/src/engine.browser.ts +245 -0
  40. package/src/engine.ts +208 -0
  41. package/src/events.ts +126 -0
  42. package/src/index.browser.ts +104 -0
  43. package/src/index.ts +126 -0
  44. package/src/remote/client.ts +274 -0
  45. package/src/remote/index.ts +17 -0
  46. package/src/remote/types.ts +51 -0
  47. package/src/renderer.ts +102 -0
  48. package/src/router.ts +311 -0
  49. package/src/state.ts +363 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Browser-compatible wrapper around the WASM engine
3
+ * Uses web target for browser environments
4
+ */
5
+
6
+ // Dynamic import path - will be configured at build time
7
+ // For browser, the WASM needs to be served and initialized explicitly
8
+ let wasmInit: ((path?: string) => Promise<void>) | null = null;
9
+ let WasmEngineClass: any = null;
10
+
11
+ export type Patch = {
12
+ type: "create" | "setProp" | "setText" | "insert" | "move" | "remove" | "attachEvent" | "detachEvent";
13
+ id?: string;
14
+ element_type?: string;
15
+ props?: Record<string, any> | Map<string, any>;
16
+ name?: string;
17
+ value?: any;
18
+ text?: string;
19
+ parent_id?: string;
20
+ before_id?: string;
21
+ event_name?: string;
22
+ };
23
+
24
+ export type Action = {
25
+ name: string;
26
+ payload?: any;
27
+ sender?: string;
28
+ };
29
+
30
+ export type RenderCallback = (patches: Patch[]) => void;
31
+ export type ActionHandler = (action: Action) => void | Promise<void>;
32
+
33
+ export type ResolvedComponent = {
34
+ source: string;
35
+ path: string;
36
+ };
37
+
38
+ export type ComponentResolver = (
39
+ componentName: string,
40
+ contextPath: string | null
41
+ ) => ResolvedComponent | null;
42
+
43
+ export interface EngineInitOptions {
44
+ /** Path to the WASM file (default: "/hypen_engine_bg.wasm") */
45
+ wasmPath?: string;
46
+ }
47
+
48
+ /**
49
+ * Recursively convert Maps and nested structures to plain objects
50
+ */
51
+ function mapToObject(value: any): any {
52
+ if (value instanceof Map) {
53
+ const obj: Record<string, any> = {};
54
+ for (const [key, val] of value.entries()) {
55
+ obj[key] = mapToObject(val);
56
+ }
57
+ return obj;
58
+ } else if (Array.isArray(value)) {
59
+ return value.map(mapToObject);
60
+ } else if (value && typeof value === 'object' && value.constructor === Object) {
61
+ const obj: Record<string, any> = {};
62
+ for (const [key, val] of Object.entries(value)) {
63
+ obj[key] = mapToObject(val);
64
+ }
65
+ return obj;
66
+ }
67
+ return value;
68
+ }
69
+
70
+ /**
71
+ * Engine wraps the WASM engine and provides a TypeScript-friendly API
72
+ * Browser version with explicit WASM initialization
73
+ */
74
+ export class Engine {
75
+ private wasmEngine: any = null;
76
+ private initialized = false;
77
+
78
+ /**
79
+ * Initialize the WASM module
80
+ * @param options - Initialization options including wasmPath
81
+ */
82
+ async init(options: EngineInitOptions = {}): Promise<void> {
83
+ if (this.initialized) return;
84
+
85
+ const wasmPath = options.wasmPath ?? "/hypen_engine_bg.wasm";
86
+
87
+ // Dynamically import the WASM module
88
+ // This allows the path to be configured at runtime
89
+ try {
90
+ // @ts-expect-error WASM module is generated at build time
91
+ const wasmModule = await import("../wasm/hypen_engine.js");
92
+ wasmInit = wasmModule.default;
93
+ WasmEngineClass = wasmModule.WasmEngine;
94
+
95
+ // Initialize WASM with explicit path
96
+ await wasmInit!(wasmPath);
97
+
98
+ this.wasmEngine = new WasmEngineClass();
99
+ this.initialized = true;
100
+ } catch (error) {
101
+ console.error("[Hypen] Failed to initialize WASM engine:", error);
102
+ throw error;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Ensure the engine is initialized before operations
108
+ */
109
+ private ensureInitialized(): any {
110
+ if (!this.wasmEngine) {
111
+ throw new Error("Engine not initialized. Call init() first.");
112
+ }
113
+ return this.wasmEngine;
114
+ }
115
+
116
+ /**
117
+ * Set the render callback that receives patches
118
+ */
119
+ setRenderCallback(callback: RenderCallback): void {
120
+ const engine = this.ensureInitialized();
121
+ engine.setRenderCallback((patches: Patch[]) => {
122
+ callback(patches);
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Set the component resolver for dynamic component composition
128
+ */
129
+ setComponentResolver(resolver: ComponentResolver): void {
130
+ const engine = this.ensureInitialized();
131
+ engine.setComponentResolver((componentName: string, contextPath: string | null) => {
132
+ const result = resolver(componentName, contextPath);
133
+ return result;
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Parse and render Hypen DSL source code
139
+ */
140
+ renderSource(source: string): void {
141
+ const engine = this.ensureInitialized();
142
+ engine.renderSource(source);
143
+ }
144
+
145
+ /**
146
+ * Render a lazy component (for lazy route loading)
147
+ */
148
+ renderLazyComponent(source: string): void {
149
+ const engine = this.ensureInitialized();
150
+ engine.renderLazyComponent(source);
151
+ }
152
+
153
+ /**
154
+ * Render a component into a specific parent node (subtree rendering)
155
+ */
156
+ renderInto(source: string, parentNodeId: string, state: Record<string, any>): void {
157
+ const engine = this.ensureInitialized();
158
+ const safeState = JSON.parse(JSON.stringify(state));
159
+ engine.renderInto(source, parentNodeId, safeState);
160
+ }
161
+
162
+ /**
163
+ * Notify the engine of state changes
164
+ */
165
+ notifyStateChange(paths: string[], currentState: Record<string, any>): void {
166
+ const engine = this.ensureInitialized();
167
+
168
+ const plainObject = JSON.parse(JSON.stringify(currentState));
169
+ engine.updateState(plainObject);
170
+
171
+ if (paths.length > 0) {
172
+ console.debug("[Hypen] State changed:", paths);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Update state (triggers re-render of affected nodes)
178
+ * @deprecated Use notifyStateChange instead
179
+ */
180
+ updateState(statePatch: Record<string, any>): void {
181
+ const engine = this.ensureInitialized();
182
+ const plainObject = JSON.parse(JSON.stringify(statePatch));
183
+ engine.updateState(plainObject);
184
+ }
185
+
186
+ /**
187
+ * Dispatch an action
188
+ */
189
+ dispatchAction(name: string, payload?: any): void {
190
+ const engine = this.ensureInitialized();
191
+ console.log(`[Engine] Action dispatched: ${name}`);
192
+ engine.dispatchAction(name, payload ?? null);
193
+ }
194
+
195
+ /**
196
+ * Register an action handler
197
+ */
198
+ onAction(actionName: string, handler: ActionHandler): void {
199
+ const engine = this.ensureInitialized();
200
+ engine.onAction(actionName, (action: Action) => {
201
+ const normalizedAction: Action = {
202
+ ...action,
203
+ payload: action.payload ? mapToObject(action.payload) : action.payload,
204
+ };
205
+ Promise.resolve(handler(normalizedAction)).catch(console.error);
206
+ });
207
+ }
208
+
209
+ /**
210
+ * Initialize a module
211
+ */
212
+ setModule(
213
+ name: string,
214
+ actions: string[],
215
+ stateKeys: string[],
216
+ initialState: Record<string, any>
217
+ ): void {
218
+ const engine = this.ensureInitialized();
219
+ engine.setModule(name, actions, stateKeys, initialState);
220
+ }
221
+
222
+ /**
223
+ * Get the current revision number
224
+ */
225
+ getRevision(): bigint {
226
+ const engine = this.ensureInitialized();
227
+ return engine.getRevision();
228
+ }
229
+
230
+ /**
231
+ * Clear the engine tree
232
+ */
233
+ clearTree(): void {
234
+ const engine = this.ensureInitialized();
235
+ engine.clearTree();
236
+ }
237
+
238
+ /**
239
+ * Debug method to inspect parsed components
240
+ */
241
+ debugParseComponent(source: string): string {
242
+ const engine = this.ensureInitialized();
243
+ return engine.debugParseComponent(source);
244
+ }
245
+ }
package/src/engine.ts ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Low-level wrapper around the WASM engine
3
+ * Node.js / Bundler target
4
+ */
5
+
6
+ // @ts-expect-error WASM module is generated at build time
7
+ import { WasmEngine } from "../wasm/hypen_engine.js";
8
+
9
+ export type Patch = {
10
+ type: "create" | "setProp" | "setText" | "insert" | "move" | "remove" | "attachEvent" | "detachEvent";
11
+ id?: string;
12
+ elementType?: string;
13
+ props?: Record<string, any>;
14
+ name?: string;
15
+ value?: any;
16
+ text?: string;
17
+ parentId?: string;
18
+ beforeId?: string;
19
+ eventName?: string;
20
+ };
21
+
22
+ export type Action = {
23
+ name: string;
24
+ payload?: any;
25
+ sender?: string;
26
+ };
27
+
28
+ export type RenderCallback = (patches: Patch[]) => void;
29
+ export type ActionHandler = (action: Action) => void | Promise<void>;
30
+
31
+ export type ResolvedComponent = {
32
+ source: string;
33
+ path: string;
34
+ };
35
+
36
+ export type ComponentResolver = (
37
+ componentName: string,
38
+ contextPath: string | null
39
+ ) => ResolvedComponent | null;
40
+
41
+ /**
42
+ * Engine wraps the WASM engine and provides a TypeScript-friendly API
43
+ */
44
+ export class Engine {
45
+ private wasmEngine: WasmEngine | null = null;
46
+ private initialized = false;
47
+
48
+ /**
49
+ * Initialize the WASM module
50
+ */
51
+ async init(): Promise<void> {
52
+ if (this.initialized) return;
53
+
54
+ // For bundler target, WASM is auto-initialized
55
+ this.wasmEngine = new WasmEngine();
56
+ this.initialized = true;
57
+ }
58
+
59
+ /**
60
+ * Ensure the engine is initialized before operations
61
+ */
62
+ private ensureInitialized(): WasmEngine {
63
+ if (!this.wasmEngine) {
64
+ throw new Error("Engine not initialized. Call init() first.");
65
+ }
66
+ return this.wasmEngine;
67
+ }
68
+
69
+ /**
70
+ * Set the render callback that receives patches
71
+ */
72
+ setRenderCallback(callback: RenderCallback): void {
73
+ const engine = this.ensureInitialized();
74
+ engine.setRenderCallback((patches: Patch[]) => {
75
+ callback(patches);
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Set the component resolver for dynamic component composition
81
+ */
82
+ setComponentResolver(resolver: ComponentResolver): void {
83
+ const engine = this.ensureInitialized();
84
+ engine.setComponentResolver((componentName: string, contextPath: string | null) => {
85
+ const result = resolver(componentName, contextPath);
86
+ return result;
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Parse and render Hypen DSL source code
92
+ */
93
+ renderSource(source: string): void {
94
+ const engine = this.ensureInitialized();
95
+ engine.renderSource(source);
96
+ }
97
+
98
+ /**
99
+ * Render a lazy component (for lazy route loading)
100
+ */
101
+ renderLazyComponent(source: string): void {
102
+ const engine = this.ensureInitialized();
103
+ engine.renderLazyComponent(source);
104
+ }
105
+
106
+ /**
107
+ * Render a component into a specific parent node (subtree rendering)
108
+ */
109
+ renderInto(source: string, parentNodeId: string, state: Record<string, any>): void {
110
+ const engine = this.ensureInitialized();
111
+ const safeState = JSON.parse(JSON.stringify(state));
112
+ engine.renderInto(source, parentNodeId, safeState);
113
+ }
114
+
115
+ /**
116
+ * Notify the engine of state changes using sparse updates
117
+ */
118
+ notifyStateChange(paths: string[], values: Record<string, any>): void {
119
+ const engine = this.ensureInitialized();
120
+
121
+ if (paths.length === 0) {
122
+ return;
123
+ }
124
+
125
+ engine.updateStateSparse(paths, values);
126
+ console.debug("[Hypen] State changed (sparse):", paths);
127
+ }
128
+
129
+ /**
130
+ * Notify the engine of state changes using full state replacement
131
+ * @deprecated Use notifyStateChange with sparse values instead
132
+ */
133
+ notifyStateChangeFull(paths: string[], currentState: Record<string, any>): void {
134
+ const engine = this.ensureInitialized();
135
+
136
+ const plainObject = JSON.parse(JSON.stringify(currentState));
137
+ engine.updateState(plainObject);
138
+
139
+ if (paths.length > 0) {
140
+ console.debug("[Hypen] State changed (full):", paths);
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Update state (triggers re-render of affected nodes)
146
+ * @deprecated Use notifyStateChange instead
147
+ */
148
+ updateState(statePatch: Record<string, any>): void {
149
+ const engine = this.ensureInitialized();
150
+ const plainObject = JSON.parse(JSON.stringify(statePatch));
151
+ engine.updateState(plainObject);
152
+ }
153
+
154
+ /**
155
+ * Dispatch an action
156
+ */
157
+ dispatchAction(name: string, payload?: any): void {
158
+ const engine = this.ensureInitialized();
159
+ engine.dispatchAction(name, payload ?? null);
160
+ }
161
+
162
+ /**
163
+ * Register an action handler
164
+ */
165
+ onAction(actionName: string, handler: ActionHandler): void {
166
+ const engine = this.ensureInitialized();
167
+ engine.onAction(actionName, (action: Action) => {
168
+ Promise.resolve(handler(action)).catch(console.error);
169
+ });
170
+ }
171
+
172
+ /**
173
+ * Initialize a module
174
+ */
175
+ setModule(
176
+ name: string,
177
+ actions: string[],
178
+ stateKeys: string[],
179
+ initialState: Record<string, any>
180
+ ): void {
181
+ const engine = this.ensureInitialized();
182
+ engine.setModule(name, actions, stateKeys, initialState);
183
+ }
184
+
185
+ /**
186
+ * Get the current revision number
187
+ */
188
+ getRevision(): number {
189
+ const engine = this.ensureInitialized();
190
+ return engine.getRevision();
191
+ }
192
+
193
+ /**
194
+ * Clear the engine tree
195
+ */
196
+ clearTree(): void {
197
+ const engine = this.ensureInitialized();
198
+ engine.clearTree();
199
+ }
200
+
201
+ /**
202
+ * Debug method to inspect parsed components
203
+ */
204
+ debugParseComponent(source: string): string {
205
+ const engine = this.ensureInitialized();
206
+ return engine.debugParseComponent(source);
207
+ }
208
+ }
package/src/events.ts ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Type-safe Event System
3
+ *
4
+ * Provides strongly-typed event emission and subscription with autocomplete support.
5
+ */
6
+
7
+ export type EventHandler<T = unknown> = (payload: T) => void;
8
+
9
+ /**
10
+ * Type-safe event emitter with generics
11
+ */
12
+ export class TypedEventEmitter<TEvents extends Record<string, unknown> = Record<string, unknown>> {
13
+ private eventBus = new Map<keyof TEvents, Set<EventHandler<any>>>();
14
+
15
+ /**
16
+ * Emit an event with type-safe payload
17
+ */
18
+ emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {
19
+ const handlers = this.eventBus.get(event);
20
+ if (!handlers || handlers.size === 0) {
21
+ return;
22
+ }
23
+
24
+ handlers.forEach((handler) => {
25
+ try {
26
+ handler(payload);
27
+ } catch (error) {
28
+ console.error(`Error in event handler for "${String(event)}":`, error);
29
+ }
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Subscribe to an event with type-safe payload
35
+ * Returns an unsubscribe function
36
+ */
37
+ on<K extends keyof TEvents>(event: K, handler: EventHandler<TEvents[K]>): () => void {
38
+ if (!this.eventBus.has(event)) {
39
+ this.eventBus.set(event, new Set());
40
+ }
41
+
42
+ const handlers = this.eventBus.get(event)!;
43
+ handlers.add(handler);
44
+
45
+ // Return unsubscribe function
46
+ return () => {
47
+ handlers.delete(handler);
48
+ if (handlers.size === 0) {
49
+ this.eventBus.delete(event);
50
+ }
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Subscribe to an event once (auto-unsubscribe after first emit)
56
+ */
57
+ once<K extends keyof TEvents>(event: K, handler: EventHandler<TEvents[K]>): () => void {
58
+ const wrappedHandler = (payload: TEvents[K]) => {
59
+ handler(payload);
60
+ unsubscribe();
61
+ };
62
+
63
+ const unsubscribe = this.on(event, wrappedHandler);
64
+ return unsubscribe;
65
+ }
66
+
67
+ /**
68
+ * Unsubscribe a specific handler from an event
69
+ */
70
+ off<K extends keyof TEvents>(event: K, handler: EventHandler<TEvents[K]>): void {
71
+ const handlers = this.eventBus.get(event);
72
+ if (handlers) {
73
+ handlers.delete(handler);
74
+ if (handlers.size === 0) {
75
+ this.eventBus.delete(event);
76
+ }
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Remove all listeners for a specific event
82
+ */
83
+ removeAllListeners<K extends keyof TEvents>(event: K): void {
84
+ this.eventBus.delete(event);
85
+ }
86
+
87
+ /**
88
+ * Remove all listeners for all events
89
+ */
90
+ clearAll(): void {
91
+ this.eventBus.clear();
92
+ }
93
+
94
+ /**
95
+ * Get the number of listeners for an event
96
+ */
97
+ listenerCount<K extends keyof TEvents>(event: K): number {
98
+ return this.eventBus.get(event)?.size ?? 0;
99
+ }
100
+
101
+ /**
102
+ * Get all registered event names
103
+ */
104
+ eventNames(): Array<keyof TEvents> {
105
+ return Array.from(this.eventBus.keys());
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Default events for Hypen framework (can be extended by users)
111
+ */
112
+ export type HypenFrameworkEvents = {
113
+ 'module:created': { moduleId: string };
114
+ 'module:destroyed': { moduleId: string };
115
+ 'route:changed': { from: string | null; to: string };
116
+ 'state:updated': { moduleId: string; paths: string[] };
117
+ 'action:dispatched': { moduleId: string; actionName: string; payload?: unknown };
118
+ 'error': { message: string; error?: Error; context?: string };
119
+ };
120
+
121
+ /**
122
+ * Create a typed event emitter with custom event map
123
+ */
124
+ export function createEventEmitter<TEvents extends Record<string, unknown> = HypenFrameworkEvents>(): TypedEventEmitter<TEvents> {
125
+ return new TypedEventEmitter<TEvents>();
126
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @hypen/core - Browser Entry Point
3
+ *
4
+ * This entry point uses the browser-compatible engine with explicit WASM initialization.
5
+ */
6
+
7
+ // ============================================================================
8
+ // ENGINE API (Browser version)
9
+ // ============================================================================
10
+
11
+ export { Engine } from "./engine.browser.js";
12
+ export type {
13
+ Patch,
14
+ Action,
15
+ RenderCallback,
16
+ ActionHandler as EngineActionHandler,
17
+ ResolvedComponent,
18
+ ComponentResolver,
19
+ EngineInitOptions,
20
+ } from "./engine.browser.js";
21
+
22
+ // ============================================================================
23
+ // APP / MODULE SYSTEM
24
+ // ============================================================================
25
+
26
+ export { app, HypenApp, HypenAppBuilder, HypenModuleInstance } from "./app.js";
27
+ export type {
28
+ IEngine,
29
+ RouterContext,
30
+ ActionContext,
31
+ ActionNext,
32
+ GlobalContext,
33
+ LifecycleHandler,
34
+ ActionHandlerContext,
35
+ ActionHandler,
36
+ HypenModuleDefinition,
37
+ HypenModule,
38
+ } from "./app.js";
39
+
40
+ // ============================================================================
41
+ // STATE MANAGEMENT
42
+ // ============================================================================
43
+
44
+ export {
45
+ createObservableState,
46
+ batchStateUpdates,
47
+ getStateSnapshot,
48
+ } from "./state.js";
49
+ export type {
50
+ StatePath,
51
+ StateChange,
52
+ StateObserverOptions,
53
+ } from "./state.js";
54
+
55
+ // ============================================================================
56
+ // RENDERER ABSTRACTION
57
+ // ============================================================================
58
+
59
+ export { BaseRenderer, ConsoleRenderer } from "./renderer.js";
60
+ export type { Renderer } from "./renderer.js";
61
+
62
+ // ============================================================================
63
+ // ROUTING
64
+ // ============================================================================
65
+
66
+ export { HypenRouter } from "./router.js";
67
+ export type {
68
+ RouteMatch,
69
+ RouteState,
70
+ RouteChangeCallback,
71
+ } from "./router.js";
72
+
73
+ // ============================================================================
74
+ // EVENTS
75
+ // ============================================================================
76
+
77
+ export { TypedEventEmitter, createEventEmitter } from "./events.js";
78
+ export type { EventHandler, HypenFrameworkEvents } from "./events.js";
79
+
80
+ // ============================================================================
81
+ // GLOBAL CONTEXT
82
+ // ============================================================================
83
+
84
+ export { HypenGlobalContext } from "./context.js";
85
+ export type { ModuleReference } from "./context.js";
86
+
87
+ // ============================================================================
88
+ // REMOTE UI
89
+ // ============================================================================
90
+
91
+ export { RemoteEngine } from "./remote/client.js";
92
+ export type {
93
+ RemoteMessage,
94
+ InitialTreeMessage,
95
+ PatchMessage,
96
+ DispatchActionMessage,
97
+ StateUpdateMessage,
98
+ RemoteClient,
99
+ RemoteServerConfig,
100
+ } from "./remote/types.js";
101
+ export type {
102
+ RemoteConnectionState,
103
+ RemoteEngineOptions,
104
+ } from "./remote/client.js";