UNPKG

unplugin-typegpu

Version:

Build plugins for TypeGPU, enabling seamless JavaScript -> WGSL transpilation and improved debugging.

1 lines 9.59 kB
{"version":3,"sources":["/Users/iwo/Projects/wigsill/packages/unplugin-typegpu/dist/chunk-LJXNN2RM.cjs","../src/index.ts","../src/rollup-impl.ts"],"names":["containsUseGpuDirective","node","statement","useGpuDirective","removeUseGpuDirective","cloned","assignMetadata","magicString","metadata","wrapInAutoName","name","rollUpImpl","rawOptions","options","defu","defaultOptions","earlyPruneRegex","code","id","ctx","ast","cause"],"mappings":"AAAA,iOAAoF,oCCArD,wECCd,kDACiC,6CAclB,kDACJ,kCACG,SAQfA,CAAAA,CAAwBC,CAAAA,CAA6B,CACnE,EAAA,CAAIA,CAAAA,CAAK,IAAA,CAAK,IAAA,GAAS,gBAAA,CAAA,CACrB,GAAA,CAAA,IAAWC,EAAAA,GAAaD,CAAAA,CAAK,IAAA,CAAK,IAAA,CAChC,EAAA,CACEC,CAAAA,CAAU,IAAA,GAAS,qBAAA,EACnBA,CAAAA,CAAU,SAAA,GAAcC,mBAAAA,CAExB,MAAO,CAAA,CAAA,CAIb,MAAO,CAAA,CACT,CAEO,SAASC,CAAAA,CAAsBH,CAAAA,CAAoB,CACxD,IAAMI,CAAAA,CAAS,eAAA,CAAgBJ,CAAI,CAAA,CAEnC,OAAII,CAAAA,CAAO,IAAA,CAAK,IAAA,GAAS,gBAAA,EAAA,CACvBA,CAAAA,CAAO,IAAA,CAAK,IAAA,CAAOA,CAAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CACjCH,CAAAA,EACC,CAAA,CACEA,CAAAA,CAAU,IAAA,GAAS,qBAAA,EACnBA,CAAAA,CAAU,SAAA,GAAcC,mBAAAA,CAE9B,CAAA,CAAA,CAGKE,CACT,CAEO,SAASC,CAAAA,CACdC,CAAAA,CACAN,CAAAA,CACAO,CAAAA,CACA,CACAD,CAAAA,CAAY,WAAA,CACVN,CAAAA,CAAK,KAAA,CACL,oEACF,CAAA,CAAE,WAAA,CACAA,CAAAA,CAAK,GAAA,CACL,CAAA,GAAA,EAAMO,CAAQ,CAAA,cAAA,CAChB,CACF,CAEO,SAASC,CAAAA,CACdF,CAAAA,CACAN,CAAAA,CACAS,CAAAA,CACA,CACAH,CAAAA,CACG,WAAA,CACCN,CAAAA,CAAK,KAAA,CACL,iDACF,CAAA,CACC,WAAA,CAAYA,CAAAA,CAAK,GAAA,CAAK,CAAA,GAAA,EAAMS,CAAI,CAAA,GAAA,CAAK,CAC1C,CAEO,IAAMC,CAAAA,CAAcC,CAAAA,EAAwB,CACjD,IAAMC,CAAAA,CAAUC,4BAAAA,CAAKF,CAAYG,mBAAc,CAAA,CAE/C,MAAO,CACL,IAAA,CAAM,kBAAA,CACN,OAAA,CAASF,CAAAA,CAAQ,OAAA,CACjB,SAAA,CAAW,CACT,MAAA,CAAQA,CAAAA,CAAQ,YAAA,CACZ,CACA,EAAA,CAAIA,CAAAA,CACJ,IAAA,CAAMG,mBACR,CAAA,CACE,CACA,EAAA,CAAIH,CACN,CAAA,CACF,OAAA,CAEEI,CAAAA,CACAC,CAAAA,CACA,CACA,IAAMC,CAAAA,CAAe,CACnB,WAAA,CAAa,IAAI,GAAA,CACfN,CAAAA,CAAQ,cAAA,CAAiB,CAACA,CAAAA,CAAQ,cAAc,CAAA,CAAI,CAAC,CACvD,CAAA,CACA,MAAA,CAAQK,CAAAA,CACR,iBAAA,CAAmBL,CAAAA,CAAQ,iBAC7B,CAAA,CAEIO,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAM,IAAA,CAAK,KAAA,CAAMH,CAAAA,CAAM,CACrB,IAAA,CAAM,IAAA,CACN,0BAAA,CAA4B,CAAA,CAC9B,CAAC,CACH,CAAA,KAAA,CAASI,CAAAA,CAAO,CACd,OAAA,CAAQ,IAAA,CACN,CAAA,mCAAA,EAAsCH,CAAE,CAAA,SAAA,EACtC,OAAOG,CAAAA,EAAU,QAAA,EAAYA,CAAAA,EAAS,SAAA,GAAaA,CAAAA,CAC/CA,CAAAA,CAAM,OAAA,CACNA,CACN,CAAA,CAAA;AA0EqB,iBAAA;AACqB,oBAAA;AACS,mBAAA;AAKrD,iCAAA;AD7LwB,aAAA","file":"/Users/iwo/Projects/wigsill/packages/unplugin-typegpu/dist/chunk-LJXNN2RM.cjs","sourcesContent":[null,"import { createUnplugin } from 'unplugin';\nimport { rollUpImpl } from './rollup-impl.ts';\n\nconst typegpu = createUnplugin(rollUpImpl);\n\nexport type { Options } from './common.ts';\n\nexport default typegpu;\n\nexport const vitePlugin = typegpu.vite;\nexport const rollupPlugin = typegpu.rollup;\nexport const rolldownPlugin = typegpu.rolldown;\nexport const webpackPlugin = typegpu.webpack;\nexport const rspackPlugin = typegpu.rspack;\nexport const esbuildPlugin = typegpu.esbuild;\nexport const farmPlugin = typegpu.farm;\n\nexport { default as babelPlugin } from './babel.ts';\nexport { default as bunPlugin } from './bun.ts';\nexport { default as rolldownBrowserPlugin } from './rolldown-browser.ts';\n","import type * as acorn from 'acorn';\nimport defu from 'defu';\nimport { generateTransform, MagicStringAST } from 'magic-string-ast';\nimport {\n type Context,\n defaultOptions,\n earlyPruneRegex,\n embedJSON,\n gatherTgpuAliases,\n getFunctionName,\n isShellImplementationCall,\n type Options,\n performExpressionNaming,\n useGpuDirective,\n} from './common.ts';\nimport type { UnpluginBuildContext, UnpluginContext } from 'unplugin';\nimport { type Node, walk } from 'estree-walker';\nimport { transpileFn } from 'tinyest-for-wgsl';\nimport { FORMAT_VERSION } from 'tinyest';\n\nexport type FunctionNode =\n | acorn.FunctionDeclaration\n | acorn.AnonymousFunctionDeclaration\n | acorn.FunctionExpression\n | acorn.ArrowFunctionExpression;\n\nexport function containsUseGpuDirective(node: FunctionNode): boolean {\n if (node.body.type === 'BlockStatement') {\n for (const statement of node.body.body) {\n if (\n statement.type === 'ExpressionStatement' &&\n statement.directive === useGpuDirective\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport function removeUseGpuDirective(node: FunctionNode) {\n const cloned = structuredClone(node);\n\n if (cloned.body.type === 'BlockStatement') {\n cloned.body.body = cloned.body.body.filter(\n (statement) =>\n !(\n statement.type === 'ExpressionStatement' &&\n statement.directive === useGpuDirective\n ),\n );\n }\n\n return cloned;\n}\n\nexport function assignMetadata(\n magicString: MagicStringAST,\n node: acorn.AnyNode,\n metadata: string,\n) {\n magicString.prependLeft(\n node.start,\n '(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (',\n ).appendRight(\n node.end,\n `), ${metadata}) && $.f)({}))`,\n );\n}\n\nexport function wrapInAutoName(\n magicString: MagicStringAST,\n node: acorn.Node,\n name: string,\n) {\n magicString\n .prependLeft(\n node.start,\n '((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(',\n )\n .appendRight(node.end, `, \"${name}\"))`);\n}\n\nexport const rollUpImpl = (rawOptions: Options) => {\n const options = defu(rawOptions, defaultOptions);\n\n return {\n name: 'unplugin-typegpu' as const,\n enforce: options.enforce,\n transform: {\n filter: options.earlyPruning\n ? {\n id: options,\n code: earlyPruneRegex,\n }\n : {\n id: options,\n },\n handler(\n this: UnpluginBuildContext & UnpluginContext,\n code: string,\n id: string,\n ) {\n const ctx: Context = {\n tgpuAliases: new Set<string>(\n options.forceTgpuAlias ? [options.forceTgpuAlias] : [],\n ),\n fileId: id,\n autoNamingEnabled: options.autoNamingEnabled,\n };\n\n let ast: Node;\n try {\n ast = this.parse(code, {\n lang: 'ts',\n allowReturnOutsideFunction: true,\n }) as Node;\n } catch (cause) {\n console.warn(\n `[unplugin-typegpu] Failed to parse ${id}. Cause: ${\n typeof cause === 'object' && cause && 'message' in cause\n ? cause.message\n : cause\n }`,\n );\n return undefined;\n }\n\n const tgslFunctionDefs: {\n def: FunctionNode;\n name?: string | undefined;\n }[] = [];\n\n const magicString = new MagicStringAST(code);\n\n walk(ast, {\n enter(_node, _parent, prop, index) {\n const node = _node as acorn.AnyNode;\n const parent = _parent as acorn.AnyNode;\n\n performExpressionNaming(ctx, node, (node, name) => {\n wrapInAutoName(magicString, node, name);\n });\n\n if (node.type === 'ImportDeclaration') {\n gatherTgpuAliases(node, ctx);\n }\n\n if (node.type === 'CallExpression') {\n if (isShellImplementationCall(node, ctx)) {\n const implementation = node.arguments[0];\n\n if (\n implementation &&\n (implementation.type === 'FunctionExpression' ||\n implementation.type === 'ArrowFunctionExpression')\n ) {\n tgslFunctionDefs.push({\n def: removeUseGpuDirective(implementation),\n });\n this.skip();\n }\n }\n }\n\n if (\n node.type === 'ArrowFunctionExpression' ||\n node.type === 'FunctionExpression' ||\n node.type === 'FunctionDeclaration'\n ) {\n if (containsUseGpuDirective(node)) {\n tgslFunctionDefs.push({\n def: removeUseGpuDirective(node),\n name: getFunctionName(node, parent),\n });\n this.skip();\n }\n }\n },\n });\n\n for (const { def, name } of tgslFunctionDefs) {\n const { params, body, externalNames } = transpileFn(def);\n const isFunctionStatement = def.type === 'FunctionDeclaration';\n\n if (\n isFunctionStatement &&\n name &&\n code.slice(0, def.start)\n .search(new RegExp(`(?<![\\\\w_.])${name}(?![\\\\w_])`)) !== -1\n ) {\n console.warn(\n `File ${id}: function \"${name}\" might have been referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.`,\n );\n }\n\n const metadata = `{\n v: ${FORMAT_VERSION},\n name: ${name ? `\"${name}\"` : 'undefined'},\n ast: ${embedJSON({ params, body, externalNames })},\n externals: () => ({${\n externalNames.map((e) => e === 'this' ? '\"this\": this' : e).join(\n ', ',\n )\n }}),\n }`;\n\n assignMetadata(magicString, def, metadata);\n\n if (isFunctionStatement && name) {\n magicString.prependLeft(def.start, `const ${name} = `);\n }\n }\n\n return generateTransform(magicString, id);\n },\n },\n };\n};\n"]}