@noego/wood 0.1.1 → 0.1.2
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": "@noego/wood",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
"dist",
|
|
19
19
|
"bin",
|
|
20
20
|
"loaders",
|
|
21
|
-
"src/
|
|
22
|
-
"src/
|
|
21
|
+
"src/components/",
|
|
22
|
+
"src/client/controller_contract.ts",
|
|
23
|
+
"src/controller/controller_lifecycle.ts",
|
|
24
|
+
"src/navigation/navigation_identity.ts"
|
|
23
25
|
],
|
|
24
26
|
"exports": {
|
|
25
27
|
".": {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ControllerLifecycle } from '../controller/controller_lifecycle';
|
|
2
|
+
export type { ControllerLifecycle } from '../controller/controller_lifecycle';
|
|
3
|
+
|
|
4
|
+
export interface ControllerState {}
|
|
5
|
+
|
|
6
|
+
export interface ControllerInput {}
|
|
7
|
+
|
|
8
|
+
export interface ControllerEvents {}
|
|
9
|
+
|
|
10
|
+
export interface PageController<
|
|
11
|
+
S extends ControllerState = ControllerState,
|
|
12
|
+
I extends ControllerInput = ControllerInput,
|
|
13
|
+
E extends ControllerEvents = ControllerEvents,
|
|
14
|
+
> extends ControllerLifecycle {
|
|
15
|
+
readonly data?: S;
|
|
16
|
+
readonly input?: I;
|
|
17
|
+
readonly events?: E;
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ControllerLifecycle {
|
|
2
|
+
dispose?(): void | Promise<void>;
|
|
3
|
+
destroy?(): void | Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Dispose a controller or controller-like instance if it exposes a lifecycle
|
|
8
|
+
* hook. `dispose` is the preferred Wood lifecycle name; `destroy` is supported
|
|
9
|
+
* for existing page controllers.
|
|
10
|
+
*/
|
|
11
|
+
export async function disposeControllerLifecycle(target: unknown): Promise<void> {
|
|
12
|
+
if (!target || (typeof target !== 'object' && typeof target !== 'function')) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const lifecycle = target as ControllerLifecycle;
|
|
17
|
+
if (typeof lifecycle.dispose === 'function') {
|
|
18
|
+
await lifecycle.dispose();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (typeof lifecycle.destroy === 'function') {
|
|
22
|
+
await lifecycle.destroy();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type NavigationParams = Record<string, unknown>;
|
|
2
|
+
|
|
3
|
+
function normalizeParamValue(value: unknown): string {
|
|
4
|
+
if (value === null || value === undefined) {
|
|
5
|
+
return '';
|
|
6
|
+
}
|
|
7
|
+
return String(value);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function hashNavigationParams(params: NavigationParams = {}): string {
|
|
11
|
+
const normalizedEntries = Object.entries(params)
|
|
12
|
+
.map(([key, value]) => [String(key), normalizeParamValue(value)] as const)
|
|
13
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
14
|
+
|
|
15
|
+
return JSON.stringify(normalizedEntries);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createNavigationMountKey(
|
|
19
|
+
page: string,
|
|
20
|
+
params: NavigationParams = {},
|
|
21
|
+
): string {
|
|
22
|
+
return `${page}:${hashNavigationParams(params)}`;
|
|
23
|
+
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
// SSR-only recursive layout renderer for stick (wood's visual preview CLI).
|
|
3
|
-
// Simplified version of Forge's RecursiveRender — no stores, navigation, or error boundaries.
|
|
4
|
-
let {
|
|
5
|
-
layouts = [],
|
|
6
|
-
view = null,
|
|
7
|
-
data = { layout: [], view: {} },
|
|
8
|
-
wood = undefined,
|
|
9
|
-
} = $props<{
|
|
10
|
-
layouts?: any[];
|
|
11
|
-
view?: any;
|
|
12
|
-
data?: { layout?: any[]; view?: any };
|
|
13
|
-
wood?: any;
|
|
14
|
-
}>();
|
|
15
|
-
|
|
16
|
-
let topLayout = $derived(layouts[0]);
|
|
17
|
-
let childLayouts = $derived(layouts.slice(1));
|
|
18
|
-
let topData = $derived((data.layout || [])[0]);
|
|
19
|
-
let otherData = $derived((data.layout || []).slice(1));
|
|
20
|
-
let viewData = $derived(data.view);
|
|
21
|
-
let recursiveChildData = $derived({
|
|
22
|
-
layout: otherData,
|
|
23
|
-
view: data.view,
|
|
24
|
-
});
|
|
25
|
-
</script>
|
|
26
|
-
|
|
27
|
-
{#if childLayouts.length > 0}
|
|
28
|
-
{#snippet nested_child()}
|
|
29
|
-
<svelte:self
|
|
30
|
-
layouts={childLayouts}
|
|
31
|
-
view={view}
|
|
32
|
-
data={recursiveChildData}
|
|
33
|
-
{wood}
|
|
34
|
-
/>
|
|
35
|
-
{/snippet}
|
|
36
|
-
<svelte:component
|
|
37
|
-
this={topLayout}
|
|
38
|
-
{...(topData || {})}
|
|
39
|
-
data={topData?.controller?.data}
|
|
40
|
-
input={topData?.controller?.input}
|
|
41
|
-
events={topData?.controller?.events}
|
|
42
|
-
{wood}
|
|
43
|
-
children={nested_child}
|
|
44
|
-
/>
|
|
45
|
-
{:else if topLayout}
|
|
46
|
-
{#snippet view_child()}
|
|
47
|
-
<svelte:component
|
|
48
|
-
this={view}
|
|
49
|
-
{...(viewData || {})}
|
|
50
|
-
data={viewData?.controller?.data}
|
|
51
|
-
input={viewData?.controller?.input}
|
|
52
|
-
events={viewData?.controller?.events}
|
|
53
|
-
{wood}
|
|
54
|
-
/>
|
|
55
|
-
{/snippet}
|
|
56
|
-
<svelte:component
|
|
57
|
-
this={topLayout}
|
|
58
|
-
{...(topData || {})}
|
|
59
|
-
data={topData?.controller?.data}
|
|
60
|
-
input={topData?.controller?.input}
|
|
61
|
-
events={topData?.controller?.events}
|
|
62
|
-
{wood}
|
|
63
|
-
children={view_child}
|
|
64
|
-
/>
|
|
65
|
-
{:else}
|
|
66
|
-
<svelte:component
|
|
67
|
-
this={view}
|
|
68
|
-
{...(viewData || {})}
|
|
69
|
-
data={viewData?.controller?.data}
|
|
70
|
-
input={viewData?.controller?.input}
|
|
71
|
-
events={viewData?.controller?.events}
|
|
72
|
-
{wood}
|
|
73
|
-
/>
|
|
74
|
-
{/if}
|