<commit_before>/*!
 * V4Fire Client Core
 * https://github.com/V4Fire/Client
 *
 * Released under the MIT license
 * https://github.com/V4Fire/Client/blob/master/LICENSE
 */

import $C = require('collection.js');
import {

	CreateElement,
	RenderContext,
	VNode,
	FunctionalComponentOptions,
	WatchOptions,
	WatchOptionsWithHandler

} from 'vue';

import { EventEmitter2 as EventEmitter } from 'eventemitter2';
import { VueElement, FunctionalCtx } from 'core/component';
import { runHook, createMeta, initDataObject, bindWatchers, defaultWrapper } from 'core/component/component';

const
	cache = new WeakMap();

/**
 * Generates a fake context for a function component
 *
 * @param createElement - Vue.createElement
 * @param renderCtx - Vue.RenderContext
 * @param baseCtx - base component context (methods, accessors, etc.)
 */
export function createFakeCtx(
	createElement: CreateElement,
	renderCtx: RenderContext,
	baseCtx: FunctionalCtx
): Dictionary & FunctionalCtx {
	const
		fakeCtx: Dictionary & FunctionalCtx = Object.create(baseCtx),
		meta = createMeta(fakeCtx.meta);

	const
		{instance} = fakeCtx,
		{methods} = meta;

	const
		p = <Dictionary>renderCtx.parent,
		watchers = new EventEmitter({maxListeners: 1e3}),
		event = new EventEmitter({maxListeners: 1e3});

	// Add base methods and properties
	Object.assign(fakeCtx, renderCtx, renderCtx.props, {
		_self: fakeCtx,
		_staticTrees: [],

		meta,
		children: [],

		$root: p.$root,
		$parent: p,
		$options: Object.assign(Object.create(p.$options), fakeCtx.$options),

		$refs: {},
		$attrs: renderCtx.data.attrs,
		$slots: {default: renderCtx.children, ...renderCtx.slots()},
		$scopedSlots: {},

		$nextTick: p.$nextTick,
		$createElement: createElement,

		$destroy(): void {
			$C(['beforeDestroy', 'destroyed']).forEach((key) => {
				runHook(key, meta, fakeCtx).then(async () => {
					if (methods[key]) {
						await methods[key].fn.call(fakeCtx);
					}
				}, stderr);
			});
		},

		$forceUpdate(): void {
			p.forceUpdate().catch(stderr);
		},

		$watch(
			exprOrFn: string | (() => string),
			cbOrOpts: (n: any, o: any) => void | WatchOptionsWithHandler<any>,
			opts?: WatchOptions
		): (() => void) {
			let
				cb = cbOrOpts;

			if (Object.isObject(cbOrOpts)) {
				cb = (<any>cbOrOpts).handler;
				opts = <any>cbOrOpts;
			}

			const
				expr = Object.isFunction(exprOrFn) ? exprOrFn.call(this) : exprOrFn;

			cb = cb.bind(this);
			watchers.on(expr, cb);

			if (opts && opts.immediate) {
				watchers.emit(expr, this.getField(expr));
			}

			return () => watchers.off(expr, cb);<commit_msg>Fixed next tick<commit_after>/*!
 * V4Fire Client Core
 * https://github.com/V4Fire/Client
 *
 * Released under the MIT license
 * https://github.com/V4Fire/Client/blob/master/LICENSE
 */

import $C = require('collection.js');
import {

	CreateElement,
	RenderContext,
	VNode,
	FunctionalComponentOptions,
	WatchOptions,
	WatchOptionsWithHandler

} from 'vue';

import { EventEmitter2 as EventEmitter } from 'eventemitter2';
import { VueElement, FunctionalCtx } from 'core/component';
import { runHook, createMeta, initDataObject, bindWatchers, defaultWrapper } from 'core/component/component';

const
	cache = new WeakMap();

/**
 * Generates a fake context for a function component
 *
 * @param createElement - Vue.createElement
 * @param renderCtx - Vue.RenderContext
 * @param baseCtx - base component context (methods, accessors, etc.)
 */
export function createFakeCtx(
	createElement: CreateElement,
	renderCtx: RenderContext,
	baseCtx: FunctionalCtx
): Dictionary & FunctionalCtx {
	const
		fakeCtx: Dictionary & FunctionalCtx = Object.create(baseCtx),
		meta = createMeta(fakeCtx.meta);

	const
		{instance} = fakeCtx,
		{methods} = meta;

	const
		p = <Dictionary>renderCtx.parent,
		watchers = new EventEmitter({maxListeners: 1e3}),
		event = new EventEmitter({maxListeners: 1e3});

	// Add base methods and properties
	Object.assign(fakeCtx, renderCtx, renderCtx.props, {
		_self: fakeCtx,
		_staticTrees: [],

		meta,
		children: [],

		$root: p.$root,
		$parent: p,
		$options: Object.assign(Object.create(p.$options), fakeCtx.$options),

		$refs: {},
		$attrs: renderCtx.data.attrs,
		$slots: {default: renderCtx.children, ...renderCtx.slots()},
		$scopedSlots: {},
		$createElement: createElement,

		$destroy(): void {
			$C(['beforeDestroy', 'destroyed']).forEach((key) => {
				runHook(key, meta, fakeCtx).then(async () => {
					if (methods[key]) {
						await methods[key].fn.call(fakeCtx);
					}
				}, stderr);
			});
		},

		$nextTick(cb?: () => void): Promise<void> | void {
			if (cb) {
				cb();
				return;
			}

			return Promise.resolve();
		},

		$forceUpdate(): void {
			p.forceUpdate().catch(stderr);
		},

		$watch(
			exprOrFn: string | (() => string),
			cbOrOpts: (n: any, o: any) => void | WatchOptionsWithHandler<any>,
			opts?: WatchOptions
		): (() => void) {
			let
				cb = cbOrOpts;

			if (Object.isObject(cbOrOpts)) {
				cb = (<any>cbOrOpts).handler;
				opts = <any>cbOrOpts;
			}

			const
				expr = Object.isFunction(exprOrFn) ? exprOrFn.call(this) : exprOrFn;

			cb = cb.bind(this);
			watchers.on(expr, cb);

			if (opts && opts.immediate) {
				watchers.emit(expr, this.getField(expr));
			}

			return () => watchers.off(expr, cb);
{'fraction_non_alphanumeric': 0.15263557072430792, 'fraction_numerical': 0.0034129692832764505, 'mean_word_length': 3.9024163568773234, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 25, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2248190', 'n_tokens_mistral': 1979, 'n_tokens_neox': 1806, 'n_words': 387}