pattycake

repository·main·Indexed 21 days ago

https://github.com/aidenybai/pattycake

A zero-runtime optimizing compiler for ts-pattern version 0.0.2 that converts pattern matching expressions into optimized JavaScript if-statement chains. It provides plugins for Vite, Webpack, Rollup, Rspack, Esbuild, Babel, and Next.js to eliminate runtime overhead and improve performance.

Tokens
1.7K
Snippets
10
Records
11
Agent score
75%

What's inside pattycake

  1. How pattycake optimizes ts-pattern

    main

    Pattycake is a zero-runtime optimizing compiler for ts-pattern. It takes expressive match() expressions and compiles them into optimized chains of if statements. This eliminates the runtime overhead of ts-pattern, typically resulting in a 10-12x performance improvement.

    Key Optimizations

    • If-statement chains: Converts complex pattern matching logic into direct conditional checks.
    • Inlining handlers: When possible, pattycake inlines small anonymous or arrow function handlers directly into the generated code to avoid function call overhead and reduce the creation of function objects at runtime.
    • IIFEs: Uses code blocks (similar to IIFEs) to maintain semantics while optimizing execution flow.

    Fallback Behavior

    If pattycake encounters a match() expression that it cannot currently optimize (due to unsupported ts-pattern features), it will automatically fallback to using the standard ts-pattern runtime.

    // Original ts-pattern code
    let html = match(result)
      .with(
        { type: 'error', error: { foo: [1, 2] }, nice: '' },
        () => '<p>Oups! An error occured</p>',
      )
      .with({ type: 'ok', data: { type: 'text' } }, function (data) {
        return '<p>420</p>';
      })
      .with(
        { type: 'ok', data: { type: 'img', src: 'hi' } },
        (src) => `<img src=${src} />`,
      )
      .otherwise(() => 'idk bro');
    
    // pattycake compiles this into an optimized if/else chain with direct property checks
  2. Configure pattycake for Next.js

    main

    To use pattycake in a Next.js project, wrap your configuration using the pattycake.next() method in your next.config.js file.

    // next.config.js
    const pattycake = require('pattycake');
    
    module.exports = pattycake.next({
      // your next.js config
    });
  3. Configure pattycake for Create React App (Webpack)

    main

    For Create React App projects, add pattycake.webpack() to the webpack.plugins.add array in your configuration object.

    const pattycake = require('pattycake');
    
    module.exports = {
      webpack: {
        plugins: {
          add: [pattycake.webpack()],
        },
      },
    };
  4. Configure pattycake for Vite

    main

    To use pattycake in a Vite project, add pattycake.vite() to the plugins array in your vite.config.js file.

    // vite.config.js
    import { defineConfig } from 'vite';
    import pattycake from 'pattycake';
    
    export default defineConfig({
      plugins: [pattycake.vite()],
    });
  5. Configure pattycake for Webpack

    main

    To use pattycake in a standard Webpack configuration, add pattycake.webpack() to the plugins array.

    const pattycake = require('pattycake');
    
    module.exports = {
      plugins: [pattycake.webpack()],
    };
  6. Supported ts-pattern features in pattycake

    main

    Pattycake aims for feature parity with ts-pattern. The following features are currently supported:

    • Literal patterns: string, number, boolean, bigint, undefined, null, NaN
    • Object patterns
    • Array/tuple patterns
    • Wildcards: P._, P.string, P.number
    • P.select

    Note: Features like .when(), P.not, P.array, P.map, and P.set are currently in the roadmap and may trigger the ts-pattern fallback.

  7. Use pattycake with unplugin

    main

    You can integrate pattycake into build tools that support unplugin (such as Vite, Rollup, Webpack, or Esbuild) using the unplugin export. The plugin is configured to run in the pre phase and automatically targets .js, .jsx, .ts, and .tsx files. It internally uses Babel with JSX and TypeScript syntax support to perform transformations.

    import { unplugin } from 'pattycake/plugin';
    
    // Example usage in a build tool configuration
    export default unplugin({
      // pass pattycake options here
    });
  8. Integrate pattycake with Next.js

    main

    To use pattycake in a Next.js project, use the next function to wrap your existing next.config.js. The next function takes your current configuration and an Options object. It automatically injects the pattycake Webpack plugin into your configuration's plugin array using unshift to ensure it runs early.

    const { next } = require('pattycake');
    
    module.exports = next({
      // your existing nextConfig
      reactStrictMode: true,
    }, {
      // pattycake options
    });
  9. Use pattycake plugins for Vite, Webpack, Rollup, Rspack, Esbuild, and Babel

    main

    Pattycake provides dedicated entry points for major build tools via unplugin. You can import the specific plugin for your bundler directly from the package root:

    • vite: Vite plugin
    • webpack: Webpack plugin
    • rollup: Rollup plugin
    • rspack: Rspack plugin
    • esbuild: Esbuild plugin
    • babel: Babel plugin
    import { vite, webpack, rollup, rspack, esbuild, babel } from 'pattycake';
    
    // Example usage in a vite.config.ts
    // export default defineConfig({
    //   plugins: [vite({ /* options */ })]
    // });
  10. Use pattycake as a Babel plugin

    main

    For direct Babel transformations, you can use the babelPlugin export. This plugin requires Babel version 7. It wraps the core pattycake logic and applies it during the Babel transformation lifecycle. You must provide an options object of type Opts.

    // In your babel.config.js or .babelrc
    module.exports = {
      plugins: [
        ['pattycake', { /* pattycake options */ }]
      ]
    };