@v4fire/client
Version:
V4Fire client core library
131 lines (115 loc) • 3.47 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
/**
* [[include:super/i-block/modules/opt/README.md]]
* @packageDocumentation
*/
import Friend from 'super/i-block/modules/friend';
import { literalCache } from 'super/i-block/modules/opt/const';
import type { IfOnceValue } from 'super/i-block/modules/opt/interface';
export * from 'super/i-block/modules/opt/const';
export * from 'super/i-block/modules/opt/interface';
/**
* Class provides some methods to optimize an application
*/
export default class Opt extends Friend {
/** @see [[iBlock.ifOnceStore]] */
protected get ifOnceStore(): Dictionary<number> {
return this.ctx.ifOnceStore;
}
/**
* Returns a number if the specified label:
* `2` -> already exists in the cache;
* `1` -> just written in the cache;
* `0` -> does not exist in the cache.
*
* This method is used with conditions to provide a logic: if the condition was switched to true,
* then further, it always returns true.
*
* @param label
* @param [value] - label value (will be saved in the cache only if true)
*
* @example
* ```
* < .content v-if = opt.ifOnce('opened', m.opened === 'true')
* Very big content
* ```
*/
ifOnce(label: unknown, value: boolean = false): IfOnceValue {
const
strLabel = String(label);
if (this.ifOnceStore[strLabel] != null) {
return 2;
}
if (value) {
return this.ifOnceStore[strLabel] = 1;
}
return 0;
}
/**
* Tries to find a blueprint in the cache to the specified value and returns it,
* or if the value wasn't found in the cache, it would be frozen, cached, and returned.
*
* This method is used to cache raw literals within component templates to avoid redundant re-renders that occurs
* because links to objects were changed.
*
* @param literal
*
* @example
* ```
* < b-button :mods = opt.memoizeLiteral({foo: 'bla'})
* ```
*/
memoizeLiteral<T>(literal: T): T extends Array<infer V> ? readonly V[] : T extends object ? Readonly<T> : T {
if (Object.isFrozen(literal)) {
return Object.cast(literal);
}
const key = Object.fastHash(literal);
return Object.cast(literalCache[key] = literalCache[key] ?? Object.freeze(literal));
}
/**
* Shows in a terminal/console any changes of component properties.
* This method is useful to debug.
*
* @example
* ```typescript
* import iBlock, { component } from 'super/i-block/i-block';
*
* @component()
* export default class bExample extends iBlock {
* mounted() {
* this.opt.showAnyChanges();
* }
* }
* ```
*/
showAnyChanges(): void {
const cg = (name, key, val, oldVal, info) => {
console.group(`${name} "${key}" (${this.ctx.componentName})`);
console.log(Object.fastClone(val));
console.log(oldVal);
console.log('Path: ', info?.path);
console.groupEnd();
};
Object.forEach(this.ctx.$systemFields, (val, key) => {
this.ctx.watch(key, {deep: true}, (val, oldVal, info) => {
cg('System field', key, val, oldVal, info);
});
});
Object.forEach(this.ctx.$fields, (val, key) => {
this.ctx.watch(key, {deep: true}, (val, oldVal, info) => {
cg('Field', key, val, oldVal, info);
});
});
Object.forEach(this.ctx.$props, (val, key) => {
this.ctx.watch(key, {deep: true}, (val, oldVal, info) => {
cg('Prop', key, val, oldVal, info);
});
});
}
}