@zenithbuild/core 0.6.2 → 1.1.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.
- package/cli/commands/dev.ts +107 -48
- package/compiler/discovery/componentDiscovery.ts +75 -11
- package/compiler/output/types.ts +15 -1
- package/compiler/parse/parseTemplate.ts +29 -0
- package/compiler/runtime/dataExposure.ts +27 -12
- package/compiler/runtime/generateDOM.ts +12 -3
- package/compiler/runtime/transformIR.ts +39 -3
- package/compiler/runtime/wrapExpression.ts +32 -13
- package/compiler/runtime/wrapExpressionWithLoop.ts +24 -10
- package/compiler/ssg-build.ts +71 -7
- package/compiler/test/component-stacking.test.ts +365 -0
- package/compiler/transform/componentResolver.ts +42 -4
- package/compiler/transform/fragmentLowering.ts +153 -1
- package/compiler/transform/generateBindings.ts +31 -10
- package/compiler/transform/transformNode.ts +114 -1
- package/core/config/index.ts +5 -3
- package/core/config/types.ts +67 -37
- package/core/plugins/bridge.ts +193 -0
- package/core/plugins/registry.ts +51 -6
- package/dist/cli.js +10 -0
- package/dist/zen-build.js +673 -1723
- package/dist/zen-dev.js +673 -1723
- package/dist/zen-preview.js +673 -1723
- package/dist/zenith.js +673 -1723
- package/package.json +11 -3
- package/runtime/bundle-generator.ts +36 -17
- package/runtime/client-runtime.ts +21 -1
- package/cli/utils/content.ts +0 -112
- package/router/manifest.ts +0 -314
- package/router/navigation/ZenLink.zen +0 -231
- package/router/navigation/index.ts +0 -78
- package/router/navigation/zen-link.ts +0 -584
- package/router/runtime.ts +0 -458
- package/router/types.ts +0 -168
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith CLI Bridge
|
|
3
|
+
*
|
|
4
|
+
* The ONLY interface between CLI and plugins.
|
|
5
|
+
*
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
+
* CLI BRIDGE RULES (CANONICAL)
|
|
8
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
9
|
+
*
|
|
10
|
+
* 1. No runtime emitters - plugins return data, CLI serializes blindly
|
|
11
|
+
* 2. No plugin typing - all data is unknown
|
|
12
|
+
* 3. No semantic helpers - CLI is blind to what data means
|
|
13
|
+
*
|
|
14
|
+
* The CLI dispatches hooks and collects returns. It never inspects payloads.
|
|
15
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* CLI Bridge API - passed to plugins during CLI registration
|
|
20
|
+
*
|
|
21
|
+
* Plugins use this to register namespaced hooks.
|
|
22
|
+
* CLI lifecycle hooks: 'cli:*'
|
|
23
|
+
* Plugin hooks: '<namespace>:*'
|
|
24
|
+
*/
|
|
25
|
+
export interface CLIBridgeAPI {
|
|
26
|
+
/**
|
|
27
|
+
* Register a hook handler
|
|
28
|
+
*
|
|
29
|
+
* @param hook - Namespaced hook name (e.g., 'cli:runtime:collect', 'content:dev:watch')
|
|
30
|
+
* @param handler - Handler function that receives context and optionally returns data
|
|
31
|
+
*/
|
|
32
|
+
on(hook: string, handler: (ctx: HookContext) => unknown | void | Promise<unknown | void>): void
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Context passed to hook handlers
|
|
37
|
+
*
|
|
38
|
+
* CLI provides this but never uses getPluginData itself.
|
|
39
|
+
* Only plugins call getPluginData with their own namespace.
|
|
40
|
+
*/
|
|
41
|
+
export interface HookContext {
|
|
42
|
+
/** Absolute path to project root */
|
|
43
|
+
projectRoot: string
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Opaque data accessor
|
|
47
|
+
*
|
|
48
|
+
* CLI passes this function but NEVER calls it.
|
|
49
|
+
* Only plugins use it to access their own namespaced data.
|
|
50
|
+
*/
|
|
51
|
+
getPluginData: (namespace: string) => unknown
|
|
52
|
+
|
|
53
|
+
/** Additional context data (e.g., filename for file-change hooks) */
|
|
54
|
+
[key: string]: unknown
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Runtime payload returned by plugins
|
|
59
|
+
*
|
|
60
|
+
* CLI collects these and serializes without inspection.
|
|
61
|
+
* The envelope structure is: { [namespace]: payload }
|
|
62
|
+
*/
|
|
63
|
+
export interface RuntimePayload {
|
|
64
|
+
/** Plugin namespace (e.g., 'content', 'router') */
|
|
65
|
+
namespace: string
|
|
66
|
+
/** Opaque payload - CLI never inspects this */
|
|
67
|
+
payload: unknown
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ============================================
|
|
71
|
+
// Hook Registry (Internal)
|
|
72
|
+
// ============================================
|
|
73
|
+
|
|
74
|
+
type HookHandler = (ctx: HookContext) => unknown | void | Promise<unknown | void>
|
|
75
|
+
|
|
76
|
+
const hookRegistry = new Map<string, HookHandler[]>()
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Register a hook handler
|
|
80
|
+
*
|
|
81
|
+
* @internal Called by CLIBridgeAPI.on()
|
|
82
|
+
*/
|
|
83
|
+
export function registerHook(hook: string, handler: HookHandler): void {
|
|
84
|
+
if (!hookRegistry.has(hook)) {
|
|
85
|
+
hookRegistry.set(hook, [])
|
|
86
|
+
}
|
|
87
|
+
hookRegistry.get(hook)!.push(handler)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Clear all registered hooks
|
|
92
|
+
*
|
|
93
|
+
* @internal Used for testing and cleanup
|
|
94
|
+
*/
|
|
95
|
+
export function clearHooks(): void {
|
|
96
|
+
hookRegistry.clear()
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ============================================
|
|
100
|
+
// Hook Execution (CLI-facing)
|
|
101
|
+
// ============================================
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Run all handlers for a hook (fire-and-forget)
|
|
105
|
+
*
|
|
106
|
+
* CLI calls this for lifecycle events.
|
|
107
|
+
* No return values are collected.
|
|
108
|
+
*
|
|
109
|
+
* @param hook - Hook name to dispatch
|
|
110
|
+
* @param ctx - Hook context
|
|
111
|
+
*/
|
|
112
|
+
export async function runPluginHooks(hook: string, ctx: HookContext): Promise<void> {
|
|
113
|
+
const handlers = hookRegistry.get(hook) || []
|
|
114
|
+
for (const handler of handlers) {
|
|
115
|
+
try {
|
|
116
|
+
await handler(ctx)
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(`[Zenith] Hook "${hook}" error:`, error)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Collect return values from all handlers for a hook
|
|
125
|
+
*
|
|
126
|
+
* CLI calls this for 'cli:runtime:collect' to gather plugin payloads.
|
|
127
|
+
* Only RuntimePayload-shaped returns are collected.
|
|
128
|
+
*
|
|
129
|
+
* @param hook - Hook name to dispatch
|
|
130
|
+
* @param ctx - Hook context
|
|
131
|
+
* @returns Array of runtime payloads from plugins
|
|
132
|
+
*/
|
|
133
|
+
export async function collectHookReturns(hook: string, ctx: HookContext): Promise<RuntimePayload[]> {
|
|
134
|
+
const handlers = hookRegistry.get(hook) || []
|
|
135
|
+
const results: RuntimePayload[] = []
|
|
136
|
+
|
|
137
|
+
for (const handler of handlers) {
|
|
138
|
+
try {
|
|
139
|
+
const result = await handler(ctx)
|
|
140
|
+
|
|
141
|
+
// Only collect properly shaped payloads
|
|
142
|
+
if (
|
|
143
|
+
result &&
|
|
144
|
+
typeof result === 'object' &&
|
|
145
|
+
'namespace' in result &&
|
|
146
|
+
'payload' in result &&
|
|
147
|
+
typeof (result as RuntimePayload).namespace === 'string'
|
|
148
|
+
) {
|
|
149
|
+
results.push(result as RuntimePayload)
|
|
150
|
+
}
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error(`[Zenith] Hook "${hook}" collection error:`, error)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return results
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build runtime envelope from collected payloads
|
|
161
|
+
*
|
|
162
|
+
* CLI calls this to serialize plugin data for injection.
|
|
163
|
+
* CLI never inspects the envelope contents.
|
|
164
|
+
*
|
|
165
|
+
* @param payloads - Array of runtime payloads from collectHookReturns
|
|
166
|
+
* @returns Envelope object: { [namespace]: payload }
|
|
167
|
+
*/
|
|
168
|
+
export function buildRuntimeEnvelope(payloads: RuntimePayload[]): Record<string, unknown> {
|
|
169
|
+
const envelope: Record<string, unknown> = {}
|
|
170
|
+
|
|
171
|
+
for (const { namespace, payload } of payloads) {
|
|
172
|
+
envelope[namespace] = payload
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return envelope
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============================================
|
|
179
|
+
// Bridge API Factory
|
|
180
|
+
// ============================================
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Create a CLI Bridge API for plugin registration
|
|
184
|
+
*
|
|
185
|
+
* CLI calls this once and passes to each plugin's registerCLI method.
|
|
186
|
+
*
|
|
187
|
+
* @returns CLIBridgeAPI instance
|
|
188
|
+
*/
|
|
189
|
+
export function createBridgeAPI(): CLIBridgeAPI {
|
|
190
|
+
return {
|
|
191
|
+
on: registerHook
|
|
192
|
+
}
|
|
193
|
+
}
|
package/core/plugins/registry.ts
CHANGED
|
@@ -2,9 +2,44 @@
|
|
|
2
2
|
* Zenith Plugin Registry
|
|
3
3
|
*
|
|
4
4
|
* Manages plugin registration and initialization
|
|
5
|
+
*
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
+
* HOOK OWNERSHIP RULE (CANONICAL)
|
|
8
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
9
|
+
*
|
|
10
|
+
* The plugin registry is part of core infrastructure.
|
|
11
|
+
* It MUST remain plugin-agnostic:
|
|
12
|
+
* - No plugin-specific types
|
|
13
|
+
* - No plugin-specific logic
|
|
14
|
+
* - Generic data handling only
|
|
15
|
+
*
|
|
16
|
+
* Plugins own their data structures; core provides the storage mechanism.
|
|
17
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
18
|
*/
|
|
6
19
|
|
|
7
|
-
import type { ZenithPlugin, PluginContext
|
|
20
|
+
import type { ZenithPlugin, PluginContext } from '../config/types';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Global plugin data store
|
|
24
|
+
*
|
|
25
|
+
* Plugins store their data here using namespaced keys.
|
|
26
|
+
* Core does not interpret this data - it just stores and serves it.
|
|
27
|
+
*/
|
|
28
|
+
const pluginDataStore: Record<string, unknown[]> = {};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get all plugin data (for runtime access)
|
|
32
|
+
*/
|
|
33
|
+
export function getPluginData(): Record<string, unknown[]> {
|
|
34
|
+
return { ...pluginDataStore };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get plugin data by namespace
|
|
39
|
+
*/
|
|
40
|
+
export function getPluginDataByNamespace(namespace: string): unknown[] {
|
|
41
|
+
return pluginDataStore[namespace] || [];
|
|
42
|
+
}
|
|
8
43
|
|
|
9
44
|
/**
|
|
10
45
|
* Plugin registry for managing Zenith plugins
|
|
@@ -63,19 +98,29 @@ export class PluginRegistry {
|
|
|
63
98
|
*/
|
|
64
99
|
clear(): void {
|
|
65
100
|
this.plugins.clear();
|
|
101
|
+
// Also clear plugin data
|
|
102
|
+
for (const key of Object.keys(pluginDataStore)) {
|
|
103
|
+
delete pluginDataStore[key];
|
|
104
|
+
}
|
|
66
105
|
}
|
|
67
106
|
}
|
|
68
107
|
|
|
69
108
|
/**
|
|
70
109
|
* Create a plugin context for initialization
|
|
110
|
+
*
|
|
111
|
+
* Uses a generic data setter that stores data by namespace.
|
|
112
|
+
* Plugins define their own data structures internally.
|
|
113
|
+
*
|
|
114
|
+
* @param projectRoot - Absolute path to the project root
|
|
115
|
+
* @returns A PluginContext for plugin initialization
|
|
71
116
|
*/
|
|
72
|
-
export function createPluginContext(
|
|
73
|
-
projectRoot: string,
|
|
74
|
-
contentSetter: (data: Record<string, ContentItem[]>) => void
|
|
75
|
-
): PluginContext {
|
|
117
|
+
export function createPluginContext(projectRoot: string): PluginContext {
|
|
76
118
|
return {
|
|
77
119
|
projectRoot,
|
|
78
|
-
|
|
120
|
+
setPluginData: (namespace: string, data: unknown[]) => {
|
|
121
|
+
pluginDataStore[namespace] = data;
|
|
122
|
+
},
|
|
79
123
|
options: {}
|
|
80
124
|
};
|
|
81
125
|
}
|
|
126
|
+
|
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,16 @@
|
|
|
19
19
|
#!/usr/bin/env bun
|
|
20
20
|
#!/usr/bin/env bun
|
|
21
21
|
#!/usr/bin/env bun
|
|
22
|
+
#!/usr/bin/env bun
|
|
23
|
+
#!/usr/bin/env bun
|
|
24
|
+
#!/usr/bin/env bun
|
|
25
|
+
#!/usr/bin/env bun
|
|
26
|
+
#!/usr/bin/env bun
|
|
27
|
+
#!/usr/bin/env bun
|
|
28
|
+
#!/usr/bin/env bun
|
|
29
|
+
#!/usr/bin/env bun
|
|
30
|
+
#!/usr/bin/env bun
|
|
31
|
+
#!/usr/bin/env bun
|
|
22
32
|
// @bun
|
|
23
33
|
var __create = Object.create;
|
|
24
34
|
var __getProtoOf = Object.getPrototypeOf;
|