Skip to content

Commit

Permalink
feat: added $map suffix for object arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobrosenberg committed Oct 17, 2020
1 parent 72cc945 commit 179fa1a
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 88 deletions.
2 changes: 1 addition & 1 deletion examples/basic/_roxi/roxi.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ plugins:
- spassr:
port: 3400
ssr: true
- postcss:
- mdsvex:
- postcss:
- vite:
- debugger:
12 changes: 7 additions & 5 deletions lib/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/// <reference path="../typedef.js" />


/** @ts-ignore */
const esmRequire = require("esm")(module, {}/*, options*/)
const { deepAssign, log } = require('./utils')
const { deepAssign, log, keysAsFunctionsRecursive } = require('./utils')


/** @type {AppEvent[]} */
Expand Down Expand Up @@ -42,20 +39,25 @@ const App = class {
async run(events = this.events) {
try {
for (const event of events) {
console.log('event', event)
this.state.event = event
await runPlugins(event, this)
}
} catch (err) { this.errorHandler(err) }
}
}

//todo move this somewhere else?
const objToArray = {
hooks: [{ event: 'bundle', action: app => keysAsFunctionsRecursive(app) }]
}

/**
* @param {AppEvent} event
* @param {RoxiApp} app
*/
async function runPlugins(event, app) {
const plugins = [...app.config.roxi.plugins]
const plugins = [objToArray, ...app.config.roxi.plugins]
for (const plugin of plugins) {
const hooks = plugin.hooks.filter(hookCondition(app, plugin.params, { event }))
for (const hook of hooks)
Expand Down
27 changes: 11 additions & 16 deletions lib/plugins/mdsvex/index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
/// <reference path="../../../typedef.js" />

import { mdsvex } from 'mdsvex'
const extension = ['.md', '.svx', '.svelte']

/** @type {RoxiPlugin} */
module.exports.default = {
name: 'mdsvex',
hooks: [
{
event: 'start',
action: app => app.config.mdsvex = {}, //provide an mdsvex object for developers to modify
},
{
event: 'before:bundle',
action: (app, params) => {
const extension = params.extension || .md

//provide an mdsvex object for developers to modify
const conf = { extension, ...params }


app.merge({
config: {
mdsvex: conf,
svelte: {
preprocess: [
mdsvex({
extension: '.md',
...app.config.mdsvex,
...params
})
],
extensions: params.extension
|| app.config.mdsvex.extension
|| extension
preprocess: { mdsvex: conf },
preprocess$map: { mdsvex },
extensions: [extension]
}
}
})
}
}
},
]
}
49 changes: 20 additions & 29 deletions lib/plugins/postcss/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,34 @@ export default {
event: 'start',
action: async (app, params) => {
const postcssImport = (await import('postcss-import')).default
app.merge({
config: {
postcss: {
pluginsMap: { postcssImport },
plugins: {
postcssImport: {}
}
}
}
})
}
},
{
event: 'before:bundle',
action: async (app, params) => {
const { keysAsFunctions } = (await import('../../utils'))
const { plugins, pluginsMap } = app.config.postcss
const postcss = (await import('rollup-plugin-postcss')).default
const autoPreprocess = (await import('svelte-preprocess')).default
app.config.postcss.plugins = await keysAsFunctions(plugins, pluginsMap)
delete app.config.postcss.pluginsMap

const postcssConfig = {
plugins$map: { postcssImport },
plugins: {
postcssImport: {},
}
}

app.merge({
config: {
// add postcss to the config
postcss: postcssConfig,

// rollup needs access
rollup: {
pluginsMap: { postcss },
plugins: {
postcss: app.config.postcss
}
plugins: { postcss: postcssConfig },
plugins$map: { postcss }
},

// and so does svelte preprocess
svelte: {
preprocess: [
autoPreprocess({
postcss: app.config.postcss,
preprocess: {
autoPreprocess: {
_postcss: postcssConfig,
defaults: { style: 'postcss' }
})
]
}
}
}
}
})
Expand Down
17 changes: 6 additions & 11 deletions lib/plugins/preprocess/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import autoPreprocess from 'svelte-preprocess'

export default {
hooks: [
{
condition: 'start',
action: app => app.config.autoPreprocess = {}
},
{
condition: 'before:bundle',
action: async (app, params) => {
const autoPreprocess = (await import('svelte-preprocess')).default

event: 'start',
action: app => {
app.merge({
config: {
svelte: {
preprocess: [
autoPreprocess(app.config.autoPreprocess)
]
preprocess: { autoPreprocess: {} },
preprocess$map: { autoPreprocess }
}
}
})
Expand Down
9 changes: 0 additions & 9 deletions lib/plugins/rollup/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const rollup = require('rollup')
import rollupTemplate from './rollup.template'
import rollupCompile from './rollup.compile'

export default {
name: 'rollup',
Expand All @@ -9,14 +8,6 @@ export default {
event: 'start',
action: rollupTemplate
},
{
event: 'bundle',
condition: app =>
app.state.production
|| app.config.rollup.compileConfig
|| app.config.rollup.writeConfig,
action: rollupCompile
},
{
event: 'bundle',
condition: app => app.state.production || app.config.rollup.writeConfig,
Expand Down
11 changes: 0 additions & 11 deletions lib/plugins/rollup/rollup.compile.js

This file was deleted.

2 changes: 1 addition & 1 deletion lib/plugins/rollup/rollup.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module.exports = function rollup(app, params) {
sourcemap: true,
format: 'esm', dir: buildDir
},
pluginsMap: { svelte, resolve, commonjs, terser, hmr, livereload },
plugins$map: { svelte, resolve, commonjs, terser, hmr, livereload },
plugins: {
terser: production && {},
svelte: app.config.svelte,
Expand Down
12 changes: 9 additions & 3 deletions lib/plugins/svelte/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ export default {
{
event: 'start',
action: async (app, params, ctx) => {
app.config.svelte = {
extensions: []
}
app.merge({
config: {
svelte: {
extensions: ['.svelte'],
preprocess: {},
preprocess$map: {}
}
}
})
}
}
]
Expand Down
47 changes: 45 additions & 2 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,47 @@ function deepAssign(target, ...sources) {
return target
}

async function keysAsFunctions(obj, map) {
async function keysAsFunctionsRecursive(obj, suffix = '$map') {
const maps = []

// process all descendants' maps first
const children = Object.entries(obj).map(([key, value]) => {
if (isObject(value)) {
if (key.endsWith(suffix))
maps.push({ key, value })
else
return keysAsFunctionsRecursive(value, suffix)
}
})
await Promise.all(children)

// process own maps
const ownMaps = await Promise.all(maps.map(async ({ key, value }) => {
delete obj[key]
key = key.substr(0, key.length - suffix.length)
const result = await keysAsFunctions(obj[key], value, key)
return {
key,
result
}
}))
ownMaps.forEach(thing => obj[thing.key] = thing.result)

return obj
}

/**
* converts objects to arrays
* each field value is parsed through a function from the map which corresponds to the field's key
* map = { aPlugin: val => val + 'bar' }
* obj = { aPlugin: 'foo', _n: 123 }
* keysAsFunctions(obj, map) // ['foobar', 123]
* @param {object} obj
* @param {Object.<string, function>} map
*/
async function keysAsFunctions(obj, map, name) {
if (!isObject(obj))
throw new Error(`expected an object for "${name}", but got ${JSON.stringify(obj, null, 2)}`)
const { log } = require('./log')
const promises = Object.entries(obj).map(([key, value]) => {
const isFn = !key.startsWith('_')
Expand All @@ -51,7 +91,9 @@ async function keysAsFunctions(obj, map) {

if (!fn && isFn) log.info(
`there's no map method named ${key}. Available methods: ${Object.keys(map)}.` +
`\nRenaming to "_${key}" will hide this message.`
`\nRenaming to "_${key}" will hide this message.` +
`\nvalue: ${JSON.stringify(value, null, 2)}` +
`\nobj: ${JSON.stringify(obj, null, 2)}`
)
return fn && value ? fn(value) : value
})
Expand All @@ -63,5 +105,6 @@ module.exports = {
isObject,
deepAssign,
keysAsFunctions,
keysAsFunctionsRecursive,
...require('./log')
}
60 changes: 60 additions & 0 deletions lib/utils/tests/keysAsFunctionsRecursive.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const { keysAsFunctionsRecursive } = require("..");

const fn = async val => ({ ...val, touched: true })
const getBaseObj = () => ({
aPlugin: {
string: 'abc',
number: 123,
obj: { foo: 'bar' },
target$map: { fn },
target: {
fn: { isTarget: true, touched: false }
}
}
})

it('converts objects to arrays', async () => {
const config = getBaseObj()
const result = await keysAsFunctionsRecursive(config)

expect(result).toEqual({
aPlugin: {
string: 'abc',
number: 123,
obj: { foo: 'bar' },
target: [
{
"isTarget": true,
"touched": true,
},
]
}
})
})

it('processes children first', async () => {
const config = getBaseObj()
config.aPlugin.target.fn.child = { fn: { isTarget: true, touched: false } }
config.aPlugin.target.fn.child$map = { fn }


const result = await keysAsFunctionsRecursive(config)

expect(result).toEqual({
aPlugin: {
string: 'abc',
number: 123,
obj: { foo: 'bar' },
target: [
{
isTarget: true,
touched: true,
child: [{
isTarget: true,
touched: true,
}]
},
]
}
})
})

0 comments on commit 179fa1a

Please sign in to comment.