Skip to content

Commit

Permalink
feat(unplugin): add configResolved/onSourceFile hooks + provide Panda…
Browse files Browse the repository at this point in the history
…Context + allow async
  • Loading branch information
astahmer committed Apr 8, 2024
1 parent e612bed commit dfd87f9
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
10 changes: 10 additions & 0 deletions .changeset/silent-birds-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@pandabox/unplugin': patch
---

- Add `onSourceFile` hook + provide PandaContext in hooks
- Add `contextCreated` hook
- Await hooks to allow for asynchronous operations

Fix case where if the `transform` hook returns a different code than the original code but `optimizeJs` was disabled,
the transformed code would not be returned
2 changes: 1 addition & 1 deletion packages/unplugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { unplugin } from '@pandabox/unplugin'

export default defineConfig({
plugins: [
unplugin({
unplugin.vite({
/* options */
}),
],
Expand Down
33 changes: 28 additions & 5 deletions packages/unplugin/src/plugin/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { createFilter } from '@rollup/pluginutils'
import { type TransformResult, type UnpluginFactory } from 'unplugin'
import type { HmrContext, Plugin } from 'vite'
import fs from 'node:fs/promises'
import { codegen } from '@pandacss/node'
import { codegen, PandaContext } from '@pandacss/node'

import { createContext, type PandaPluginContext } from '../plugin/create-context'
import { ensureAbsolute } from './ensure-absolute'
import { tranformPanda, type TransformOptions } from './transform'
import path from 'node:path'
import { addCompoundVariantCss, inlineCva } from './cva-fns'
import type { SourceFile } from 'ts-morph'

const createVirtualModuleId = (id: string) => {
const base = `virtual:panda${id}`
Expand Down Expand Up @@ -52,11 +53,26 @@ export interface PandaPluginOptions extends Partial<PandaPluginHooks>, Pick<Tran
optimizeCss?: boolean
}

interface SourceFileHookArgs {
sourceFile: SourceFile
context: PandaContext
}

type MaybePromise<T> = T | Promise<T>
export interface PandaPluginHooks {
contextCreated: (args: { context: PandaContext }) => MaybePromise<void>
/**
* A transform callback similar to the `transform` hook of `vite` that allows you to modify the source code before it's parsed.
* Called before the source file is parsed by ts-morph and Panda.
*/
transform: (
args: Omit<ParserResultBeforeHookArgs, 'configure'> & Pick<SourceFileHookArgs, 'context'>,
) => MaybePromise<TransformResult | void>
/**
* A callback that allows you to modify or use the ts-morph sourceFile before it's parsed by Panda.
* Called after ts-morph has parsed the source file, but before it was parsed by Panda.
*/
transform: (args: Omit<ParserResultBeforeHookArgs, 'configure'>) => TransformResult | void
onSourceFile: (args: SourceFileHookArgs) => MaybePromise<void>
}

export const unpluginFactory: UnpluginFactory<PandaPluginOptions | undefined> = (rawOptions) => {
Expand All @@ -78,9 +94,12 @@ export const unpluginFactory: UnpluginFactory<PandaPluginOptions | undefined> =

// console.log('loadConfig', options)
// @ts-expect-error
initPromise = loadConfig({ cwd: options.cwd, file: options.configPath }).then((conf: LoadConfigResult) => {
initPromise = loadConfig({ cwd: options.cwd, file: options.configPath }).then(async (conf: LoadConfigResult) => {
conf.config.cwd = options.cwd
_ctx = createContext({ root: options.cwd, conf })
if (options.contextCreated) {
await options.contextCreated({ context: _ctx.panda })
}
})

return initPromise
Expand Down Expand Up @@ -130,7 +149,7 @@ export const unpluginFactory: UnpluginFactory<PandaPluginOptions | undefined> =
let transformResult: TransformResult = { code, map: undefined }

if (options.transform) {
const result = options.transform({ filePath: id, content: code }) || code
const result = (await options.transform({ filePath: id, content: code, context: ctx.panda })) || code
if (typeof result === 'string') {
transformResult.code = result
} else if (result) {
Expand All @@ -139,6 +158,10 @@ export const unpluginFactory: UnpluginFactory<PandaPluginOptions | undefined> =
}

const sourceFile = panda.project.addSourceFile(id, transformResult.code)
if (options.onSourceFile) {
await options.onSourceFile({ sourceFile, context: ctx.panda })
}

const parserResult = panda.project.parseSourceFile(id)
if (!parserResult) return null

Expand All @@ -147,7 +170,7 @@ export const unpluginFactory: UnpluginFactory<PandaPluginOptions | undefined> =
}

if (!options.optimizeJs) {
return null
return transformResult.code !== code ? transformResult : null
}

const result = tranformPanda(ctx, {
Expand Down

0 comments on commit dfd87f9

Please sign in to comment.