Skip to content

Commit

Permalink
Speedup 3 1 (#1438)
Browse files Browse the repository at this point in the history
* chore: use V4_COMPONENT to check whether an object is a component

* refactor: use getters for friendly classes

* fix: fixed `once` modifier for hook handlers

* fix: retrieving information about the observed field should be done in beforeDataCreate

* fix: don't create abstract smart components

* refactor: moved to composition API

* feat: added a method to determine which specific props have been added to the component

* chore: added an optimization that prevents watching a prop if it is not passed through the template

* feat: added support for `renderTracked` & fixed bugs

* chore: respect `functional: false` & `functionalWatching: false`

* feat: added the new prop `getPassedHandlers`

* fix: fixed the `emit` optimization

* chore: optimize event API

* refactor: extract @watch from factory

* refactor: extract @field/@System from factory

* refactor: extract @prop from factory

* refactor: extract @hook from factory

* refactor: extract @computed from factory

* refactor: optimized meta creation

* feat: added the new @DefaultValue decorator

* feat: added a transformer for registering default values on component properties

* refactor: improved DSL transformer

* feat: added a new decorator `method`

* feat: added a new decorator @derive for components

* chore: removed `addMethodsToMeta`

* chore: optimized meta inheritance

* feat: added support for `this` within default values

* refactor: generate getters/setters using transformers

* fix: fixed modifier initializing

* fix: provide parameters to setter

* fix: theme initialization

* refactor: removed `forceDefault` & `defaultProps`; now `getPassedProps` returns a dictionary; removed getPassedHandlers; fixed b-dynamic-page

* chore: provide `isProp` for vue sfc

* refactor: removed idle initializing

* feat: added a static property graph for use in synchronous code

* BREAKING_CHANGE: the passing of the component graph to the runtime has been removed

* chore: added support for the hint in dontWaitRemoteProviders

* chore: generate getters/setters dynamically

* BREAKING_CHANGE: removed legacy `inheritMods` implementation

* chore: new `sharedMods` API

* chore: added caching for shared-mods

* chore: improved sharedMods api

* fix: don't provide redundant mods

* chore: optimized method creation

* chore: implemented a smoother migration to `forceUpdate: false` props

* chore: methods for accessors, such as fooGetter/fooSetter, are used only with super, so it's not necessary to initialize them as a method on the component
---------

Co-authored-by: Artem Shinkaruk <46344555+shining-mind@users.noreply.github.com>
  • Loading branch information
kobezzza and shining-mind authored Nov 19, 2024
1 parent a567a71 commit c925ed3
Show file tree
Hide file tree
Showing 209 changed files with 4,942 additions and 3,234 deletions.
54 changes: 53 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,58 @@ Changelog
_Note: Gaps between patch versions are faulty, broken or test releases._

## v4.0.0-beta.?? (2024-??-??)

#### :boom: Breaking Change

* The `getPassedProps` method now returns a dictionary instead of a set `core/component`

* `iBlock`:
* The API for `InferComponentEvents` has been changed so that you no longer need to pass `this` as the first argument
* Component events without an `error` or `warning` status are logged only if the `verbose` prop is set
* The `strictEmit` method no longer performs normalization of the event name

* To automatically implement traits or characteristics for components,
the `derive` decorator from the `components/traits` module should now be used.

* Removed the constants `COMPONENTS` and `BLOCK_NAMES` `build/globals.webpack`
* Removed the `components` property `config`

#### :bug: Bug Fix

* Fixed an error in normalizing attribute and prop values in Snakeskin `build`

#### :rocket: New Feature

* `core/component/decorators`:
* Added new decorators, defaultValue and method, for the class-based DSL.
These decorators are used during code generation by the TS transformer DSL.

* The prop, field, and system decorators can now accept a default value for the field as a second argument.
This argument is used during code generation by the TS transformer DSL.

#### :house: Internal

* Various micro-optimizations

* `build`:
* Added a new TypeScript transformer to automatically apply decorators to parts of a component:
methods, accessors, field overrides, etc.
* Now, only the value from the decorator is used to get the default field value.
Default values specified in the class property will automatically be passed to the decorator by the transformer.

* The observation of accessor dependencies is now initialized only if the accessor has been used at least once `core/component/accessor`

* The decorators from `core/component/decorators` no longer use a single factory module.
Now, each decorator is implemented independently.

* `core/component/meta`:
* When inheriting metaobjects, prototype chains are now used instead of full copying.
This optimizes the process of creating metaobjects.
* Methods and accessors are now added to the metaobject via the `method` decorator instead of runtime reflection.
This decorator is automatically added during the build process.
* Optimized creation of metaobjects.

## v4.0.0-beta.153 (2024-11-15)

#### :house: Internal
Expand All @@ -30,7 +82,7 @@ Reloading now occurs for unloaded components or when explicitly specified with `
* Fix error "ctx.$vueWatch is not a function" caused by the incorrect fix in the v4.0.0-beta.146 `core/component/watch`
* Fixed endless attempts to load a component template that is not in use.
Added a 10-second limit for attempts to load the template. `core/component/decorators/component`
* Default `forceUpdate` param of a property no longer overrides its value inherited from parent component `core/component/decorators/prop`
* Default `forceUpdate` param of a property no longer overrides its value inherited from the parent component `core/component/decorators/prop`
* Fixed typo: `"prop"` -> `"props"` when inheriting parent properties `core/component/decorators/factory`

## v4.0.0-beta.152 (2024-11-11)
Expand Down
17 changes: 17 additions & 0 deletions build/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]
## v4.0.0-beta.?? (2024-??-??)

#### :boom: Breaking Change

* Removed the constants `COMPONENTS` and `BLOCK_NAMES` `globals.webpack`

#### :bug: Bug Fix

* Fixed an error in normalizing attribute and prop values in Snakeskin

#### :house: Internal

* Added a new TypeScript transformer to automatically apply decorators to parts of a component:
methods, accessors, field overrides, etc.
* Now, only the value from the decorator is used to get the default field value.
Default values specified in the class property will automatically be passed to the decorator by the transformer.

## v4.0.0-beta.138.dsl-speedup (2024-10-01)

#### :house: Internal
Expand Down
33 changes: 2 additions & 31 deletions build/globals.webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@

'use strict';

const
$C = require('collection.js'),
config = require('@config/config');
const config = require('@config/config');

const
{csp, build, webpack, i18n} = config,
{config: pzlr} = require('@pzlr/build-core'),
{collectI18NKeysets} = include('build/helpers'),
{getDSComponentMods, getThemes, getDS} = include('build/ds');

const
projectGraph = include('build/graph'),
s = JSON.stringify;
const s = JSON.stringify;

const
locales = i18n.supportedLocales(),
Expand Down Expand Up @@ -53,31 +49,6 @@ module.exports = {
LANG_KEYSETS: s(collectI18NKeysets(locales)),
LANG_PACKS: s(config.i18n.langPacksStore),

COMPONENTS: projectGraph.then(({components}) => {
if (Object.isMap(components)) {
return $C(components).to({}).reduce((res, el, key) => {
res[key] = {
parent: JSON.stringify(el.parent),
dependencies: JSON.stringify(el.dependencies)
};

return res;
});
}

return {};
}),

BLOCK_NAMES: runtime.blockNames ?
projectGraph.then(({components}) => {
if (Object.isMap(components)) {
const blockNames = Array.from(components.keys()).filter((el) => /^b-/.test(el));
return s(blockNames);
}
}) :

null,

THEME: s(config.theme.default()),
THEME_ATTRIBUTE: s(config.theme.attribute),
AVAILABLE_THEMES: pzlr.designSystem ?
Expand Down
9 changes: 3 additions & 6 deletions build/graph/component-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const
$C = require('collection.js'),
escaper = require('escaper');

const
fs = require('node:fs');
const fs = require('node:fs');

const {
componentRgxp,
Expand Down Expand Up @@ -67,8 +66,7 @@ Object.assign(componentParams, {
* Load component runtime parameters to a map
*/
componentFiles.forEach((el) => {
const
escapedFragments = [];
const escapedFragments = [];

const
file = escaper.replace(fs.readFileSync(el).toString(), escapedFragments),
Expand All @@ -94,8 +92,7 @@ componentFiles.forEach((el) => {
parent
};

const
obj = componentParams[component];
const obj = componentParams[component];

obj.deprecatedProps = p.deprecatedProps ?? {};

Expand Down
2 changes: 2 additions & 0 deletions build/graph/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ async function buildProjectGraph() {
if (build.buildGraphFromCache && fs.existsSync(graphCacheFile)) {
const cache = loadFromCache();
buildFinished();
module.exports.graph = await cache;
return cache;
}

Expand Down Expand Up @@ -168,6 +169,7 @@ async function buildProjectGraph() {
console.log('The project graph is initialized');
buildFinished();

module.exports.graph = res;
return res;

/**
Expand Down
63 changes: 45 additions & 18 deletions build/snakeskin/default-filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,20 @@ Snakeskin.importFilters({
});

function tagFilter({name: tag, attrs = {}}, _, rootTag, forceRenderAsVNode, tplName, cursor) {
Object.entries(attrs).forEach(([key, attr]) => {
if (isStaticV4Prop.test(key)) {
// Since HTML is not case-sensitive, the name can be written differently.
// We will explicitly normalize the name to the most popular format for HTML notation.
const tmp = key.dasherize(key.startsWith(':'));

if (tmp !== key) {
delete attrs[key];
attrs[tmp] = attr;
}
}
});

let componentName;

if (attrs[':instance-of']) {
attrs[':instanceOf'] = attrs[':instance-of'];
delete attrs[':instance-of'];
}

if (attrs[TYPE_OF]) {
componentName = attrs[TYPE_OF];

} else if (tag === 'component') {
if (attrs[':instance-of']) {
componentName = attrs[':instance-of'][0].camelize(false);
delete attrs[':instance-of'];
if (attrs[':instanceOf']) {
componentName = attrs[':instanceOf'][0].camelize(false);
delete attrs[':instanceOf'];

} else {
componentName = 'iBlock';
Expand All @@ -92,6 +84,41 @@ function tagFilter({name: tag, attrs = {}}, _, rootTag, forceRenderAsVNode, tplN

const component = componentParams[componentName];

Object.entries(attrs).forEach(([key, attr]) => {
if (isStaticV4Prop.test(key)) {
// Since HTML is not case-sensitive, the name can be written differently.
// We will explicitly normalize the name to the most popular format for HTML notation.
// For Vue component attributes such as `:` and `@`, we convert the prop to camelCase format.
let normalizedKey;

if (component) {
if (key.startsWith('@')) {
normalizedKey = key.camelize(false);

} else if (key.startsWith('v-on:')) {
normalizedKey = key.replace(/^v-on:([^.[]+)(.*)/, (_, event, rest) =>
`v-on:${event.camelize(false)}${rest}`);

} else if (key.startsWith(':') && !key.startsWith(':-') && !key.startsWith(':v-')) {
const camelizedKey = key.camelize(false);

if (component.props[camelizedKey.slice(1)]) {
normalizedKey = camelizedKey;
}
}
}

if (!normalizedKey) {
normalizedKey = key.dasherize();
}

if (normalizedKey !== key) {
delete attrs[key];
attrs[normalizedKey] = attr;
}
}
});

if (isSmartComponent(component)) {
attrs[SMART_PROPS] = component.functional;
}
Expand Down Expand Up @@ -177,8 +204,8 @@ function tagFilter({name: tag, attrs = {}}, _, rootTag, forceRenderAsVNode, tplN
attrs[':componentIdProp'] = [`componentId + ${JSON.stringify(id)}`];
}

if (component.inheritMods !== false && !attrs[':mods'] && !attrs[':modsProp']) {
attrs[':mods'] = ['provide.mods()'];
if (component.inheritMods !== false) {
attrs[':inheritMods'] = ['sharedMods != null'];
}

Object.entries(attrs).forEach(([name, val]) => {
Expand Down
6 changes: 6 additions & 0 deletions build/ts-transformers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]
## v4.0.0-beta.?? (2024-??-??)

#### :rocket: New Feature

* Added a new transformer `register-component-default-values`

## v3.23.5 (2022-07-12)

#### :rocket: New Feature
Expand Down
9 changes: 8 additions & 1 deletion build/ts-transformers/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# build/ts-transformers

This module provides a bunch of custom transformers for TypeScript.
This module provides a bunch of custom transformers for TypeScript/TSC.

## Default Transformers

* `set-component-layer` - this module provides a transformer that adds information to each component declaration about
the application layer in which the component is declared.

* `register-component-parts` - this module provides a transformer for registering parts of a class as parts of the associated component.
11 changes: 5 additions & 6 deletions build/ts-transformers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
'use strict';

const
setComponentLayer = include('build/ts-transformers/set-component-layer');
setComponentLayer = include('build/ts-transformers/set-component-layer'),
resisterComponentParts = include('build/ts-transformers/register-component-parts');

/**
* Returns a settings object for setting up TypeScript transformers
*
* @param {import('typescript').Program} program
* Returns a settings object for configuring TypeScript transformers
* @returns {object}
*/
module.exports = (program) => ({
before: [setComponentLayer(program)],
module.exports = () => ({
before: [setComponentLayer, resisterComponentParts],
after: {},
afterDeclarations: {}
});
16 changes: 16 additions & 0 deletions build/ts-transformers/register-component-parts/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Changelog
=========

> **Tags:**
> - :boom: [Breaking Change]
> - :rocket: [New Feature]
> - :bug: [Bug Fix]
> - :memo: [Documentation]
> - :house: [Internal]
> - :nail_care: [Polish]
## v4.0.0-beta.?? (2024-??-??)

#### :rocket: New Feature

* Initial release
Loading

0 comments on commit c925ed3

Please sign in to comment.