UNPKG

@v4fire/client

Version:

V4Fire client core library

131 lines (115 loc) 3.47 kB
/*! * 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); }); }); } }