-
Notifications
You must be signed in to change notification settings - Fork 3
perf(gulp-bem-src): cache level introspection #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| module.exports = require('./introspect-levels'); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
| const { Writable } = require('stream'); | ||
|
|
||
| const walk = require('@bem/sdk.walk'); | ||
| const pify = require('pify'); | ||
|
|
||
| /** | ||
| * @param {string} levelPath | ||
| * @param {*} bemConfig | ||
| */ | ||
| module.exports = async (levelPath, bemConfig) => { | ||
| const levelMap = await Promise.resolve(bemConfig.levelMap ? bemConfig.levelMap() : {}); | ||
|
|
||
| return new Promise((resolve, reject) => { | ||
| const entityMap = new Map(); | ||
|
|
||
| walk([levelPath], levelMap) | ||
| .on('error', reject) | ||
| .pipe(new Writable({ | ||
| objectMode: true, | ||
| write(file, encoding, callback) { | ||
| tryCatch(async () => { | ||
| const id = file.entity.id; | ||
| const stats = await pify(fs.stat)(file.path); | ||
|
|
||
| file.stats = stats; | ||
|
|
||
| const entityFiles = entityMap.has(id) ? entityMap.get(id) : entityMap.set(id, new Set()).get(id); | ||
| entityFiles.add(file); | ||
|
|
||
| callback(); | ||
| }, callback); | ||
| } | ||
| })) | ||
| .on('error', reject) | ||
| .on('finish', () => resolve(entityMap)); | ||
| }); | ||
| }; | ||
|
|
||
| // try-catch optimization | ||
| function tryCatch(tryFn, catchFn) { | ||
| try { | ||
| tryFn(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets test, I think it may not catch async functions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It wont' catch throws in callbacks, but will catch |
||
| } catch (err) { | ||
| catchFn(err); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
| const { Writable } = require('stream'); | ||
|
|
||
| const introspectLevel = require('./introspect-level'); | ||
| const Introspection = require('./introspection'); | ||
|
|
||
| const levelCache = {}; | ||
|
|
||
| /** | ||
| * @param {string[]} levelPaths | ||
| * @param {*} bemConfig | ||
| * @returns {Introspection} | ||
| */ | ||
| module.exports = async (levelPaths, bemConfig, { cache=false } = {}) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JSDoc doesn't has options and cache description. |
||
| const levelIntrospections = await Promise.all(levelPaths.map(levelPath => { | ||
| if (cache && levelCache[levelPath]) { | ||
| return levelCache[levelPath]; | ||
| } | ||
|
|
||
| const introspect = introspectLevel(levelPath, bemConfig); | ||
|
|
||
| levelCache[levelPath] = introspect; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets invert if. |
||
|
|
||
| return introspect; | ||
| })); | ||
|
|
||
| return new Introspection(levelPaths, levelIntrospections); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| 'use strict'; | ||
|
|
||
| /** | ||
| * Contains info about files in levels for bundle. | ||
| */ | ||
| module.exports = class Introspection { | ||
| constructor(levelPaths, introspections) { | ||
| this._levelPaths = levelPaths; | ||
| this._introspections = introspections; | ||
| } | ||
| /** | ||
| * Returns all level paths. | ||
| * | ||
| * @returns {String[]} | ||
| */ | ||
| levels() { | ||
| return this._levelPaths; | ||
| } | ||
| /** | ||
| * Returns all files. | ||
| * | ||
| * @returns {Iterator} | ||
| */ | ||
| *files() { | ||
| for (const introspection of this._introspections) { | ||
| for (const files of introspection.values()) { | ||
| yield* files; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Returns info about files of specified entity. | ||
| * | ||
| * @param {Object} entity | ||
| * @returns {Iterator} | ||
| */ | ||
| *entityFiles(entity) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. filesByEntity |
||
| for (const introspection of this._introspections) { | ||
| yield* introspection.get(entity.id); | ||
| } | ||
| } | ||
| /** | ||
| * Returns info about files with specified tech. | ||
| * | ||
| * @param {string} tech | ||
| * @returns {Iterator} | ||
| */ | ||
| *techFiles(tech) { | ||
| for (const introspection of this._introspections) { | ||
| for (const files of introspection.values()) { | ||
| for (const file of files) { | ||
| if (file.tech === tech) { | ||
| yield file; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,11 +25,12 @@ | |
| "@bem/sdk.walk": "0.2.5", | ||
| "bubble-stream-error": "1.0.0", | ||
| "gulp-read": "0.0.1", | ||
| "stream-to-array": "2.3.0", | ||
| "pify": "^3.0.0", | ||
| "vinyl": "2.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@bem/sdk.naming.entity.parse": "^0.2.4", | ||
| "@bem/sdk.naming.presets": "^0.0.7" | ||
| "@bem/sdk.naming.presets": "^0.0.7", | ||
| "stream-to-array": "2.3.0" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. крышечки долой, гринкипер в помощь |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ const path = require('path'); | |
| const parseEntity = require('@bem/sdk.naming.entity.parse')(require('@bem/sdk.naming.presets/origin')); | ||
| const { assert } = require('chai'); | ||
| const lib = require('..'); | ||
| const Introspection = require('../lib/introspect-levels/introspection'); | ||
|
|
||
| describe('harvest', () => { | ||
| it('should filter introspection by entity and tech', () => { | ||
|
|
@@ -96,7 +97,17 @@ describe('harvest', () => { | |
| // {entity: {block: 'button'}, tech: 'css'} | ||
|
|
||
| function checkHarvest(opts) { | ||
| opts.introspection = opts.files.map(makeFileEntity); | ||
| const files = opts.files.map(makeFileEntity); | ||
| const entityMap = new Map(); | ||
|
|
||
| for (const file of files) { | ||
| const id = file.entity.id; | ||
| const entityFiles = entityMap.has(id) ? entityMap.get(id) : entityMap.set(id, new Set()).get(id); | ||
|
|
||
| entityFiles.add(file); | ||
| } | ||
|
|
||
| opts.introspection = new Introspection(['<level-path>'], [entityMap]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is |
||
| opts.result = opts.result.map(makeFileEntity); | ||
| opts.decl = opts.decl.map(makeEntity); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on → once?