@hypen-space/core 0.4.82 → 0.4.84
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 +10 -4
- package/dist/app.d.ts +78 -1
- package/dist/app.js +102 -46
- package/dist/app.js.map +6 -5
- package/dist/components/builtin.js +102 -46
- package/dist/components/builtin.js.map +6 -5
- package/dist/engine-base.d.ts +19 -0
- package/dist/engine-base.js +32 -1
- package/dist/engine-base.js.map +3 -3
- package/dist/index.browser.js +117 -85
- package/dist/index.browser.js.map +7 -6
- package/dist/index.d.ts +4 -0
- package/dist/index.js +318 -85
- package/dist/index.js.map +9 -7
- package/dist/managed-router.d.ts +121 -5
- package/dist/portable.d.ts +62 -0
- package/dist/router.d.ts +7 -1
- package/dist/router.js +60 -81
- package/dist/router.js.map +6 -5
- package/dist/state.js +49 -46
- package/dist/state.js.map +5 -4
- package/dist/types.d.ts +12 -1
- package/package.json +7 -1
- package/src/app.ts +131 -1
- package/src/engine-base.ts +55 -0
- package/src/index.ts +13 -0
- package/src/managed-router.ts +285 -35
- package/src/portable.ts +113 -0
- package/src/router.ts +25 -50
- package/src/state.ts +11 -70
- package/src/types.ts +23 -1
package/src/state.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* creating nested proxies repeatedly.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { portable } from "./portable";
|
|
9
|
+
|
|
8
10
|
// Symbol for proxy detection (more robust than string property)
|
|
9
11
|
const IS_PROXY = Symbol.for('hypen.isProxy');
|
|
10
12
|
const RAW_TARGET = Symbol.for('hypen.rawTarget');
|
|
@@ -126,82 +128,21 @@ function deepClone<T>(obj: T): T {
|
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
/**
|
|
129
|
-
* Compare two values and detect changes with full paths
|
|
131
|
+
* Compare two values and detect changes with full paths.
|
|
132
|
+
*
|
|
133
|
+
* Thin wrapper over [`portable.diffState`] — the algorithm lives in
|
|
134
|
+
* the Rust engine at `hypen-engine-rs/src/portable/diff.rs` and is
|
|
135
|
+
* called through the WASM installed by `@hypen-space/server` /
|
|
136
|
+
* `@hypen-space/web-engine`. When `@hypen-space/core` is used
|
|
137
|
+
* standalone (no WASM available), a byte-identical TS fallback in
|
|
138
|
+
* `portable.ts` takes over.
|
|
130
139
|
*/
|
|
131
140
|
function diffState(
|
|
132
141
|
oldState: any,
|
|
133
142
|
newState: any,
|
|
134
143
|
basePath: string = ""
|
|
135
144
|
): StateChange {
|
|
136
|
-
|
|
137
|
-
const newValues: Record<StatePath, any> = {};
|
|
138
|
-
|
|
139
|
-
function diff(oldVal: any, newVal: any, path: string) {
|
|
140
|
-
// Handle null/undefined
|
|
141
|
-
if (oldVal === newVal) return;
|
|
142
|
-
|
|
143
|
-
// Different types or primitives
|
|
144
|
-
if (
|
|
145
|
-
typeof oldVal !== "object" ||
|
|
146
|
-
typeof newVal !== "object" ||
|
|
147
|
-
oldVal === null ||
|
|
148
|
-
newVal === null
|
|
149
|
-
) {
|
|
150
|
-
if (oldVal !== newVal) {
|
|
151
|
-
paths.push(path);
|
|
152
|
-
newValues[path] = newVal;
|
|
153
|
-
}
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Arrays
|
|
158
|
-
if (Array.isArray(oldVal) || Array.isArray(newVal)) {
|
|
159
|
-
if (
|
|
160
|
-
!Array.isArray(oldVal) ||
|
|
161
|
-
!Array.isArray(newVal) ||
|
|
162
|
-
oldVal.length !== newVal.length
|
|
163
|
-
) {
|
|
164
|
-
paths.push(path);
|
|
165
|
-
newValues[path] = newVal;
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
for (let i = 0; i < newVal.length; i++) {
|
|
170
|
-
const itemPath = path ? `${path}.${i}` : `${i}`;
|
|
171
|
-
diff(oldVal[i], newVal[i], itemPath);
|
|
172
|
-
}
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Objects
|
|
177
|
-
const oldKeys = new Set(Object.keys(oldVal));
|
|
178
|
-
const newKeys = new Set(Object.keys(newVal));
|
|
179
|
-
|
|
180
|
-
// Check for added or changed keys
|
|
181
|
-
for (const key of newKeys) {
|
|
182
|
-
const propPath = path ? `${path}.${key}` : key;
|
|
183
|
-
if (!oldKeys.has(key)) {
|
|
184
|
-
// New property
|
|
185
|
-
paths.push(propPath);
|
|
186
|
-
newValues[propPath] = newVal[key];
|
|
187
|
-
} else {
|
|
188
|
-
// Existing property, recurse
|
|
189
|
-
diff(oldVal[key], newVal[key], propPath);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Check for removed keys
|
|
194
|
-
for (const key of oldKeys) {
|
|
195
|
-
if (!newKeys.has(key)) {
|
|
196
|
-
const propPath = path ? `${path}.${key}` : key;
|
|
197
|
-
paths.push(propPath);
|
|
198
|
-
newValues[propPath] = undefined;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
diff(oldState, newState, basePath);
|
|
204
|
-
return { paths, newValues };
|
|
145
|
+
return portable.diffState(oldState, newState, basePath);
|
|
205
146
|
}
|
|
206
147
|
|
|
207
148
|
/**
|
package/src/types.ts
CHANGED
|
@@ -6,7 +6,29 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export type Patch = {
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Patch variant.
|
|
11
|
+
*
|
|
12
|
+
* `detach` / `attach` are used by the engine's Router subtree cache
|
|
13
|
+
* to keep off-screen route content alive between navigations. On
|
|
14
|
+
* `detach`, the renderer must unlink the subtree from its parent
|
|
15
|
+
* but keep the underlying native element (and its children) alive
|
|
16
|
+
* under the same id, so a later `attach` can reinsert it with zero
|
|
17
|
+
* rebuild. If `remove` arrives for a detached id instead, the
|
|
18
|
+
* subtree is torn down normally.
|
|
19
|
+
*/
|
|
20
|
+
type:
|
|
21
|
+
| "create"
|
|
22
|
+
| "setProp"
|
|
23
|
+
| "removeProp"
|
|
24
|
+
| "setText"
|
|
25
|
+
| "insert"
|
|
26
|
+
| "move"
|
|
27
|
+
| "remove"
|
|
28
|
+
| "attachEvent"
|
|
29
|
+
| "detachEvent"
|
|
30
|
+
| "detach"
|
|
31
|
+
| "attach";
|
|
10
32
|
id?: string;
|
|
11
33
|
elementType?: string;
|
|
12
34
|
props?: Record<string, any>;
|