@zenithbuild/compiler 1.0.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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/build-analyzer.d.ts +44 -0
- package/dist/build-analyzer.js +87 -0
- package/dist/bundler.d.ts +31 -0
- package/dist/bundler.js +86 -0
- package/dist/core/components/index.d.ts +9 -0
- package/dist/core/components/index.js +13 -0
- package/dist/core/config/index.d.ts +11 -0
- package/dist/core/config/index.js +10 -0
- package/dist/core/config/loader.d.ts +17 -0
- package/dist/core/config/loader.js +60 -0
- package/dist/core/config/types.d.ts +98 -0
- package/dist/core/config/types.js +32 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +6 -0
- package/dist/core/lifecycle/index.d.ts +16 -0
- package/dist/core/lifecycle/index.js +19 -0
- package/dist/core/lifecycle/zen-mount.d.ts +66 -0
- package/dist/core/lifecycle/zen-mount.js +151 -0
- package/dist/core/lifecycle/zen-unmount.d.ts +54 -0
- package/dist/core/lifecycle/zen-unmount.js +76 -0
- package/dist/core/plugins/bridge.d.ts +116 -0
- package/dist/core/plugins/bridge.js +121 -0
- package/dist/core/plugins/index.d.ts +6 -0
- package/dist/core/plugins/index.js +6 -0
- package/dist/core/plugins/registry.d.ts +67 -0
- package/dist/core/plugins/registry.js +113 -0
- package/dist/core/reactivity/index.d.ts +30 -0
- package/dist/core/reactivity/index.js +33 -0
- package/dist/core/reactivity/tracking.d.ts +74 -0
- package/dist/core/reactivity/tracking.js +136 -0
- package/dist/core/reactivity/zen-batch.d.ts +45 -0
- package/dist/core/reactivity/zen-batch.js +54 -0
- package/dist/core/reactivity/zen-effect.d.ts +48 -0
- package/dist/core/reactivity/zen-effect.js +98 -0
- package/dist/core/reactivity/zen-memo.d.ts +43 -0
- package/dist/core/reactivity/zen-memo.js +100 -0
- package/dist/core/reactivity/zen-ref.d.ts +44 -0
- package/dist/core/reactivity/zen-ref.js +34 -0
- package/dist/core/reactivity/zen-signal.d.ts +48 -0
- package/dist/core/reactivity/zen-signal.js +84 -0
- package/dist/core/reactivity/zen-state.d.ts +35 -0
- package/dist/core/reactivity/zen-state.js +147 -0
- package/dist/core/reactivity/zen-untrack.d.ts +38 -0
- package/dist/core/reactivity/zen-untrack.js +41 -0
- package/dist/css/index.d.ts +73 -0
- package/dist/css/index.js +246 -0
- package/dist/discovery/componentDiscovery.d.ts +42 -0
- package/dist/discovery/componentDiscovery.js +56 -0
- package/dist/discovery/layouts.d.ts +13 -0
- package/dist/discovery/layouts.js +41 -0
- package/dist/errors/compilerError.d.ts +31 -0
- package/dist/errors/compilerError.js +51 -0
- package/dist/finalize/finalizeOutput.d.ts +32 -0
- package/dist/finalize/finalizeOutput.js +62 -0
- package/dist/finalize/generateFinalBundle.d.ts +24 -0
- package/dist/finalize/generateFinalBundle.js +68 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +51 -0
- package/dist/ir/types.d.ts +181 -0
- package/dist/ir/types.js +8 -0
- package/dist/output/types.d.ts +30 -0
- package/dist/output/types.js +6 -0
- package/dist/parse/detectMapExpressions.d.ts +45 -0
- package/dist/parse/detectMapExpressions.js +77 -0
- package/dist/parse/parseScript.d.ts +8 -0
- package/dist/parse/parseScript.js +36 -0
- package/dist/parse/parseTemplate.d.ts +11 -0
- package/dist/parse/parseTemplate.js +487 -0
- package/dist/parse/parseZenFile.d.ts +11 -0
- package/dist/parse/parseZenFile.js +50 -0
- package/dist/parse/scriptAnalysis.d.ts +25 -0
- package/dist/parse/scriptAnalysis.js +60 -0
- package/dist/parse/trackLoopContext.d.ts +20 -0
- package/dist/parse/trackLoopContext.js +62 -0
- package/dist/parseZenFile.d.ts +10 -0
- package/dist/parseZenFile.js +55 -0
- package/dist/runtime/analyzeAndEmit.d.ts +20 -0
- package/dist/runtime/analyzeAndEmit.js +70 -0
- package/dist/runtime/build.d.ts +6 -0
- package/dist/runtime/build.js +13 -0
- package/dist/runtime/bundle-generator.d.ts +27 -0
- package/dist/runtime/bundle-generator.js +1263 -0
- package/dist/runtime/client-runtime.d.ts +41 -0
- package/dist/runtime/client-runtime.js +397 -0
- package/dist/runtime/dataExposure.d.ts +52 -0
- package/dist/runtime/dataExposure.js +227 -0
- package/dist/runtime/generateDOM.d.ts +21 -0
- package/dist/runtime/generateDOM.js +194 -0
- package/dist/runtime/generateHydrationBundle.d.ts +15 -0
- package/dist/runtime/generateHydrationBundle.js +399 -0
- package/dist/runtime/hydration.d.ts +53 -0
- package/dist/runtime/hydration.js +271 -0
- package/dist/runtime/navigation.d.ts +58 -0
- package/dist/runtime/navigation.js +372 -0
- package/dist/runtime/serve.d.ts +13 -0
- package/dist/runtime/serve.js +76 -0
- package/dist/runtime/thinRuntime.d.ts +23 -0
- package/dist/runtime/thinRuntime.js +158 -0
- package/dist/runtime/transformIR.d.ts +19 -0
- package/dist/runtime/transformIR.js +285 -0
- package/dist/runtime/wrapExpression.d.ts +24 -0
- package/dist/runtime/wrapExpression.js +76 -0
- package/dist/runtime/wrapExpressionWithLoop.d.ts +17 -0
- package/dist/runtime/wrapExpressionWithLoop.js +75 -0
- package/dist/spa-build.d.ts +26 -0
- package/dist/spa-build.js +866 -0
- package/dist/ssg-build.d.ts +32 -0
- package/dist/ssg-build.js +408 -0
- package/dist/test/analyze-emit.test.d.ts +1 -0
- package/dist/test/analyze-emit.test.js +88 -0
- package/dist/test/bundler-contract.test.d.ts +1 -0
- package/dist/test/bundler-contract.test.js +137 -0
- package/dist/test/compiler-authority.test.d.ts +1 -0
- package/dist/test/compiler-authority.test.js +90 -0
- package/dist/test/component-instance-test.d.ts +1 -0
- package/dist/test/component-instance-test.js +115 -0
- package/dist/test/error-native-bridge.test.d.ts +1 -0
- package/dist/test/error-native-bridge.test.js +51 -0
- package/dist/test/error-serialization.test.d.ts +1 -0
- package/dist/test/error-serialization.test.js +38 -0
- package/dist/test/macro-inlining.test.d.ts +1 -0
- package/dist/test/macro-inlining.test.js +178 -0
- package/dist/test/validate-test.d.ts +6 -0
- package/dist/test/validate-test.js +95 -0
- package/dist/transform/classifyExpression.d.ts +46 -0
- package/dist/transform/classifyExpression.js +354 -0
- package/dist/transform/componentResolver.d.ts +15 -0
- package/dist/transform/componentResolver.js +30 -0
- package/dist/transform/expressionTransformer.d.ts +19 -0
- package/dist/transform/expressionTransformer.js +333 -0
- package/dist/transform/fragmentLowering.d.ts +25 -0
- package/dist/transform/fragmentLowering.js +468 -0
- package/dist/transform/layoutProcessor.d.ts +5 -0
- package/dist/transform/layoutProcessor.js +34 -0
- package/dist/transform/transformTemplate.d.ts +11 -0
- package/dist/transform/transformTemplate.js +33 -0
- package/dist/validate/invariants.d.ts +23 -0
- package/dist/validate/invariants.js +55 -0
- package/native/compiler-native/compiler-native.node +0 -0
- package/native/compiler-native/index.d.ts +113 -0
- package/native/compiler-native/index.js +19 -0
- package/native/compiler-native/package.json +19 -0
- package/package.json +49 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Memo - Computed/Derived Value
|
|
3
|
+
*
|
|
4
|
+
* A memo is a lazily-evaluated, cached computation that automatically
|
|
5
|
+
* tracks its dependencies and only recomputes when those dependencies change.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Lazy evaluation (only computes when read)
|
|
9
|
+
* - Automatic dependency tracking
|
|
10
|
+
* - Cached value until dependencies change
|
|
11
|
+
* - Read-only (no setter)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const firstName = zenSignal('John')
|
|
16
|
+
* const lastName = zenSignal('Doe')
|
|
17
|
+
*
|
|
18
|
+
* // Memo computes full name, tracks firstName and lastName
|
|
19
|
+
* const fullName = zenMemo(() => `${firstName()} ${lastName()}`)
|
|
20
|
+
*
|
|
21
|
+
* console.log(fullName()) // "John Doe"
|
|
22
|
+
*
|
|
23
|
+
* firstName('Jane')
|
|
24
|
+
* console.log(fullName()) // "Jane Doe" (recomputed)
|
|
25
|
+
* console.log(fullName()) // "Jane Doe" (cached, no recomputation)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import { pushContext, popContext, cleanupContext, trackDependency } from './tracking';
|
|
29
|
+
/**
|
|
30
|
+
* Create a memoized computed value
|
|
31
|
+
*
|
|
32
|
+
* @param fn - The computation function
|
|
33
|
+
* @returns A memo that can be read to get the computed value
|
|
34
|
+
*/
|
|
35
|
+
export function zenMemo(fn) {
|
|
36
|
+
const state = {
|
|
37
|
+
fn,
|
|
38
|
+
value: undefined,
|
|
39
|
+
dirty: true,
|
|
40
|
+
context: {
|
|
41
|
+
execute: () => markDirty(state),
|
|
42
|
+
dependencies: new Set()
|
|
43
|
+
},
|
|
44
|
+
subscribers: new Set(),
|
|
45
|
+
initialized: false
|
|
46
|
+
};
|
|
47
|
+
function memo() {
|
|
48
|
+
// Track that something is reading this memo
|
|
49
|
+
trackDependency(state.subscribers);
|
|
50
|
+
// Recompute if dirty
|
|
51
|
+
if (state.dirty) {
|
|
52
|
+
computeMemo(state);
|
|
53
|
+
}
|
|
54
|
+
return state.value;
|
|
55
|
+
}
|
|
56
|
+
// Add peek method
|
|
57
|
+
;
|
|
58
|
+
memo.peek = function () {
|
|
59
|
+
// Return cached value without tracking or recomputing
|
|
60
|
+
if (state.dirty && !state.initialized) {
|
|
61
|
+
computeMemo(state);
|
|
62
|
+
}
|
|
63
|
+
return state.value;
|
|
64
|
+
};
|
|
65
|
+
return memo;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Compute the memo value, tracking dependencies
|
|
69
|
+
*/
|
|
70
|
+
function computeMemo(state) {
|
|
71
|
+
// Clean up old dependencies
|
|
72
|
+
cleanupContext(state.context);
|
|
73
|
+
// Push this memo onto the tracking stack
|
|
74
|
+
pushContext(state.context);
|
|
75
|
+
try {
|
|
76
|
+
// Compute new value
|
|
77
|
+
state.value = state.fn();
|
|
78
|
+
state.dirty = false;
|
|
79
|
+
state.initialized = true;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
// Pop from tracking stack
|
|
83
|
+
popContext();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Mark the memo as dirty (needs recomputation)
|
|
88
|
+
* Called when a dependency changes
|
|
89
|
+
*/
|
|
90
|
+
function markDirty(state) {
|
|
91
|
+
if (!state.dirty) {
|
|
92
|
+
state.dirty = true;
|
|
93
|
+
// Notify any effects/memos that depend on this memo
|
|
94
|
+
// Copy to avoid issues during iteration
|
|
95
|
+
const subscribers = [...state.subscribers];
|
|
96
|
+
for (const subscriber of subscribers) {
|
|
97
|
+
subscriber();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Ref - Mutable Reference Container
|
|
3
|
+
*
|
|
4
|
+
* A ref is a mutable container that does NOT trigger reactivity.
|
|
5
|
+
* It's useful for:
|
|
6
|
+
* - Storing DOM element references
|
|
7
|
+
* - Imperative escape hatches
|
|
8
|
+
* - Values that change but shouldn't trigger re-renders
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Mutable `.current` property
|
|
12
|
+
* - Does NOT track dependencies
|
|
13
|
+
* - Does NOT trigger effects
|
|
14
|
+
* - Persists across effect re-runs
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // DOM reference
|
|
19
|
+
* const inputRef = zenRef<HTMLInputElement>()
|
|
20
|
+
*
|
|
21
|
+
* // Later, after mount
|
|
22
|
+
* inputRef.current = document.querySelector('input')
|
|
23
|
+
* inputRef.current?.focus()
|
|
24
|
+
*
|
|
25
|
+
* // Mutable value that doesn't trigger reactivity
|
|
26
|
+
* const previousValue = zenRef(0)
|
|
27
|
+
* previousValue.current = count() // No effect triggered
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Ref interface - mutable container with .current
|
|
32
|
+
*/
|
|
33
|
+
export interface Ref<T> {
|
|
34
|
+
/** The current value */
|
|
35
|
+
current: T;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a mutable reference container
|
|
39
|
+
*
|
|
40
|
+
* @param initialValue - The initial value (optional, defaults to undefined)
|
|
41
|
+
* @returns A ref object with a mutable .current property
|
|
42
|
+
*/
|
|
43
|
+
export declare function zenRef<T>(): Ref<T | undefined>;
|
|
44
|
+
export declare function zenRef<T>(initialValue: T): Ref<T>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Ref - Mutable Reference Container
|
|
3
|
+
*
|
|
4
|
+
* A ref is a mutable container that does NOT trigger reactivity.
|
|
5
|
+
* It's useful for:
|
|
6
|
+
* - Storing DOM element references
|
|
7
|
+
* - Imperative escape hatches
|
|
8
|
+
* - Values that change but shouldn't trigger re-renders
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Mutable `.current` property
|
|
12
|
+
* - Does NOT track dependencies
|
|
13
|
+
* - Does NOT trigger effects
|
|
14
|
+
* - Persists across effect re-runs
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // DOM reference
|
|
19
|
+
* const inputRef = zenRef<HTMLInputElement>()
|
|
20
|
+
*
|
|
21
|
+
* // Later, after mount
|
|
22
|
+
* inputRef.current = document.querySelector('input')
|
|
23
|
+
* inputRef.current?.focus()
|
|
24
|
+
*
|
|
25
|
+
* // Mutable value that doesn't trigger reactivity
|
|
26
|
+
* const previousValue = zenRef(0)
|
|
27
|
+
* previousValue.current = count() // No effect triggered
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function zenRef(initialValue) {
|
|
31
|
+
return {
|
|
32
|
+
current: initialValue
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Signal - Atomic Reactive Value
|
|
3
|
+
*
|
|
4
|
+
* A signal is the most basic reactive primitive. It holds a single value
|
|
5
|
+
* and notifies subscribers when the value changes.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Getter/setter model
|
|
9
|
+
* - Automatic dependency tracking
|
|
10
|
+
* - Fine-grained reactivity (no component re-rendering)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const count = zenSignal(0)
|
|
15
|
+
*
|
|
16
|
+
* // Read value
|
|
17
|
+
* console.log(count()) // 0
|
|
18
|
+
*
|
|
19
|
+
* // Write value
|
|
20
|
+
* count(1)
|
|
21
|
+
*
|
|
22
|
+
* // Or use .value
|
|
23
|
+
* count.value = 2
|
|
24
|
+
* console.log(count.value) // 2
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Signal interface - callable getter/setter with .value accessor
|
|
29
|
+
*/
|
|
30
|
+
export interface Signal<T> {
|
|
31
|
+
/** Get the current value (also tracks dependency) */
|
|
32
|
+
(): T;
|
|
33
|
+
/** Set a new value */
|
|
34
|
+
(value: T): void;
|
|
35
|
+
/** Get/set value via property */
|
|
36
|
+
value: T;
|
|
37
|
+
/** Peek at value without tracking */
|
|
38
|
+
peek(): T;
|
|
39
|
+
/** Subscribe to changes */
|
|
40
|
+
subscribe(fn: (value: T) => void): () => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a reactive signal
|
|
44
|
+
*
|
|
45
|
+
* @param initialValue - The initial value of the signal
|
|
46
|
+
* @returns A signal that can be read and written
|
|
47
|
+
*/
|
|
48
|
+
export declare function zenSignal<T>(initialValue: T): Signal<T>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Signal - Atomic Reactive Value
|
|
3
|
+
*
|
|
4
|
+
* A signal is the most basic reactive primitive. It holds a single value
|
|
5
|
+
* and notifies subscribers when the value changes.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Getter/setter model
|
|
9
|
+
* - Automatic dependency tracking
|
|
10
|
+
* - Fine-grained reactivity (no component re-rendering)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const count = zenSignal(0)
|
|
15
|
+
*
|
|
16
|
+
* // Read value
|
|
17
|
+
* console.log(count()) // 0
|
|
18
|
+
*
|
|
19
|
+
* // Write value
|
|
20
|
+
* count(1)
|
|
21
|
+
*
|
|
22
|
+
* // Or use .value
|
|
23
|
+
* count.value = 2
|
|
24
|
+
* console.log(count.value) // 2
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import { trackDependency, notifySubscribers } from './tracking';
|
|
28
|
+
/**
|
|
29
|
+
* Create a reactive signal
|
|
30
|
+
*
|
|
31
|
+
* @param initialValue - The initial value of the signal
|
|
32
|
+
* @returns A signal that can be read and written
|
|
33
|
+
*/
|
|
34
|
+
export function zenSignal(initialValue) {
|
|
35
|
+
const state = {
|
|
36
|
+
value: initialValue,
|
|
37
|
+
subscribers: new Set()
|
|
38
|
+
};
|
|
39
|
+
// The signal function - acts as both getter and setter
|
|
40
|
+
function signal(newValue) {
|
|
41
|
+
if (arguments.length === 0) {
|
|
42
|
+
// Getter - track dependency and return value
|
|
43
|
+
trackDependency(state.subscribers);
|
|
44
|
+
return state.value;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Setter - update value and notify
|
|
48
|
+
const oldValue = state.value;
|
|
49
|
+
state.value = newValue;
|
|
50
|
+
if (!Object.is(oldValue, newValue)) {
|
|
51
|
+
notifySubscribers(state.subscribers);
|
|
52
|
+
}
|
|
53
|
+
return state.value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Add .value accessor
|
|
57
|
+
Object.defineProperty(signal, 'value', {
|
|
58
|
+
get() {
|
|
59
|
+
trackDependency(state.subscribers);
|
|
60
|
+
return state.value;
|
|
61
|
+
},
|
|
62
|
+
set(newValue) {
|
|
63
|
+
const oldValue = state.value;
|
|
64
|
+
state.value = newValue;
|
|
65
|
+
if (!Object.is(oldValue, newValue)) {
|
|
66
|
+
notifySubscribers(state.subscribers);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
enumerable: true,
|
|
70
|
+
configurable: false
|
|
71
|
+
});
|
|
72
|
+
signal.peek = function () {
|
|
73
|
+
return state.value;
|
|
74
|
+
};
|
|
75
|
+
signal.subscribe = function (fn) {
|
|
76
|
+
const subscriber = () => fn(state.value);
|
|
77
|
+
state.subscribers.add(subscriber);
|
|
78
|
+
// Return unsubscribe function
|
|
79
|
+
return () => {
|
|
80
|
+
state.subscribers.delete(subscriber);
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
return signal;
|
|
84
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith State - Deep Reactive Object
|
|
3
|
+
*
|
|
4
|
+
* Creates a deeply reactive object using Proxy. Any property access
|
|
5
|
+
* is tracked, and any mutation triggers effects.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Deep reactivity via nested Proxies
|
|
9
|
+
* - Automatic dependency tracking on property access
|
|
10
|
+
* - Triggers effects on property mutation
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const user = zenState({
|
|
15
|
+
* name: 'John',
|
|
16
|
+
* address: {
|
|
17
|
+
* city: 'NYC'
|
|
18
|
+
* }
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* // Access triggers tracking
|
|
22
|
+
* console.log(user.name)
|
|
23
|
+
*
|
|
24
|
+
* // Mutation triggers effects
|
|
25
|
+
* user.name = 'Jane'
|
|
26
|
+
* user.address.city = 'LA'
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Create a deeply reactive state object
|
|
31
|
+
*
|
|
32
|
+
* @param initialValue - The initial state object
|
|
33
|
+
* @returns A reactive proxy of the object
|
|
34
|
+
*/
|
|
35
|
+
export declare function zenState<T extends object>(initialValue: T): T;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith State - Deep Reactive Object
|
|
3
|
+
*
|
|
4
|
+
* Creates a deeply reactive object using Proxy. Any property access
|
|
5
|
+
* is tracked, and any mutation triggers effects.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Deep reactivity via nested Proxies
|
|
9
|
+
* - Automatic dependency tracking on property access
|
|
10
|
+
* - Triggers effects on property mutation
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const user = zenState({
|
|
15
|
+
* name: 'John',
|
|
16
|
+
* address: {
|
|
17
|
+
* city: 'NYC'
|
|
18
|
+
* }
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* // Access triggers tracking
|
|
22
|
+
* console.log(user.name)
|
|
23
|
+
*
|
|
24
|
+
* // Mutation triggers effects
|
|
25
|
+
* user.name = 'Jane'
|
|
26
|
+
* user.address.city = 'LA'
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { trackDependency, notifySubscribers } from './tracking';
|
|
30
|
+
/**
|
|
31
|
+
* WeakMap to store proxy targets and their subscriber maps
|
|
32
|
+
* Key: target object
|
|
33
|
+
* Value: Map of property key -> subscriber set
|
|
34
|
+
*/
|
|
35
|
+
const proxySubscribers = new WeakMap();
|
|
36
|
+
/**
|
|
37
|
+
* WeakMap to store original objects and their proxies
|
|
38
|
+
* Prevents creating multiple proxies for the same object
|
|
39
|
+
*/
|
|
40
|
+
const proxyCache = new WeakMap();
|
|
41
|
+
/**
|
|
42
|
+
* Get or create subscriber set for a property
|
|
43
|
+
*/
|
|
44
|
+
function getPropertySubscribers(target, key) {
|
|
45
|
+
let propertyMap = proxySubscribers.get(target);
|
|
46
|
+
if (!propertyMap) {
|
|
47
|
+
propertyMap = new Map();
|
|
48
|
+
proxySubscribers.set(target, propertyMap);
|
|
49
|
+
}
|
|
50
|
+
let subscribers = propertyMap.get(key);
|
|
51
|
+
if (!subscribers) {
|
|
52
|
+
subscribers = new Set();
|
|
53
|
+
propertyMap.set(key, subscribers);
|
|
54
|
+
}
|
|
55
|
+
return subscribers;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a value should be wrapped in a proxy
|
|
59
|
+
*/
|
|
60
|
+
function shouldProxy(value) {
|
|
61
|
+
if (value === null || typeof value !== 'object') {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
// Don't proxy special objects
|
|
65
|
+
if (value instanceof Date ||
|
|
66
|
+
value instanceof RegExp ||
|
|
67
|
+
value instanceof Map ||
|
|
68
|
+
value instanceof Set ||
|
|
69
|
+
value instanceof WeakMap ||
|
|
70
|
+
value instanceof WeakSet ||
|
|
71
|
+
value instanceof Promise ||
|
|
72
|
+
ArrayBuffer.isView(value)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create a reactive proxy for an object
|
|
79
|
+
*/
|
|
80
|
+
function createReactiveProxy(target) {
|
|
81
|
+
// Check cache first
|
|
82
|
+
const cached = proxyCache.get(target);
|
|
83
|
+
if (cached) {
|
|
84
|
+
return cached;
|
|
85
|
+
}
|
|
86
|
+
const proxy = new Proxy(target, {
|
|
87
|
+
get(target, key, receiver) {
|
|
88
|
+
// Track dependency
|
|
89
|
+
const subscribers = getPropertySubscribers(target, key);
|
|
90
|
+
trackDependency(subscribers);
|
|
91
|
+
const value = Reflect.get(target, key, receiver);
|
|
92
|
+
// Recursively proxy nested objects
|
|
93
|
+
if (shouldProxy(value)) {
|
|
94
|
+
return createReactiveProxy(value);
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
},
|
|
98
|
+
set(target, key, value, receiver) {
|
|
99
|
+
const oldValue = Reflect.get(target, key, receiver);
|
|
100
|
+
// Unwrap proxies before storing
|
|
101
|
+
const rawValue = value;
|
|
102
|
+
const result = Reflect.set(target, key, rawValue, receiver);
|
|
103
|
+
// Only notify if value actually changed
|
|
104
|
+
if (!Object.is(oldValue, rawValue)) {
|
|
105
|
+
const subscribers = getPropertySubscribers(target, key);
|
|
106
|
+
notifySubscribers(subscribers);
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
},
|
|
110
|
+
deleteProperty(target, key) {
|
|
111
|
+
const hadKey = Reflect.has(target, key);
|
|
112
|
+
const result = Reflect.deleteProperty(target, key);
|
|
113
|
+
if (hadKey && result) {
|
|
114
|
+
const subscribers = getPropertySubscribers(target, key);
|
|
115
|
+
notifySubscribers(subscribers);
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
},
|
|
119
|
+
has(target, key) {
|
|
120
|
+
// Track dependency for 'in' operator
|
|
121
|
+
const subscribers = getPropertySubscribers(target, key);
|
|
122
|
+
trackDependency(subscribers);
|
|
123
|
+
return Reflect.has(target, key);
|
|
124
|
+
},
|
|
125
|
+
ownKeys(target) {
|
|
126
|
+
// Track a special 'keys' dependency for iteration
|
|
127
|
+
const subscribers = getPropertySubscribers(target, Symbol.for('zen:keys'));
|
|
128
|
+
trackDependency(subscribers);
|
|
129
|
+
return Reflect.ownKeys(target);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// Cache the proxy
|
|
133
|
+
proxyCache.set(target, proxy);
|
|
134
|
+
return proxy;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Create a deeply reactive state object
|
|
138
|
+
*
|
|
139
|
+
* @param initialValue - The initial state object
|
|
140
|
+
* @returns A reactive proxy of the object
|
|
141
|
+
*/
|
|
142
|
+
export function zenState(initialValue) {
|
|
143
|
+
if (!shouldProxy(initialValue)) {
|
|
144
|
+
throw new Error('zenState requires a plain object or array');
|
|
145
|
+
}
|
|
146
|
+
return createReactiveProxy(initialValue);
|
|
147
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Untrack - Escape Dependency Tracking
|
|
3
|
+
*
|
|
4
|
+
* Allows reading reactive values without creating a dependency.
|
|
5
|
+
* Useful when you need to read a value inside an effect but don't
|
|
6
|
+
* want the effect to re-run when that value changes.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Disables dependency tracking within the callback
|
|
10
|
+
* - Returns the callback's return value
|
|
11
|
+
* - Can be nested
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const count = zenSignal(0)
|
|
16
|
+
* const multiplier = zenSignal(2)
|
|
17
|
+
*
|
|
18
|
+
* zenEffect(() => {
|
|
19
|
+
* // This creates a dependency on 'count'
|
|
20
|
+
* const c = count()
|
|
21
|
+
*
|
|
22
|
+
* // This does NOT create a dependency on 'multiplier'
|
|
23
|
+
* const m = zenUntrack(() => multiplier())
|
|
24
|
+
*
|
|
25
|
+
* console.log(c * m)
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* count(5) // Effect re-runs
|
|
29
|
+
* multiplier(3) // Effect does NOT re-run
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Execute a function without tracking dependencies
|
|
34
|
+
*
|
|
35
|
+
* @param fn - The function to execute
|
|
36
|
+
* @returns The return value of the function
|
|
37
|
+
*/
|
|
38
|
+
export declare function zenUntrack<T>(fn: () => T): T;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Untrack - Escape Dependency Tracking
|
|
3
|
+
*
|
|
4
|
+
* Allows reading reactive values without creating a dependency.
|
|
5
|
+
* Useful when you need to read a value inside an effect but don't
|
|
6
|
+
* want the effect to re-run when that value changes.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Disables dependency tracking within the callback
|
|
10
|
+
* - Returns the callback's return value
|
|
11
|
+
* - Can be nested
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const count = zenSignal(0)
|
|
16
|
+
* const multiplier = zenSignal(2)
|
|
17
|
+
*
|
|
18
|
+
* zenEffect(() => {
|
|
19
|
+
* // This creates a dependency on 'count'
|
|
20
|
+
* const c = count()
|
|
21
|
+
*
|
|
22
|
+
* // This does NOT create a dependency on 'multiplier'
|
|
23
|
+
* const m = zenUntrack(() => multiplier())
|
|
24
|
+
*
|
|
25
|
+
* console.log(c * m)
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* count(5) // Effect re-runs
|
|
29
|
+
* multiplier(3) // Effect does NOT re-run
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { runUntracked } from './tracking';
|
|
33
|
+
/**
|
|
34
|
+
* Execute a function without tracking dependencies
|
|
35
|
+
*
|
|
36
|
+
* @param fn - The function to execute
|
|
37
|
+
* @returns The return value of the function
|
|
38
|
+
*/
|
|
39
|
+
export function zenUntrack(fn) {
|
|
40
|
+
return runUntracked(fn);
|
|
41
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith CSS Compiler Module
|
|
3
|
+
*
|
|
4
|
+
* Compiler-owned CSS processing that integrates Tailwind CSS v4 JIT
|
|
5
|
+
* at compile time. This module ensures:
|
|
6
|
+
*
|
|
7
|
+
* 1. All CSS is processed at build time (no runtime generation)
|
|
8
|
+
* 2. Tailwind sees all .zen templates for class scanning
|
|
9
|
+
* 3. HMR support for instant CSS updates in dev mode
|
|
10
|
+
* 4. Deterministic, cacheable output for production
|
|
11
|
+
*
|
|
12
|
+
* Per Zenith CSS Directive: The compiler owns styles.
|
|
13
|
+
*/
|
|
14
|
+
export interface CSSCompileOptions {
|
|
15
|
+
/** Input CSS file path (e.g., src/styles/globals.css) */
|
|
16
|
+
input: string;
|
|
17
|
+
/** Output CSS file path, or ':memory:' for in-memory result */
|
|
18
|
+
output: string;
|
|
19
|
+
/** Enable minification for production */
|
|
20
|
+
minify?: boolean;
|
|
21
|
+
/** Watch mode for HMR */
|
|
22
|
+
watch?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface CSSCompileResult {
|
|
25
|
+
/** Compiled CSS content */
|
|
26
|
+
css: string;
|
|
27
|
+
/** Compilation time in milliseconds */
|
|
28
|
+
duration: number;
|
|
29
|
+
/** Whether compilation succeeded */
|
|
30
|
+
success: boolean;
|
|
31
|
+
/** Error message if failed */
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Compile CSS using Tailwind CSS v4 CLI
|
|
36
|
+
*
|
|
37
|
+
* This function synchronously compiles CSS for use in:
|
|
38
|
+
* - Dev server startup
|
|
39
|
+
* - SSG build
|
|
40
|
+
* - On-demand recompilation
|
|
41
|
+
*
|
|
42
|
+
* @param options Compilation options
|
|
43
|
+
* @returns Compiled CSS result
|
|
44
|
+
*/
|
|
45
|
+
export declare function compileCss(options: CSSCompileOptions): CSSCompileResult;
|
|
46
|
+
/**
|
|
47
|
+
* Compile CSS asynchronously (non-blocking)
|
|
48
|
+
*
|
|
49
|
+
* Used for HMR updates where we don't want to block the main thread.
|
|
50
|
+
*/
|
|
51
|
+
export declare function compileCssAsync(options: CSSCompileOptions): Promise<CSSCompileResult>;
|
|
52
|
+
export interface CSSWatchOptions extends CSSCompileOptions {
|
|
53
|
+
/** Callback when CSS changes */
|
|
54
|
+
onChange: (result: CSSCompileResult) => void;
|
|
55
|
+
/** Debounce delay in ms */
|
|
56
|
+
debounce?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Watch CSS and source files for changes, recompile on change
|
|
60
|
+
*
|
|
61
|
+
* This is used by the dev server for HMR support.
|
|
62
|
+
* It watches both the CSS entry point AND all .zen files
|
|
63
|
+
* that Tailwind scans for class names.
|
|
64
|
+
*/
|
|
65
|
+
export declare function watchCss(options: CSSWatchOptions): () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve the canonical globals.css path for a Zenith project
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveGlobalsCss(projectRoot: string): string | null;
|
|
70
|
+
/**
|
|
71
|
+
* Get the output path for compiled CSS
|
|
72
|
+
*/
|
|
73
|
+
export declare function getCompiledCssPath(projectRoot: string, mode: 'dev' | 'build'): string;
|