--- /dev/null
+import { value, isValue, Value } from './apiState'
+import { currentInstance } from './component'
+
+export interface Key<T> extends Symbol {}
+
+export function provide<T>(key: Key<T>, value: T | Value<T>) {
+ if (!currentInstance) {
+ // TODO warn
+ } else {
+ const provides = currentInstance.provides || (currentInstance.provides = {})
+ provides[key as any] = value
+ }
+}
+
+export function inject<T>(key: Key<T>): Value<T> | undefined {
+ // traverse parent chain and look for provided value
+ if (!currentInstance) {
+ // TODO warn
+ } else {
+ let parent = currentInstance.parent
+ while (parent) {
+ const { provides } = parent
+ if (provides !== null && provides.hasOwnProperty(key as any)) {
+ const val = provides[key as any]
+ return isValue(val) ? val : value(val)
+ }
+ parent = parent.parent
+ }
+ }
+}
type LifecycleHook = Function[] | null
-interface LifecycleHooks {
+export interface LifecycleHooks {
bm: LifecycleHook // beforeMount
m: LifecycleHook // mounted
bu: LifecycleHook // beforeUpdate
next: VNode | null
subTree: VNode
update: ReactiveEffect
- effects: ReactiveEffect[] | null
render: RenderFunction<P, S> | null
+ effects: ReactiveEffect[] | null
+ provides: Data | null
// the rest are only for stateful components
data: S
rtc: null,
ec: null,
effects: null,
+ provides: null,
// public properties
data: EMPTY_OBJ,
export * from './apiState'
export * from './apiWatch'
export * from './apiLifecycle'
+export * from './apiInject'
export * from './patchFlags'
export * from './typeFlags'