@cfcs/core
Version:
Write once, create framework components that supports React, Vue, Svelte, and more.
89 lines (77 loc) • 2.19 kB
text/typescript
/**
* cfcs
* Copyright (c) 2022-present NAVER Corp.
* MIT license
*/
import { keys } from "../../core";
import { getObserver, getObservers } from "../utils";
/**
* @hidden
*/
export function injectReactiveSubscribe(object: Record<string, any>,) {
object["subscribe"] = function (name: string, callback: (value: any) => void) {
this[name];
getObserver(this, name).subscribe(callback);
};
object["unsubscribe"] = function (name?: string, callback?: (value: any) => void) {
if (!name) {
keys(getObservers(this)).forEach((observerName) => {
this.unsubscribe(observerName);
});
return;
}
if (!(name in this)) {
return;
}
getObserver(this, name).unsubscribe(callback);
};
}
/**
* @description `ReactiveSubscribe` is a class decorator and adds `.subscribe` and `.unsubscribe` methods.
* @category Reactive-Decorator
* @see Observe
* @example
* ```ts
import { ReactiveSubscribe, Observe } from "@cfcs/core";
@ReactiveSubscribe
class Component {
@Observe value1 = 1;
constructor() {
requestAnimationFrame(() => {
this.value1 = 2;
});
}
}
interface Component extends ReactiveSubscribe<{
value1: number;
value2: number;
}> {}
const component = new Component();
// 1
console.log(component.value1);
component.subscribe("value1", nextValue => {
// When the change event occurs => (2, 2)
console.log(nextValue, component.value2);
});
```
*/
export function ReactiveSubscribe(Constructor: any) {
const prototype = Constructor.prototype;
injectReactiveSubscribe(prototype);
}
/**
* `ReactiveSubscribe` is a class decorator and adds `.subscribe` and `.unsubscribe` methods.
* @category Reactive
*/
export interface ReactiveSubscribe<State extends Record<string, any>> {
/**
* When the value of the property changes, the callback function is called.
*/
subscribe<Name extends keyof State = keyof State>(
name: Name, callback: (value: State[Name]) => void): void;
/**
* Unregister the callback function corresponding to the property.
*/
unsubscribe<Name extends keyof State = keyof State>(
name?: Name, callback?: (value: State[Name]) => void): void;
}