Full Code of lxsmnsyc/solid-labels for AI

main 56eecd581df1 cached
88 files
203.3 KB
57.7k tokens
145 symbols
1 requests
Download .txt
Showing preview only (224K chars total). Download the full file or copy to clipboard to get everything.
Repository: lxsmnsyc/solid-labels
Branch: main
Commit: 56eecd581df1
Files: 88
Total size: 203.3 KB

Directory structure:
gitextract_zomu0hq3/

├── .github/
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .npmrc
├── .vscode/
│   └── settings.json
├── LICENSE
├── README.md
├── biome.json
├── docs/
│   ├── comments.md
│   ├── ctf.md
│   ├── labels.md
│   └── namespace.md
├── examples/
│   ├── comments/
│   │   ├── .gitignore
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.js
│   ├── ctf/
│   │   ├── .gitignore
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.js
│   └── labels/
│       ├── .gitignore
│       ├── index.html
│       ├── package.json
│       ├── src/
│       │   ├── App.tsx
│       │   └── main.tsx
│       ├── tsconfig.json
│       └── vite.config.js
├── lerna.json
├── package.json
├── packages/
│   ├── core/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── babel/
│   │   │   ├── components.ts
│   │   │   ├── constants.ts
│   │   │   ├── core/
│   │   │   │   ├── accessor-variable.ts
│   │   │   │   ├── assert.ts
│   │   │   │   ├── deferred-variable.ts
│   │   │   │   ├── deref-memo-variable.ts
│   │   │   │   ├── deref-memo.ts
│   │   │   │   ├── deref-signal-variable.ts
│   │   │   │   ├── deref-signal.ts
│   │   │   │   ├── destructure-variable.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── generate-unique-name.ts
│   │   │   │   ├── get-import-identifier.ts
│   │   │   │   ├── is-awaited.ts
│   │   │   │   ├── is-in-typescript.ts
│   │   │   │   ├── is-static.ts
│   │   │   │   ├── is-yielded.ts
│   │   │   │   ├── memo-variable.ts
│   │   │   │   ├── proto.ts
│   │   │   │   ├── signal-variable.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── unwrap-node.ts
│   │   │   ├── index.ts
│   │   │   ├── transform-comment.ts
│   │   │   ├── transform-ctf.ts
│   │   │   └── transform-label.ts
│   │   ├── example.js
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── test/
│   │   │   ├── __snapshots__/
│   │   │   │   └── ctf.test.ts.snap
│   │   │   └── ctf.test.ts
│   │   └── tsconfig.json
│   ├── rollup/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── unplugin/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── vite/
│       ├── .gitignore
│       ├── README.md
│       ├── package.json
│       ├── pridepack.json
│       ├── src/
│       │   └── index.ts
│       └── tsconfig.json
└── pnpm-workspace.yaml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/main.yml
================================================
name: CI
on:
  - push
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with:
          version: 8
          run_install: true

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Clean
        run: pnpm recursive run clean
        env:
          CI: true

      - name: Build
        run: pnpm recursive run build
        env:
          CI: true

      - name: Begin Tests
        run: pnpm recursive run test
        env:
          CI: true


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/

dist
.DS_Store

================================================
FILE: .npmrc
================================================
strict-peer-dependencies=false
prefer-workspace-packages=true
link-workspace-packages=true

================================================
FILE: .vscode/settings.json
================================================
{
  "editor.defaultFormatter": "biomejs.biome",
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome"
  }
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Alexis Munsayac

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================

# `solid-labels`

[![NPM](https://img.shields.io/npm/v/solid-labels.svg)](https://www.npmjs.com/package/solid-labels) [![JavaScript Style Guide](https://badgen.net/badge/code%20style/airbnb/ff5a5f?icon=airbnb)](https://github.com/airbnb/javascript)

<p align="center">
  <img
    src="https://github.com/LXSMNSYC/solid-labels/blob/main/images/ctf.png?raw=true"
    alt="Example"
    style="width: 80%; height: auto;"
  />
</p>

## Install

```bash
npm install solid-labels
```

```bash
yarn add solid-labels
```

```bash
pnpm add solid-labels
```

## Features

- 🏷 Labels: Turn labels into SolidJS utility calls!
- 💬 Comments: Turn comments into SolidJS utility calls, too!
- ⏱ Compile-time Functions: Use functions that are evaluated during compile-time!
- 📦 Auto Imports: No need to import SolidJS utilities, explicitly!
- 🤝 JS and TS Friendly!

## Usage

- [Labels](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/labels.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/labels)
- [Comments](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/comments.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/comments)
- [Compile-Time Functions](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/ctf.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/ctf)
- [Solid Namespace](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/namespace.md)

### Typescript

`<any file>.d.ts`

```ts
/// <reference types="solid-labels" />
```

### Babel

`.babelrc`

```json
{
  "plugins": [
    ["solid-labels/babel", { "dev": false }]
  ]
}
```

[!INFO]: You don't have to use this if you're using Vite or Rollup plugins

## Integrations

- [Vite](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/vite)
- [Rollup](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/rollup)
- [Unplugin](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/unplugin)

### Disabling features

You can disable some features by passing `disabled` option to the plugin options.

```js
{
  disabled: {
    labels: {
      signal: true,
    },
    pragma: {
      '@signal': true,
    },
    ctf: {
      $signal: true,
    },
  }
}
```

## Limitations

- Detecting shadowed identifier for `signal` and `memo`.

## Sponsors

![Sponsors](https://github.com/lxsmnsyc/sponsors/blob/main/sponsors.svg?raw=true)

## License

MIT © [lxsmnsyc](https://github.com/lxsmnsyc)


================================================
FILE: biome.json
================================================
{
  "$schema": "https://unpkg.com/@biomejs/biome/configuration_schema.json",
  "files": {
    "ignore": ["node_modules/**/*"]
  },
  "vcs": {
    "useIgnoreFile": true
  },
  "linter": {
    "enabled": true,
    "ignore": ["node_modules/**/*"],
    "rules": {
      "recommended": true,
      "a11y": {
        "noAriaHiddenOnFocusable": "off",
        "useIframeTitle": "warn",
        "useKeyWithClickEvents": "warn",
        "useKeyWithMouseEvents": "warn"
      },
      "complexity": {
        "noForEach": "error",
        "noVoid": "off",
        "useOptionalChain": "warn",
        "useSimplifiedLogicExpression": "error"
      },
      "correctness": {
        "noConstantMathMinMaxClamp": "error",
        "noInvalidNewBuiltin": "error",
        "noNewSymbol": "error",
        "noNodejsModules": "off",
        "noUndeclaredDependencies": "off",
        "noUndeclaredVariables": "error",
        "noUnusedFunctionParameters": "error",
        "noUnusedImports": "error",
        "noUnusedPrivateClassMembers": "error",
        "noUnusedVariables": "error",
        "useArrayLiterals": "error"
      },
      "performance": {
        "noAccumulatingSpread": "error",
        "useTopLevelRegex": "error"
      },
      "security": {
        "noGlobalEval": "off"
      },
      "style": {
        "noArguments": "error",
        "noImplicitBoolean": "error",
        "noInferrableTypes": "error",
        "noNamespace": "error",
        "noNegationElse": "error",
        "noRestrictedGlobals": "error",
        "noShoutyConstants": "error",
        "noUnusedTemplateLiteral": "error",
        "noUselessElse": "error",
        "noVar": "error",
        "noYodaExpression": "error",
        "useAsConstAssertion": "error",
        "useBlockStatements": "error",
        "useCollapsedElseIf": "error",
        "useConsistentArrayType": "error",
        "useConsistentBuiltinInstantiation": "error",
        "useConst": "error",
        "useDefaultParameterLast": "error",
        "useEnumInitializers": "error",
        "useExponentiationOperator": "error",
        "useExportType": "error",
        "useFragmentSyntax": "error",
        "useForOf": "warn",
        "useImportType": "error",
        "useLiteralEnumMembers": "error",
        "useNodejsImportProtocol": "warn",
        "useNumberNamespace": "error",
        "useNumericLiterals": "error",
        "useSelfClosingElements": "error",
        "useShorthandArrayType": "error",
        "useShorthandAssign": "error",
        "useShorthandFunctionType": "warn",
        "useSingleCaseStatement": "error",
        "useSingleVarDeclarator": "error",
        "useTemplate": "off",
        "useWhile": "error"
      },
      "suspicious": {
        "noConsoleLog": "warn",
        "noConstEnum": "off",
        "noDebugger": "off",
        "noEmptyBlockStatements": "error",
        "noExplicitAny": "warn",
        "noImplicitAnyLet": "off",
        "noMisrefactoredShorthandAssign": "off",
        "noSelfCompare": "off",
        "noSparseArray": "off",
        "noThenProperty": "warn",
        "useAwait": "error",
        "useErrorMessage": "error"
      }
    }
  },
  "formatter": {
    "enabled": true,
    "ignore": ["node_modules/**/*"],
    "formatWithErrors": false,
    "indentWidth": 2,
    "indentStyle": "space",
    "lineEnding": "lf",
    "lineWidth": 80
  },
  "organizeImports": {
    "enabled": true,
    "ignore": ["node_modules/**/*"]
  },
  "javascript": {
    "formatter": {
      "enabled": true,
      "arrowParentheses": "asNeeded",
      "bracketSameLine": false,
      "bracketSpacing": true,
      "indentWidth": 2,
      "indentStyle": "space",
      "jsxQuoteStyle": "double",
      "lineEnding": "lf",
      "lineWidth": 80,
      "quoteProperties": "asNeeded",
      "quoteStyle": "single",
      "semicolons": "always",
      "trailingCommas": "all"
    },
    "globals": [],
    "parser": {
      "unsafeParameterDecoratorsEnabled": true
    }
  },
  "json": {
    "formatter": {
      "enabled": true,
      "indentWidth": 2,
      "indentStyle": "space",
      "lineEnding": "lf",
      "lineWidth": 80
    },
    "parser": {
      "allowComments": false,
      "allowTrailingCommas": false
    }
  }
}


================================================
FILE: docs/comments.md
================================================
# Comments

## Utilities

### `@signal`

Transforms into `createSignal`:

```js
function Counter() {
  // @signal
  let x = 0;

  function increment() {
    x += 1;
  }

  return () => x;
}
```

becomes

```js
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0);

  function increment() {
    _setx(_current => _current += 1);
  }

  return () => _x();
}
```

Chained variable declaration is also supported.

```js
// @signal
let x = 0, y = 0, z = 0;
```

### `@memo`

Transforms into `createMemo`:

```js
function Counter() {
  // @signal
  let x = 0;
  // @memo
  const message = `Count: ${x}`;

  return () => message;
}
```

becomes

```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  //
  let [_x, _setx] = _createSignal(0, {
    name: "x"
  }); //


  const _message = _createMemo(() => `Count: ${_x()}`, undefined, {
    name: "message"
  });

  return () => _message();
}
```

Chained variable declaration is also supported.

```js
// @memo
const y = x + 10, z = y / 10;
```

### `@effect`, `@computed` and `@renderEffect`

Transforms into `createEffect`, `createComputed` and `createRenderEffect`, respectively.

```js
function Counter() {
  // @signal
  let x = 0;

  /* @effect */ {
    console.log('Count', x);
  }
  /* @computed */ {
    console.log('Count', x);
  }
  /* @renderEffect */ {
    console.log('Count', x);
  }
}
```

into

```js
import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0);

  _createEffect(() => {
    console.log('Count', _x());
  });

  _createComputed(() => {
    console.log('Count', _x());
  });

  _createRenderEffect(() => {
    console.log('Count', _x());
  });
}
```

You may use an arrow function instead of a block statement to accepts the previously returned value.

`@effect`, `@computed` and `@renderEffect` can also be named:

```js
// @signal
let x = 0;

/* @effect Effect Log */ {
  console.log('Count', x);
}
/* @computed Computed Log */ {
  console.log('Count', x);
}
/* @renderEffect Render Effect Log */ {
  console.log('Count', x);
}
```

```js
import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

//
let [_x, _setx] = _createSignal(0);
/**/


_createEffect(() => {
  console.log('Count', _x());
}, undefined, {
  name: "Effect Log"
});
/**/


_createComputed(() => {
  console.log('Count', _x());
}, undefined, {
  name: "Computed Log"
});
/**/


_createRenderEffect(() => {
  console.log('Count', _x());
}, undefined, {
  name: "Render Effect Log"
});
```

### `@mount`, `@cleanup` and `@error`

Transforms into `onMount`, `onCleanup` and `onError`.

```js
function Counter() {
  /* @mount */ {
    console.log('Mounted!');
  }
  /* @cleanup */ {
    console.log('Cleaned!');
  }
  /* @error */ {
    console.log('Something went wrong.');
  }
}
```

into

```js
import { onError as _onError } from "solid-js";    
import { onCleanup as _onCleanup } from "solid-js";
import { onMount as _onMount } from "solid-js";    

function Counter() {
  _onMount(() => {
    console.log('Mounted!');
  });

  _onCleanup(() => {
    console.log('Cleaned!');
  });

  _onError(() => {
    console.log('Something went wrong.');
  });
}
```

You may also use an arrow function. For `onError`, an arrow function with a parameter may be used to receive the error object.

### `@untrack` and `@batch`

Transforms into `untrack` and `batch`.

```js
function Counter() {
  /* @batch */ {
    console.log('This is batched!');
  }
  /* @untrack */ {
    console.log('This is untracked!');
  }
}
```

into

```js
import { untrack as _untrack } from "solid-js";
import { batch as _batch } from "solid-js";

function Counter() {
  _batch(() => {
    console.log('This is batched!');
  });

  _untrack(() => {
    console.log('This is untracked!');
  });
}
```

### `@root`

Transforms into `createRoot`

```js
/* @root */ {
  element = renderComponent(MyComponent);
}
```

into

```js
import { createRoot as _createRoot } from "solid-js";

_createRoot(() => {
  element = renderComponent(MyComponent);
});
```

You can also pass an arrow function instead of a block to receive the `dispose` callback.

### `@children`

Compiles to `children`.

```js
// @children
const nodes = props.children;
```

```js
import { children as _children } from "solid-js";

//
const _nodes = _children(() => props.children);
```

### `@deferred`

Compiles to `createDeferred`.

```js
// @signal
let searchInput = '';
// @deferred
let deferredSearchInput = searchInput;

effect: {
  fetchResults(deferredSearchInput);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { createDeferred as _createDeferred } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

//
let [_searchInput, _setsearchInput] = _createSignal('', {
  name: "searchInput"
}); //


let _deferredSearchInput = _createDeferred(() => _searchInput(), {
  name: "deferredSearchInput"
});

_createEffect(() => {
  fetchResults(_deferredSearchInput());
});
```

### `@transition`

Compiles to `startTransition`. Arrow function can be provided instead of blocks.

```js
// @signal
let data;

/* @transition */ {
  data = fetchData();
}
```

```js
import { startTransition as _startTransition } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

//
let [_data, _setdata] = _createSignal(undefined, {
  name: "data"
});
/**/


_startTransition(() => {
  _setdata(() => fetchData());
});
```

### `@destructure`

Destructures an object while retaining reactivity. This partially compiles to `splitProps` if a rest expression is detected.

`@destructure` also supports nested destructures.

Does not support default assignment.

```js
// @destructure
let { a: { b, c }, b: { d, e }, ...f } = x;

effect: {
  console.log(b, c);
}
effect: {
  console.log(d, e);
}
effect: {
  console.log(f);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { splitProps as _splitProps } from "solid-js";
//
const _prop = () => x.a,
  _prop2 = () => _prop().b,
  _prop3 = () => _prop().c,
  _other2 = _splitProps(_prop(), ["b", "c"])[1],
  _prop4 = () => x.b,
  _prop5 = () => _prop4().d,
  _prop6 = () => _prop4().e,
  _other3 = _splitProps(_prop4(), ["d", "e"])[1],
  _other = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(_prop2(), _prop3());
});
_createEffect(() => {
  console.log(_prop5(), _prop6());
});
_createEffect(() => {
  console.log(_other);
});
```

## Tooling

### ESLint

```json
{
  "rules": {
    "no-lone-blocks": "off"
  },
}
```


================================================
FILE: docs/ctf.md
================================================
# Compile-Time Functions

## Reactivity

### `$signal`

```ts
function $signal<T>(): T | undefined;
function $signal<T>(
  value: T,
  options?: {
    equals?: false | ((prev: T, next: T) => boolean);
    name?: string;
    internal?: boolean,
  }
): T;
```

Compiles into `createSignal`.

```js
let count = $signal(0);
```

becomes

```js
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});
```

`$signal` is only allowed to be used on variable declarations, otherwise it raises a compile-time error.

### `$memo`

```ts
function $memo<T>(
  value: T,
  options?: { equals?: false | ((prev: T, next: T) => boolean); name?: string }
): T;
function $memo<T>(
  value: T,
  options?: { equals?: false | ((prev: T, next: T) => boolean); name?: string }
): T;
```

Compiles into `createMemo`.

```js
let count = $signal(0);
const message = $memo(`Count: ${count}`);
```

becomes

```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const _message = _createMemo(() => `Count: ${_count()}`, undefined, {
  name: "message"
});
```

`$memo` is only allowed to be used on variable declarations, otherwise it raises a compile-time error.

### `$`

```ts
function $<T>(value: T): T;
```

Compiles into `createMemo` when used in variable declarations, otherwise it compiles to `createEffect` when used in single-line statements. If used for other expressions, it raises a compile-time error.

```js
let count = $signal(0);
const message = $(`Count: ${count}`);

$(console.log(message));
```

compiles into

```js
import { createEffect as _createEffect } from "solid-js";
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const _message = _createMemo(() => `Count: ${_count()}`, undefined, {
  name: "message"
});

_createEffect(() => console.log(_message()));
```

### `$untrack` and `$batch`

```ts
function $untrack<T>(value: T): T;
function $batch<T>(value: T): T;
```

Compiles into `untrack` and `batch`, respectively. Unlike `untrack` and `batch`, `$untrack` and `$batch` doesn't have to provide an arrow function.

```js
let count = $signal(0);

effect: {
  console.log($untrack(count));

  $batch(updateData(count));
}
```

compiles into

```js
import { batch as _batch } from "solid-js";
import { untrack as _untrack } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

_createEffect(() => {
  console.log(_untrack(() => _count()));

  _batch(() => updateData(_count()));
});
```

### `$effect`, `$computed` and `$renderEffect`

```ts
function $effect<T>(fn: (v?: T) => T | undefined): void;
function $effect<T>(fn: (v: T) => T, value: T, options?: { name?: string }): void;

function $computed<T>(fn: (v?: T) => T | undefined): void;
function $computed<T>(fn: (v: T) => T, value: T, options?: { name?: string }): void;

function $renderEffect<T>(fn: (v?: T) => T | undefined): void;
function $renderEffect<T>(fn: (v: T) => T, value: T, options?: { name?: string }): void;
```

Compiles to `createEffect`, `createComputed` and `createRenderEffect`, respectively.

```js
let x = $signal(0);

$effect(() => {
  console.log('Count', x);
});
$computed(() => {
  console.log('Count', x);
});
$renderEffect(() => {
  console.log('Count', x);
});
```

```js
import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_x, _setx] = _createSignal(0, {
  name: "x"
});

_createEffect(() => {
  console.log('Count', _x());
});

_createComputed(() => {
  console.log('Count', _x());
});

_createRenderEffect(() => {
  console.log('Count', _x());
});
```

### `$root`

```ts
function $root<T>(value: T): T;
function $root<T>(cb: (dispose: () => void) => T): T;
```

Compiles to `createRoot`. Can be called inline. Arrow function is automatically injected if not provided.

```js
const cleanup = $root((dispose) => {
  renderApp();
  return dispose;
});

$root(renderApp());
```

```js
import { createRoot as _createRoot } from "solid-js";

const cleanup = _createRoot(dispose => {
  renderApp();
  return dispose;
});

_createRoot(() => renderApp());
```

### `$selector`

```ts
function $selector<T, U>(
  source: T,
  fn?: (a: U, b: T) => boolean,
  options?: { name?: string }
): (key: U) => boolean;
```

Compiles to `createSelector`. Automatically injects arrow function to `source`.

```js
let selectedID = $signal();

let isSelected = $selector(selectedID);

effect: {
  if (isSelected(userID)) {
    selectUser(userID);
  }
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { createSelector as _createSelector } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_selectedID, _setselectedID] = _createSignal(undefined, {
  name: "selectedID"
});

let isSelected = _createSelector(() => _selectedID());

_createEffect(() => {
  if (isSelected(userID)) {
    selectUser(userID);
  }
});
```

### `$on`

```ts
function $on<T, U>(
  deps: T,
  fn: (input: T, prevInput: T, prevValue?: U) => U,
  options?: { defer?: boolean }
): (prevValue?: U) => U;
```

Compiles to `on`. Arrow function is automatically injected to `deps`.

```js
let selectedID = $signal();

effect: $on(selectedID, (value) => {
  if (userID === value) {
    selectUser(userID);
  }
})
```

```js
import { on as _on } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_selectedID, _setselectedID] = _createSignal(undefined, {
  name: "selectedID"
});

_createEffect(_on(() => _selectedID(), value => {
  if (userID === value) {
    selectUser(userID);
  }
}));
```

### `$deferred`

```ts
function $deferred<T>(
  source: T,
  options?: {
    equals?: false | ((prev: T, next: T) => boolean);
    name?: string;
    timeoutMs?: number;
  },
): T;
```

Compiles to `createDeferred`. Automatically injects arrow function to `source`. Automatically treats variable reads as accessor calls like `$memo`. Can only be called in variable declarations.

```js
let searchInput = $signal('');
let deferredSearchInput = $deferred(searchInput);

effect: {
  fetchResults(deferredSearchInput);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { createDeferred as _createDeferred } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_searchInput, _setsearchInput] = _createSignal('', {
  name: "searchInput"
});

let _deferredSearchInput = _createDeferred(() => _searchInput(), {
  name: "deferredSearchInput"
});

_createEffect(() => {
  fetchResults(_deferredSearchInput());
});
```

### `$resource`

This compile as an auto-import alias for `createResource`.

### `$reaction`

This CTF is a compile-time alias for the `createReaction` utility that was added in 1.3.

## Lifecycles

The following CTFs are compile-time aliases:

- `$cleanup` -> `onCleanup`
- `$mount` -> `onMount`
- `$error` -> `onError`

## Observables

### `$observable`

```ts
function $observable<T>(value: T): Observable<T>;
```

Compiles to `observable`. Automatically injects arrow function to `value`.

```js
let count = $signal(0);
const counter$ = $observable(count);
```

```js
import { observable as _observable } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const counter$ = _observable(() => _count());
```

### `$from`

```ts
function $from<T>(observable: Observable<T>): T;
function $from<T>(produce: ((setter: Setter<T>) => () => void)): T;
```

Compiles to `from`. Automatically treats variable reads as accessor calls like `$memo`.

```js
let count = $signal(0);
const counter$ = $observable(count);
const counter = $from(counter$);

effect: {
  console.log('Count:', counter);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { from as _from } from "solid-js";
import { observable as _observable } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const counter$ = _observable(() => _count());

const _counter = _from(counter$);

_createEffect(() => {
  console.log('Count:', _counter());
});
```

## Objects

### `$destructure`

```ts
function $destructure<T>(value: T): T;
```

Destructures an object while retaining reactivity. This partially compiles to `splitProps` if a rest expression is detected.

`$destructure` also supports nested destructures.

Does not support default assignment.

```js
let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

effect: {
  console.log(b, c);
}
effect: {
  console.log(d, e);
}
effect: {
  console.log(f);
}
```

```js
import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let _prop = () => x.a,
  _prop2 = () => _prop().b,
  _prop3 = () => _prop().c,
  _other2 = _splitProps(_prop(), ["b", "c"])[1],
  _prop4 = () => x.b,
  _def = defaultD,
  _prop5 = () => {
    const _value = _prop4().d;
    return _value === undefined ? _def : _value;
  },
  _def2 = defaultE,
  _prop6 = () => {
    const _value2 = _prop4().e;
    return _value2 === undefined ? _def2 : _value2;
  },
  _other3 = _splitProps(_prop4(), ["d", "e"])[1],
  _other = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(_prop2(), _prop3());
});
_createEffect(() => {
  console.log(_prop5(), _prop6());
});
_createEffect(() => {
  console.log(_other);
});
```

### `$merge`

```ts
function $merge<T extends any[]>(...args: T): MergeProps<T>;
```

Merges one or more objects while retaining reactivity. Compiles to `mergeProps`.

```js
const mergedObject = $merge(a, b, c, d);
```

```js
import { mergeProps as _mergeProps } from "solid-js";

const mergedObject = _mergeProps(a, b, c, d);
```

### `$component`

A compile-time function used to wrap components and implicitly allow prop destructuring, much like `$destructure`.

```js
$component(({ [x]: { y, ...z } = { y: 10 }, ...a }) => (
  <>
    {y}
    {z}
    {a}
  </>
))
```

```js
import { mergeProps as _mergeProps } from "solid-js";
import { splitProps as _splitProps } from "solid-js";
_props => {
  const _def = {
      y: 10
    },
    _prop = () => {
      const _value = _props[x];
      return _value === undefined ? _def : _value;
    },
    _prop2 = () => _prop().y,
    _other2 = _splitProps(_mergeProps(_prop(), _def), ["y"])[1],
    _other = _splitProps(_props, [x])[1];
  return <>
    {_prop2()}
    {_other2}
    {_other}
  </>;
};
```

## Arrays

### `$mapArray`

```ts
function $mapArray<T, U>(
  arr: readonly T[] | undefined | null | false,
  mapFn: (v: T, i: Accessor<number>) => U,
  options?: {
    fallback?: Accessor<any>;
  },
): U[];
```

Compiles to `mapArray`. Automatically treats variable reads as accessor calls like `$memo`. Automatically injects arrow function to `arr`.

```js
let list = $signal([]);
const squaredList = $mapArray(list, (value) => value ** 2);

effect: {
  console.log('1st value', squaredList[0]);
}

list = ['Hello'];
```

```js
import { createEffect as _createEffect } from "solid-js";
import { mapArray as _mapArray } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_list, _setlist] = _createSignal([], {
  name: "list"
});

const _squaredList = _mapArray(() => _list(), value => value ** 2);

_createEffect(() => {
  console.log('1st value', _squaredList()[0]);
});

_setlist(() => ['Hello']);
```

### `$indexArray`

```ts
function $indexArray<T, U>(
  arr: readonly T[] | undefined | null | false,
  mapFn: (v: Accessor<T>, i: number) => U,
  options?: {
    fallback?: Accessor<any>;
  },
): U[];
```

Compiles to `mapArray`. Automatically treats variable reads as accessor calls like `$memo`. Automatically injects arrow function to `arr`.

```js
let list = $signal([]);
const squaredList = $indexArray(list, (value) => value() ** 2);

effect: {
  console.log('1st value', squaredList[0]);
}

list = ['Hello'];
```

```js
import { createEffect as _createEffect } from "solid-js";
import { indexArray as _indexArray } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_list, _setlist] = _createSignal([], {
  name: "list"
});

const _squaredList = _indexArray(() => _list(), value => value() ** 2);

_createEffect(() => {
  console.log('1st value', _squaredList()[0]);
});

_setlist(() => ['Hello']);
```

## Component APIs

### `$uid`

```ts
function $uid(): string;
```

Compiles to `createUniqueId` (Only available for Solid 1.1.0+)

```js
const elementID = $uid();
```

```ts
import { createUniqueId as _createUniqueId } from "solid-js";

const elementID = _createUniqueId();
```

### `$lazy`

```ts
function $lazy<T extends Component<any>>(fn: Promise<{ default: T }>): T & {
  preload: () => void;
};
```

Compiles into `lazy`. Arrow function is automatically injected.

```js
const LazyComponent = $lazy(import('./LazyComponent'));
```

```js
import { lazy as _lazy } from "solid-js";

const LazyComponent = _lazy(() => import('./LazyComponent'));
```

### `$children`

```ts
function $children(value: JSX.Element): JSX.Element;
```

Compiles to `children`. Arrow function is automatically injected.

```js
const nodes = $children(props.children);
```

```js
import { children as _children } from "solid-js";

const _nodes = _children(() => props.children);
```

### Context

```ts
function $createContext<T>(): Context<T | undefined>;
function $createContext<T>(defaultValue: T): Context<T>;
function $useContext<T>(context: Context<T>): T;
```

Compiles to `createContext` and `useContext`.

```js
const CounterContext = $createContext(0);

const value = $useContext(CounterContext);
```

```js
import { useContext as _useContext } from "solid-js";
import { createContext as _createContext } from "solid-js";

const CounterContext = _createContext(0);

const value = _useContext(CounterContext);
```

### Transition

```ts
function $startTransition(fn: () => unknown): Promise<void>
function $useTransition(): Transition
```

### Owner

```ts
function $owner(): Owner | null
function $runWithOwner<T>(o: Owner, fn: () => T): T
```

Compiles to `useTransition` and `startTransition`.

## Refs and Derefs

Ref and Deref allows opting in and out of the labels syntax. This is useful for scenarios where we want to return the actual signal tuple instead of the signal value or when we have a third-party utility that we want to opt-into

```ts
function $derefSignal<T>(value: [Accessor<T>, Setter<T>]): T;
function $refSignal<T>(value: T): [Accessor<T>, Setter<T>];
function $derefMemo<T>(value: Accessor<T>): T;
function $refMemo<T>(value: T): Accessor<T>;
```

### `$refSignal`

`$refSignal` returns the signal tuple of a given signal variable.

```js
let count = $signal(0);
const [value, setValue] = $refSignal(count);
```

compiles into

```js
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const [value, setValue] = [_count, _setcount];
```

`$refSignal` also works with `signal:` label and `@signal` comment.

### `$refMemo`

`$refMemo` returns the accessor of the given memo variable. This is similar to `() => memoVariable`.

```js
let count = $signal(0);
const message = $memo(`Count: ${count}`);
const getMessage = $refMemo(message);

getMessage();
```

compiles into

```js
import { createMemo as _createMemo } from "solid-js";    
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const _message = _createMemo(() => `Count: ${_count()}`, undefined, {
  name: "message"
});

const getMessage = _message;
getMessage();
```

`$refMemo` also works  with `memo:` label and `@memo` comment.

### `$get` and `$set`

```ts
function $get<T>(value: T): Accessor<T>;
function $set<T>(value: T): Setter<T>;
```

`$get` returns the accessor for a given signal or memo variable.

```js
let count = $signal(0);
const message = $memo(`Count: ${count}`);
const getMessage = $get(message);
const getCount = $get(count);

getMessage();
getCount();
```

compiles into

```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const _message = _createMemo(() => `Count: ${_count()}`, undefined, {
  name: "message"
});

const getMessage = _message;
const getCount = _count;
getMessage();
getCount();
```

`$get` works with `signal:` and `memo:` labels as well as `@signal` and `@memo` comments.

### `$set`

`$set` returns the setter of the given signal variable.

```js
let count = $signal(0);
const setCount = $set(count);

setCount(10);
```

compiles into

```js
import { createSignal as _createSignal } from "solid-js";

let [_count, _setcount] = _createSignal(0, {
  name: "count"
});

const setCount = _setcount;
setCount(10);
```

`$set` also works with `signal:` label and `@signal` comment.

### `$derefSignal`

`$derefSignal` converts any kind of signal tuple into a signal variable.

```js
let count = $derefSignal(useCounter());

count += 10;
```

compiles into

```js
let [_count, _setcount] = useCounter();

_setcount(_current => _current += 10);
```

You can provide any kind of get/set tuples.

```js
let value = $derefSignal([getValue, setValue]);

value = newValue;

effect: {
  console.log(value);
}
```

```js
let [_value, _setvalue] = [getValue, setValue];

_setvalue(() => newValue);

_createEffect(() => {
  console.log(_value());
});
```

### `$derefMemo`

`$derefMemo` converts any kind of accessor into a memo variable.

```js
const count = $derefMemo(useCounterValue());

effect: {
  console.log('Count:', count);
}
```

compiles into

```js
import { createEffect as _createEffect } from "solid-js";

const _count = useCounterValue();

_createEffect(() => {
  console.log('Count:', _count());
});
```

## Reactive properties

### `$getter`

Assigns the given memo or signal ref to the property, transforming it into a getter property. Reading the property allows the assigned ref to be tracked.

```js
let count = $signal(0);

const obj = {
  count: $getter(count),
};
```

```js
import { createSignal as _createSignal } from "solid-js";
const _proto = {
  get count() {
    return this.__$get$count();
  }
};
let [_count, _setcount] = _createSignal(0);
const obj = {
  __proto__: _proto,
  __$get$count: _count
};
```

### `$setter`

Assigns the given signal ref to the property, transforming it into a setter property. Setting the property allows the assigned ref to be reactively updated.

```js
let count = $signal(0);

const obj = {
  count: $setter(count),
};
```

```js
import { createSignal as _createSignal } from "solid-js";
const _proto = {
  set count(_param) {
    this.__$set$count(() => _param);
  }
};
let [_count, _setcount] = _createSignal(0);
const obj = {
  __proto__: _proto,
  __$set$count: _setcount
};
```

### `$property`

A combination of `$getter` and `$setter`. For memo refs, this only outputs the getter property.

```js
let count = $signal(0);
const message = $memo(`Count: ${count}`);

const obj = {
  count: $property(count),
  message: $property(message),
};
```

```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";
const _proto = {
  get count() {
    return this.__$get$count();
  },
  set count(_param) {
    this.__$set$count(() => _param);
  },
  get message() {
    return this.__$get$message();
  }
};
let [_count, _setcount] = _createSignal(0);
const _message = _createMemo(() => `Count: ${_count()}`);
const obj = {
  __proto__: _proto,
  __$get$count: _count,
  __$set$count: _setcount,
  __$get$message: _message
};
```

## Store

These CTFs are based from `solid-js/store` exports.

- `$store` -> `createStore`
- `$mutable` -> `createMutable`
- `$reconcile` -> `reconcile`
- `$produce` -> `produce`
- `$unwrap` -> `unwrap`

## Components

These CTFs are auto-imported components from `solid-js` and `solid-js/web`. You can still use their original identifiers since those are already supported by `babel-preset-solid`.

## Tooling

On any `d.ts` file, add a reference markup

```ts
/// <reference types="solid-labels" />
```

All CTFs are declared globally so there's no need to import.


================================================
FILE: docs/labels.md
================================================
# Labels

## Utilities

### `signal`

Transforms into `createSignal`:

```js
function Counter() {
  signal: x = 0;

  function increment() {
    x += 1;
  }

  return () => x;
}
```

becomes

```js
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0);

  function increment() {
    _setx(_current => _current += 1);
  }

  return () => _x();
}
```

Chained variable declaration is also supported.

```js
signal: var x = 0, y = 0, z = 0;
```

### `memo`

Transforms into `createMemo`:

```js
function Counter() {
  signal: x = 0;
  memo: message = `Count: ${x}`;

  return () => message;
}
```

becomes

```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0, {
    name: "x"
  });

  const _message = _createMemo(() => `Count: ${_x()}`, undefined, {
    name: "message"
  });

  return () => _message();
}
```

Chained variable declaration is also supported.

```js
memo: var y = x + 10, z = y / 10;
```

### `effect`, `computed` and `renderEffect`

Transforms into `createEffect`, `createComputed` and `createRenderEffect`, respectively.

```js
function Counter() {
  signal: x = 0;

  effect: {
    console.log('Count', x);
  }
  computed: {
    console.log('Count', x);
  }
  renderEffect: {
    console.log('Count', x);
  }
}
```

into

```js
import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0);

  _createEffect(() => {
    console.log('Count', _x());
  });

  _createComputed(() => {
    console.log('Count', _x());
  });

  _createRenderEffect(() => {
    console.log('Count', _x());
  });
}
```

You may use an arrow function instead of a block statement to accept the previously returned value. If an expression (e.g. identifier, function call for `label: expr;`) is supplied, it compiles to `hook(expr)`.

They can also be named by adding another labeled statement:

```js
function Counter() {
  signal: x = 0;

  effect: effectLog: {
    console.log('Count', x);
  }
  computed: computedLog: {
    console.log('Count', x);
  }
  renderEffect: renderEffectLog: {
    console.log('Count', x);
  }
}
```

```js
import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

function Counter() {
  const [_x, _setx] = _createSignal(0);

  _createEffect(() => {
    console.log('Count', _x());
  }, undefined, {
    name: "effectLog"
  });

  _createComputed(() => {
    console.log('Count', _x());
  }, undefined, {
    name: "computedLog"
  });

  _createRenderEffect(() => {
    console.log('Count', _x());
  }, undefined, {
    name: "renderEffectLog"
  });
}
```

### `$`

Similar to `memo` and `effect`, `$` compiles to `createMemo` for variable declaration, while `createEffect(() => expr)` for other kinds of expressions (including block statements). `$` is ideal for single-line effects.

```js
let x = $signal(0);

$: var y = x + 10;
$: x = compute();
$: {
  console.log(x);
}
```

compiles into

```js
import { createEffect as _createEffect } from "solid-js";
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

let [_x, _setx] = _createSignal(0, {
  name: "x"
});

const _y = _createMemo(() => _x() + 10, undefined, {
  name: "y"
});

_createEffect(() => _setx(() => compute()));

_createEffect(() => {
  console.log(_x());
});
```

### `mount`, `cleanup` and `error`

Transforms into `onMount`, `onCleanup` and `onError`.

```js
function Counter() {
  mount: {
    console.log('Mounted!');
  }
  cleanup: {
    console.log('Cleaned!');
  }
  error: {
    console.log('Something went wrong.');
  }
}
```

into

```js
import { onError as _onError } from "solid-js";    
import { onCleanup as _onCleanup } from "solid-js";
import { onMount as _onMount } from "solid-js";    

function Counter() {
  _onMount(() => {
    console.log('Mounted!');
  });

  _onCleanup(() => {
    console.log('Cleaned!');
  });

  _onError(() => {
    console.log('Something went wrong.');
  });
}
```

You may also use an arrow function. For `onError`, an arrow function with a parameter may be used to receive the error object. If an expression (e.g. identifier, function call for `label: expr;`) is supplied, it compiles to `hook(expr)`.

### `untrack` and `batch`

Transforms into `untrack` and `batch`.

```js
function Counter() {
  batch: {
    console.log('This is batched!');
  }
  untrack: {
    console.log('This is untracked!');
  }
}
```

into

```js
import { untrack as _untrack } from "solid-js";
import { batch as _batch } from "solid-js";

function Counter() {
  _batch(() => {
    console.log('This is batched!');
  });

  _untrack(() => {
    console.log('This is untracked!');
  });
}
```

You may also use an arrow function. If an expression (e.g. identifier, function call for `label: expr;`) is supplied, it compiles to `hook(expr)`.

### `root`

Transforms into `createRoot`

```js
root: {
  element = renderComponent(MyComponent);
}
```

into

```js
import { createRoot as _createRoot } from "solid-js";

_createRoot(() => {
  element = renderComponent(MyComponent);
});
```

You can also pass an arrow function instead of a block to receive the `dispose` callback. If an expression (e.g. identifier, function call for `label: expr;`) is supplied, it compiles to `hook(expr)`.

### `children`

Compiles to `children`.

```js
children: var nodes = props.children;
```

```js
import { children as _children } from "solid-js";

const _nodes = _children(() => props.children);
```

### `deferred`

Compiles to `createDeferred`.

```js
signal: var searchInput = '';
deferred: var deferredSearchInput = searchInput;

effect: {
  fetchResults(deferredSearchInput);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { createDeferred as _createDeferred } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

const [_searchInput, _setsearchInput] = _createSignal('', {
  name: "searchInput"
});

const _deferredSearchInput = _createDeferred(() => _searchInput(), {
  name: "deferredSearchInput"
});

_createEffect(() => {
  fetchResults(_deferredSearchInput());
});
```

### `transition`

Compiles to `startTransition`. Arrow function can be provided instead of blocks.

```js
signal: var data;

transition: {
  data = fetchData();
}
```

```js
import { startTransition as _startTransition } from "solid-js";
import { createSignal as _createSignal } from "solid-js";

const [_data, _setdata] = _createSignal(undefined, {
  name: "data"
});

_startTransition(() => {
  _setdata(() => fetchData());
});
```

### `destructure`

Destructures an object while retaining reactivity. This partially compiles to `splitProps` if a rest expression is detected.

`destructure` also supports nested destructures.

Does not support default assignment.

```js
destructure: var { a: { b, c }, b: { d, e }, ...f } = x;

effect: {
  console.log(b, c);
}
effect: {
  console.log(d, e);
}
effect: {
  console.log(f);
}
```

```js
import { createEffect as _createEffect } from "solid-js";
import { splitProps as _splitProps } from "solid-js";
const _prop = () => x.a,
  _prop2 = () => _prop().b,
  _prop3 = () => _prop().c,
  _other2 = _splitProps(_prop(), ["b", "c"])[1],
  _prop4 = () => x.b,
  _prop5 = () => _prop4().d,
  _prop6 = () => _prop4().e,
  _other3 = _splitProps(_prop4(), ["d", "e"])[1],
  _other = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(_prop2(), _prop3());
});
_createEffect(() => {
  console.log(_prop5(), _prop6());
});
_createEffect(() => {
  console.log(_other);
});
```

## Tooling

### TypeScript

`tsconfig.json`

```json
{
  "compilerOptions": {
    "allowUnusedLabels": true,
  }
}
```

For `signal` and `memo` sugar, you'll need to use `@ts-ignore` to suppress warnings for TS1344 when using strict mode.

### ESLint

```json
{
  "rules": {
    "no-var": "off",
    "no-restricted-syntax": "off",
    "no-labels": "off",
    "vars-on-top": "off",
    "no-unused-labels": "off"
  },
}
```


================================================
FILE: docs/namespace.md
================================================
# Namespace

## `<solid:for>`

Alias for [`<For>`](https://www.solidjs.com/docs/latest#%3Cfor%3E)

```jsx
<solid:for each={state.list} fallback={<div>Loading...</div>}>
  {(item) => <div>{item}</div>}
</solid:for>
```

```jsx
import { For as _For } from "solid-js";
<_For each={state.list} fallback={<div>Loading...</div>}>
  {item => <div>{item}</div>}
</_For>;
```

## `<solid:index>`

Alias for [`<Index>`](https://www.solidjs.com/docs/latest#%3Cindex%3E)

```jsx
<solid:index each={state.list} fallback={<div>Loading...</div>}>
  {(item) => <div>{item()}</div>}
</solid:index>
```

```jsx
import { Index as _Index } from "solid-js";
<_Index each={state.list} fallback={<div>Loading...</div>}>
  {item => <div>{item()}</div>}
</_Index>;
```

## `<solid:switch>` and `<solid:match>`

Alias for [`<Switch>` and `<Match>`](https://www.solidjs.com/docs/latest#%3Cswitch%3E%2F%3Cmatch%3E)

```jsx
<solid:switch fallback={<div>Not Found</div>}>
  <solid:match when={state.route === "home"}>
    <Home />
  </solid:match>
  <solid:match when={state.route === "settings"}>
    <Settings />
  </solid:match>
</solid:switch>
```

```jsx
import { Match as _Match } from "solid-js";
import { Switch as _Switch } from "solid-js";
<_Switch fallback={<div>Not Found</div>}>
  <_Match when={state.route === "home"}>
    <Home />
  </_Match>
  <_Match when={state.route === "settings"}>
    <Settings />
  </_Match>
</_Switch>;
```

## `<solid:show>`

Alias for [`<Show>`](https://www.solidjs.com/docs/latest#%3Cshow%3E)

```jsx
<solid:show when={state.user} fallback={<div>Loading...</div>}>
  {(user) => <div>{user.firstName}</div>}
</solid:show>
```

```jsx
import { Show as _Show } from "solid-js";
<_Show when={state.user} fallback={<div>Loading...</div>}>
  {user => <div>{user.firstName}</div>}
</_Show>;
```

## `<solid:error-boundary>`

Alias for [`<ErrorBoundary>`](https://www.solidjs.com/docs/latest#%3Cerrorboundary%3E)

```jsx
<solid:error-boundary
  fallback={(err, reset) => <div onClick={reset}>Error: {err.toString()}</div>}
>
  <MyComp />
</solid:error-boundary>
```

```jsx
import { ErrorBoundary as _ErrorBoundary } from "solid-js";
<_ErrorBoundary fallback={(err, reset) => <div onClick={reset}>Error: {err.toString()}</div>}>
  <MyComp />
</_ErrorBoundary>;
```

## `<solid:suspense>`

Alias for [`<Suspense>`](https://www.solidjs.com/docs/latest#%3Csuspense%3E)

```jsx
<solid:suspense fallback={<div>Loading...</div>}>
  <AsyncComponent />
</solid:suspense>
```

```jsx
import { Suspense as _Suspense } from "solid-js";
<_Suspense fallback={<div>Loading...</div>}>
  <AsyncComponent />
</_Suspense>;
```

## `<solid:suspense-list>`

Alias for [`<SuspenseList>`](https://www.solidjs.com/docs/latest#%3Csuspenselist%3E-(experimental))

```jsx
<solid:suspense-list revealOrder="forwards" tail="collapsed">
  <ProfileDetails user={resource.user} />
  <solid:suspense fallback={<h2>Loading posts...</h2>}>
    <ProfileTimeline posts={resource.posts} />
  </solid:suspense>
  <solid:suspense fallback={<h2>Loading fun facts...</h2>}>
    <ProfileTrivia trivia={resource.trivia} />
  </solid:suspense>
</solid:suspense-list>
```

```jsx
import { Suspense as _Suspense } from "solid-js";
import { SuspenseList as _SuspenseList } from "solid-js";
<_SuspenseList revealOrder="forwards" tail="collapsed">
  <ProfileDetails user={resource.user} />
  <_Suspense fallback={<h2>Loading posts...</h2>}>
    <ProfileTimeline posts={resource.posts} />
  </_Suspense>
  <_Suspense fallback={<h2>Loading fun facts...</h2>}>
    <ProfileTrivia trivia={resource.trivia} />
  </_Suspense>
</_SuspenseList>;
```

## `<solid:dynamic>`

Alias for [`<Dynamic>`](https://www.solidjs.com/docs/latest#%3Cdynamic%3E)

```jsx
<solid:dynamic component={state.component} someProp={state.something} />
```

```jsx
import { Dynamic as _Dynamic } from "solid-js/web";
<_Dynamic component={state.component} someProp={state.something} />;
```

## `<solid:portal>`

Alias for [`<Portal>`](https://www.solidjs.com/docs/latest#%3Cportal%3E)

```jsx
<solid:portal mount={document.getElementById("modal")}>
  <div>My Content</div>
</solid:portal>
```

```jsx
import { Portal as _Portal } from "solid-js/web";
<_Portal mount={document.getElementById("modal")}>
  <div>My Content</div>
</_Portal>;
```

## `<solid:assets>`

Alias for `<Assets>`

```jsx
<solid:assets>
  <link rel="stylesheet" href="/styles.css" />
</solid:assets>
```

```jsx
import { Assets as _Assets } from "solid-js/web";
<_Assets>
  <link rel="stylesheet" href="/styles.css" />
</_Assets>;
```

## `<solid:hydration-script>`

Alias for `<HydrationScript>`

```jsx
const App = () => {
  return (
    <html lang="en">
      <head>
        <title>🔥 Solid SSR 🔥</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="/styles.css" />
        <solid:hydration-script />
      </head>
      <body>{/*... rest of App*/}</body>
    </html>
  );
}
```

```jsx
import { HydrationScript as _HydrationScript } from "solid-js/web";

const App = () => {
  return <html lang="en">
      <head>
        <title>🔥 Solid SSR 🔥</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="/styles.css" />
        <_HydrationScript />
      </head>
      <body>{
        /*... rest of App*/
      }</body>
    </html>;
};
```

## `<solid:no-hydration>`

Alias for `<NoHydration>`

```jsx
<solid:no-hydration>
  <ImNotHydrated />
</solid:no-hydration>
```

```jsx
import { NoHydration as _NoHydration } from "solid-js/web";
<_NoHydration>
  <ImNotHydrated />
</_NoHydration>;
```


================================================
FILE: examples/comments/.gitignore
================================================
node_modules
.DS_Store
dist
dist-ssr
*.local

================================================
FILE: examples/comments/index.html
================================================
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="favicon.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vite App</title>
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.tsx"></script>
</body>

</html>

================================================
FILE: examples/comments/package.json
================================================
{
  "name": "vite-example-comments",
  "type": "module",
  "version": "0.17.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  },
  "devDependencies": {
    "solid-labels": "0.17.0",
    "typescript": "^5.8.2",
    "vite": "^6.1.1",
    "vite-plugin-solid": "^2.11.2",
    "vite-plugin-solid-labels": "0.17.0"
  },
  "private": true,
  "publishConfig": {
    "access": "restricted"
  },
  "dependencies": {
    "solid-js": "^1.9.3"
  }
}


================================================
FILE: examples/comments/src/App.tsx
================================================
import type { JSX } from 'solid-js/jsx-runtime';

export default function App(): JSX.Element {
  /* @signal */
  let count = 0;

  /* @memo */
  const message = `Count: ${count}`;

  /* @effect */ {
    console.log(message);
  }

  function increment(): void {
    count += 1;
  }

  return (
    <button type="button" onClick={increment}>
      {message}
    </button>
  );
}


================================================
FILE: examples/comments/src/main.tsx
================================================
import { render } from 'solid-js/web';
import App from './App';

const app = document.getElementById('app');

if (app) {
  render(() => <App />, app);
}


================================================
FILE: examples/comments/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "moduleResolution": "Node",
    "strict": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnusedLabels": true,
    "noImplicitReturns": true,
    "jsx": "preserve",
    "jsxImportSource": "solid-js",
    "types": [
      "vite/client",
      "solid-labels"
    ]
  },
  "include": ["./src"]
}


================================================
FILE: examples/comments/vite.config.js
================================================
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import solidLabels from 'vite-plugin-solid-labels';

export default defineConfig({
  plugins: [
    solidPlugin({}),
    solidLabels({
      filter: {
        include: 'src/**/*.{ts,js,tsx,jsx}',
        exclude: 'node_modules/**/*.{ts,js,tsx,jsx}',
      },
    }),
  ],
});


================================================
FILE: examples/ctf/.gitignore
================================================
node_modules
.DS_Store
dist
dist-ssr
*.local

================================================
FILE: examples/ctf/index.html
================================================
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="favicon.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vite App</title>
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.tsx"></script>
</body>

</html>

================================================
FILE: examples/ctf/package.json
================================================
{
  "name": "vite-example-ctf",
  "type": "module",
  "version": "0.17.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  },
  "devDependencies": {
    "solid-labels": "0.17.0",
    "typescript": "^5.8.2",
    "vite": "^6.1.1",
    "vite-plugin-solid": "^2.11.2",
    "vite-plugin-solid-labels": "0.17.0"
  },
  "private": true,
  "publishConfig": {
    "access": "restricted"
  },
  "dependencies": {
    "solid-js": "^1.9.3"
  }
}


================================================
FILE: examples/ctf/src/App.tsx
================================================
import type { Accessor, JSX, Setter } from 'solid-js';

function useCounter(): [Accessor<number>, Setter<number>] {
  const count = $signal(0);

  $effect(() => {
    console.log('Current count:', count);
  });

  return $refSignal(count);
}

export default function App(): JSX.Element {
  let count = $derefSignal(useCounter());

  const message = $memo(`Count: ${count}`);

  $effect(() => {
    console.log(message);
  });

  function increment(): void {
    count += 1;
  }

  return (
    <>
      <button type="button" onClick={increment}>
        {message}
      </button>
      <Show when={count % 2 === 0} fallback={<h1>Odd</h1>}>
        <h1>Even</h1>
      </Show>
    </>
  );
}


================================================
FILE: examples/ctf/src/main.tsx
================================================
import { render } from 'solid-js/web';
import App from './App';

const app = document.getElementById('app');

if (app) {
  render(() => <App />, app);
}


================================================
FILE: examples/ctf/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "moduleResolution": "Node",
    "strict": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnusedLabels": true,
    "noImplicitReturns": true,
    "jsx": "preserve",
    "jsxImportSource": "solid-js",
    "types": [
      "vite/client",
      "solid-labels"
    ]
  },
  "include": ["./src"]
}


================================================
FILE: examples/ctf/vite.config.js
================================================
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import solidLabels from 'vite-plugin-solid-labels';

export default defineConfig({
  plugins: [
    solidPlugin({}),
    solidLabels({
      filter: {
        include: 'src/**/*.{ts,js,tsx,jsx}',
        exclude: 'node_modules/**/*.{ts,js,tsx,jsx}',
      },
    }),
  ],
});


================================================
FILE: examples/labels/.gitignore
================================================
node_modules
.DS_Store
dist
dist-ssr
*.local

================================================
FILE: examples/labels/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>


================================================
FILE: examples/labels/package.json
================================================
{
  "name": "vite-example-labels",
  "type": "module",
  "version": "0.17.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  },
  "devDependencies": {
    "solid-labels": "0.17.0",
    "typescript": "^5.8.2",
    "vite": "^6.1.1",
    "vite-plugin-solid": "^2.11.2",
    "vite-plugin-solid-labels": "0.17.0"
  },
  "private": true,
  "publishConfig": {
    "access": "restricted"
  },
  "dependencies": {
    "solid-js": "^1.9.3"
  }
}


================================================
FILE: examples/labels/src/App.tsx
================================================
import type { JSX } from 'solid-js/jsx-runtime';

export default function App(): JSX.Element {
  signal: var count = 0;
  memo: var message = `Count: ${count}`;

  effect: {
    console.log(message);
  }

  function increment(): void {
    count += 1;
  }

  return (
    <button type="button" onClick={increment}>
      {message}
    </button>
  );
}


================================================
FILE: examples/labels/src/main.tsx
================================================
import { render } from 'solid-js/web';
import App from './App';

const app = document.getElementById('app');

if (app) {
  render(() => <App />, app);
}


================================================
FILE: examples/labels/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "moduleResolution": "Node",
    "strict": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnusedLabels": true,
    "noImplicitReturns": true,
    "jsx": "preserve",
    "jsxImportSource": "solid-js",
    "types": [
      "vite/client",
      "solid-labels"
    ]
  },
  "include": ["./src"]
}


================================================
FILE: examples/labels/vite.config.js
================================================
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import solidLabels from 'vite-plugin-solid-labels';

export default defineConfig({
  plugins: [
    solidPlugin({}),
    solidLabels({
      filter: {
        include: 'src/**/*.{ts,js,tsx,jsx}',
        exclude: 'node_modules/**/*.{ts,js,tsx,jsx}',
      },
    }),
  ],
});


================================================
FILE: lerna.json
================================================
{
  "npmClient": "npm",
  "packages": [
    "packages/*",
    "examples/*"
  ],
  "command": {
    "version": {
      "exact": true
    },
    "publish": {
      "allowBranch": [
        "main"
      ],
      "registry": "https://registry.npmjs.org/"
    }
  },
  "version": "0.17.0"
}

================================================
FILE: package.json
================================================
{
  "name": "root",
  "private": true,
  "workspaces": ["packages/*", "examples/*"],
  "devDependencies": {
    "@biomejs/biome": "^1.9.4",
    "lerna": "^8.2.1",
    "typescript": "^5.8.2"
  }
}


================================================
FILE: packages/core/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc


================================================
FILE: packages/core/README.md
================================================

# `solid-labels`

[![NPM](https://img.shields.io/npm/v/solid-labels.svg)](https://www.npmjs.com/package/solid-labels) [![JavaScript Style Guide](https://badgen.net/badge/code%20style/airbnb/ff5a5f?icon=airbnb)](https://github.com/airbnb/javascript)

<p align="center">
  <img
    src="https://github.com/LXSMNSYC/solid-labels/blob/main/images/ctf.png?raw=true"
    alt="Example"
    style="width: 80%; height: auto;"
  />
</p>

## Install

```bash
npm install solid-labels
```

```bash
yarn add solid-labels
```

```bash
pnpm add solid-labels
```

## Features

- 🏷 Labels: Turn labels into SolidJS utility calls!
- 💬 Comments: Turn comments into SolidJS utility calls, too!
- ⏱ Compile-time Functions: Use functions that are evaluated during compile-time!
- 📦 Auto Imports: No need to import SolidJS utilities, explicitly!
- 🤝 JS and TS Friendly!

## Usage

- [Labels](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/labels.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/labels)
- [Comments](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/comments.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/comments)
- [Compile-Time Functions](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/ctf.md)
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/github/LXSMNSYC/solid-labels/tree/main/examples/ctf)
- [Solid Namespace](https://github.com/LXSMNSYC/solid-labels/tree/main/docs/namespace.md)

### Typescript

`<any file>.d.ts`

```ts
/// <reference types="solid-labels" />
```

### Babel

`.babelrc`

```json
{
  "plugins": [
    ["solid-labels/babel", { "dev": false }]
  ]
}
```

[!INFO]: You don't have to use this if you're using Vite or Rollup plugins

## Integrations

- [Vite](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/vite)
- [Rollup](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/rollup)
- [Unplugin](https://github.com/lxsmnsyc/solid-labels/tree/main/packages/unplugin)

### Disabling features

You can disable some features by passing `disabled` option to the plugin options.

```js
{
  disabled: {
    labels: {
      signal: true,
    },
    pragma: {
      '@signal': true,
    },
    ctf: {
      $signal: true,
    },
  }
}
```

## Limitations

- Detecting shadowed identifier for `signal` and `memo`.

## Sponsors

![Sponsors](https://github.com/lxsmnsyc/sponsors/blob/main/sponsors.svg?raw=true)

## License

MIT © [lxsmnsyc](https://github.com/lxsmnsyc)


================================================
FILE: packages/core/babel/components.ts
================================================
import type { NodePath, Visitor } from '@babel/traverse';
import * as t from '@babel/types';
import { getImportIdentifier } from './core/get-import-identifier';
import type { State } from './core/types';

type ComponentImport = [name: string, source: string];

const COMPONENTS: Record<string, ComponentImport> = {
  // Components
  For: ['For', 'solid-js'],
  Show: ['Show', 'solid-js'],
  Switch: ['Switch', 'solid-js'],
  Match: ['Match', 'solid-js'],
  Index: ['Index', 'solid-js'],
  ErrorBoundary: ['ErrorBoundary', 'solid-js'],
  Suspense: ['Suspense', 'solid-js'],
  SuspenseList: ['SuspenseList', 'solid-js'],
  Dynamic: ['Dynamic', 'solid-js/web'],
  Portal: ['Portal', 'solid-js/web'],
  Assets: ['Assets', 'solid-js/web'],
  HydrationScript: ['HydrationScript', 'solid-js/web'],
  NoHydration: ['NoHydration', 'solid-js/web'],
};

const NAMESPACE = 'solid';

const NAMESPACE_COMPONENTS: Record<string, ComponentImport> = {
  // Components
  for: ['For', 'solid-js'],
  show: ['Show', 'solid-js'],
  switch: ['Switch', 'solid-js'],
  match: ['Match', 'solid-js'],
  index: ['Index', 'solid-js'],
  'error-boundary': ['ErrorBoundary', 'solid-js'],
  suspense: ['Suspense', 'solid-js'],
  'suspense-list': ['SuspenseList', 'solid-js'],
  dynamic: ['Dynamic', 'solid-js/web'],
  portal: ['Portal', 'solid-js/web'],
  assets: ['Assets', 'solid-js/web'],
  'hydration-script': ['HydrationScript', 'solid-js/web'],
  'no-hydration': ['NoHydration', 'solid-js/web'],
};

const COMPONENT_TRAVERSE: Visitor<State> = {
  Expression(p, state) {
    if (
      t.isIdentifier(p.node) &&
      !p.scope.hasBinding(p.node.name) &&
      p.node.name in COMPONENTS
    ) {
      const [name, source] = COMPONENTS[p.node.name];
      p.replaceWith(getImportIdentifier(state, p, name, source));
    }
  },
  JSXElement(p, state) {
    const { openingElement, closingElement } = p.node;
    const id = openingElement.name;
    let replacement: t.JSXIdentifier | undefined;
    if (
      t.isJSXNamespacedName(id) &&
      id.namespace.name === NAMESPACE &&
      id.name.name in NAMESPACE_COMPONENTS
    ) {
      const [name, source] = NAMESPACE_COMPONENTS[id.name.name];
      const identifier = getImportIdentifier(state, p, name, source);
      replacement = t.jsxIdentifier(identifier.name);
    }
    if (
      t.isJSXIdentifier(id) &&
      !p.scope.hasBinding(id.name) &&
      id.name in COMPONENTS
    ) {
      const [name, source] = COMPONENTS[id.name];
      const identifier = getImportIdentifier(state, p, name, source);
      replacement = t.jsxIdentifier(identifier.name);
    }

    if (replacement) {
      openingElement.name = replacement;
      if (closingElement) {
        closingElement.name = replacement;
      }
    }
  },
};

export function transformComponents(state: State, path: NodePath): void {
  path.traverse(COMPONENT_TRAVERSE, state);
}


================================================
FILE: packages/core/babel/constants.ts
================================================
import * as t from '@babel/types';

export const UNDEFINED = t.unaryExpression('void', t.numericLiteral(0));


================================================
FILE: packages/core/babel/core/accessor-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { derefMemo } from './deref-memo';
import { generateUniqueName } from './generate-unique-name';

export function accessorVariable(
  path: babel.NodePath,
  accessorIdentifier: t.Identifier,
  callee: t.Identifier,
  replacement: Array<t.Expression | t.SpreadElement | t.ArgumentPlaceholder>,
): t.VariableDeclarator {
  const readIdentifier = generateUniqueName(path, accessorIdentifier.name);

  derefMemo(path, accessorIdentifier, readIdentifier);

  return t.variableDeclarator(
    readIdentifier,
    t.callExpression(callee, replacement),
  );
}


================================================
FILE: packages/core/babel/core/assert.ts
================================================
export function assert<T extends Error>(cond: unknown, error: T): asserts cond {
  if (!cond) {
    throw error;
  }
}


================================================
FILE: packages/core/babel/core/deferred-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { accessorVariable } from './accessor-variable';
import { getImportIdentifier } from './get-import-identifier';
import type { State } from './types';
import { UNDEFINED } from '../constants';

export function deferredVariable(
  state: State,
  path: babel.NodePath,
  deferredIdentifier: t.Identifier,
  stateIdentifier: t.Expression = UNDEFINED,
  optionsIdentifier: t.Expression | undefined = undefined,
): t.VariableDeclarator {
  const normalIdentifier = t.arrowFunctionExpression([], stateIdentifier);
  const args: t.Expression[] = [normalIdentifier];
  if (state.opts.dev) {
    if (optionsIdentifier) {
      args.push(
        t.callExpression(
          t.memberExpression(t.identifier('Object'), t.identifier('assign')),
          [
            t.objectExpression([
              t.objectProperty(
                t.identifier('name'),
                t.stringLiteral(deferredIdentifier.name),
              ),
            ]),
            optionsIdentifier,
          ],
        ),
      );
    } else {
      args.push(
        t.objectExpression([
          t.objectProperty(
            t.identifier('name'),
            t.stringLiteral(deferredIdentifier.name),
          ),
        ]),
      );
    }
  } else if (optionsIdentifier) {
    args.push(optionsIdentifier);
  }
  return accessorVariable(
    path,
    deferredIdentifier,
    getImportIdentifier(state, path, 'createDeferred', 'solid-js'),
    args,
  );
}


================================================
FILE: packages/core/babel/core/deref-memo-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { derefMemo } from './deref-memo';
import { generateUniqueName } from './generate-unique-name';

export function derefMemoVariable(
  path: babel.NodePath,
  memoIdentifier: t.Identifier,
  stateIdentifier: t.Expression,
): t.VariableDeclarator {
  const readIdentifier = generateUniqueName(path, memoIdentifier.name);

  derefMemo(path, memoIdentifier, readIdentifier);

  return t.variableDeclarator(readIdentifier, stateIdentifier);
}


================================================
FILE: packages/core/babel/core/deref-memo.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { assert } from './assert';
import { unexpectedType } from './errors';
import { addProtoGetter } from './proto';
import { getProperParentPath, unwrapNode } from './unwrap-node';

const REF_MEMO_CTF = '$refMemo';
const GET_CTF = '$get';

const GETTER_CTF = '$getter';
const PROPERTY_CTF = '$property';

const CALL_CTF = new Set([REF_MEMO_CTF, GET_CTF, GETTER_CTF, PROPERTY_CTF]);

function transformGetter(
  parent: babel.NodePath<t.CallExpression>,
  readIdentifier: t.Identifier,
): boolean {
  const propertyParent = getProperParentPath(parent, t.isObjectProperty);
  if (!propertyParent) {
    return true;
  }
  const key = propertyParent.node.key;
  assert(
    t.isExpression(key),
    unexpectedType(propertyParent.get('key'), key.type, 'Identifier'),
  );
  const objectParent = getProperParentPath(
    propertyParent,
    t.isObjectExpression,
  );
  if (!objectParent) {
    return true;
  }
  addProtoGetter(objectParent, propertyParent, key, readIdentifier);
  return false;
}

function transformReferencePath(
  ref: babel.NodePath,
  readIdentifier: t.Identifier,
): boolean {
  const parent = getProperParentPath(ref, t.isCallExpression);
  if (parent) {
    const trueCallee = unwrapNode(parent.node.callee, t.isIdentifier);
    if (!(trueCallee && CALL_CTF.has(trueCallee.name))) {
      return true;
    }
    const rawArgs = parent.get('arguments')[0];
    const arg = unwrapNode(rawArgs.node, t.isIdentifier);
    assert(arg, unexpectedType(rawArgs, rawArgs.type, 'Identifier'));
    if (arg !== ref.node) {
      return true;
    }
    switch (trueCallee.name) {
      case REF_MEMO_CTF:
      case GET_CTF:
        parent.replaceWith(readIdentifier);
        break;
      case PROPERTY_CTF:
      case GETTER_CTF:
        return transformGetter(parent, readIdentifier);
    }
    return false;
  }
  return true;
}

export function derefMemo(
  path: babel.NodePath,
  memoIdentifier: t.Identifier,
  readIdentifier: t.Identifier,
): void {
  const binding = path.scope.getBinding(memoIdentifier.name);
  if (!binding) {
    return;
  }
  for (const ref of binding.referencePaths) {
    if (transformReferencePath(ref, readIdentifier)) {
      assert(
        t.isIdentifier(ref.node),
        unexpectedType(ref, ref.node.type, 'Identifier'),
      );
      ref.replaceWith(t.callExpression(readIdentifier, []));
    }
  }
}


================================================
FILE: packages/core/babel/core/deref-signal-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { derefSignal } from './deref-signal';
import { generateUniqueName } from './generate-unique-name';

export function derefSignalVariable(
  path: babel.NodePath,
  signalIdentifier: t.Identifier,
  stateIdentifier: t.Expression,
): t.VariableDeclarator {
  const readIdentifier = generateUniqueName(path, signalIdentifier.name);
  const writeIdentifier = generateUniqueName(
    path,
    `set${signalIdentifier.name}`,
  );
  derefSignal(path, signalIdentifier, readIdentifier, writeIdentifier);

  return t.variableDeclarator(
    t.arrayPattern([readIdentifier, writeIdentifier]),
    stateIdentifier,
  );
}


================================================
FILE: packages/core/babel/core/deref-signal.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { assert } from './assert';
import { unexpectedType } from './errors';
import { generateUniqueName } from './generate-unique-name';
import { isAwaited } from './is-awaited';
import { isYielded } from './is-yielded';
import { addProtoGetter, addProtoProperty, addProtoSetter } from './proto';
import { getProperParentPath, isPathValid, unwrapNode } from './unwrap-node';

const REF_SIGNAL_CTF = '$refSignal';
const GET_CTF = '$get';
const SET_CTF = '$set';

const GETTER_CTF = '$getter';
const SETTER_CTF = '$setter';
const PROPERTY_CTF = '$property';

const CALL_CTF = new Set([
  REF_SIGNAL_CTF,
  GET_CTF,
  SET_CTF,
  GETTER_CTF,
  SETTER_CTF,
  PROPERTY_CTF,
]);

function transformProperty(
  parent: babel.NodePath<t.CallExpression>,
  ctf: string,
  readIdentifier: t.Identifier,
  writeIdentifier: t.Identifier,
): boolean {
  const propertyParent = getProperParentPath(parent, t.isObjectProperty);
  if (!propertyParent) {
    return true;
  }
  const key = propertyParent.node.key;
  assert(
    t.isExpression(key),
    unexpectedType(propertyParent.get('key'), key.type, 'Identifier'),
  );
  const objectParent = getProperParentPath(
    propertyParent,
    t.isObjectExpression,
  );
  if (!objectParent) {
    return true;
  }
  switch (ctf) {
    case SETTER_CTF:
      addProtoSetter(objectParent, propertyParent, key, writeIdentifier);
      break;
    case GETTER_CTF:
      addProtoGetter(objectParent, propertyParent, key, writeIdentifier);
      break;
    case PROPERTY_CTF:
      addProtoProperty(
        objectParent,
        propertyParent,
        key,
        readIdentifier,
        writeIdentifier,
      );
      break;
  }
  return false;
}

function transformSignalRead(
  ref: babel.NodePath,
  readIdentifier: t.Identifier,
  writeIdentifier: t.Identifier,
): boolean {
  const parent = getProperParentPath(ref, t.isCallExpression);
  if (parent) {
    const trueCallee = unwrapNode(parent.node.callee, t.isIdentifier);
    if (!(trueCallee && CALL_CTF.has(trueCallee.name))) {
      return true;
    }
    const rawArgs = parent.get('arguments')[0];
    const arg = unwrapNode(rawArgs.node, t.isIdentifier);
    assert(arg, unexpectedType(rawArgs, rawArgs.type, 'Identifier'));
    if (arg !== ref.node) {
      return true;
    }
    switch (trueCallee.name) {
      case REF_SIGNAL_CTF:
        parent.replaceWith(
          t.arrayExpression([readIdentifier, writeIdentifier]),
        );
        break;
      case SET_CTF:
        parent.replaceWith(writeIdentifier);
        break;
      case GET_CTF:
        parent.replaceWith(readIdentifier);
        break;
      case PROPERTY_CTF:
      case SETTER_CTF:
      case GETTER_CTF:
        return transformProperty(
          parent,
          trueCallee.name,
          readIdentifier,
          writeIdentifier,
        );
    }
    return false;
  }
  return true;
}

function transformUpdateExpression(
  ref: babel.NodePath<t.UpdateExpression>,
  writeIdentifier: t.Identifier,
): void {
  const param = generateUniqueName(ref, 'current');
  if (ref.node.prefix) {
    const tmp = generateUniqueName(ref, 'tmp');
    ref.replaceWith(
      t.callExpression(
        t.arrowFunctionExpression(
          [],
          t.blockStatement([
            t.variableDeclaration('let', [t.variableDeclarator(tmp)]),
            t.expressionStatement(
              t.callExpression(writeIdentifier, [
                t.arrowFunctionExpression(
                  [param],
                  t.binaryExpression(
                    ref.node.operator === '++' ? '+' : '-',
                    t.assignmentExpression('=', tmp, param),
                    t.numericLiteral(1),
                  ),
                ),
              ]),
            ),
            t.returnStatement(tmp),
          ]),
        ),
        [],
      ),
    );
  } else {
    ref.replaceWith(
      t.callExpression(writeIdentifier, [
        t.arrowFunctionExpression(
          [param],
          t.binaryExpression(
            ref.node.operator === '++' ? '+' : '-',
            param,
            t.numericLiteral(1),
          ),
        ),
      ]),
    );
  }
}

function transformAssignmentExpression(
  ref: babel.NodePath<t.AssignmentExpression>,
  writeIdentifier: t.Identifier,
): void {
  assert(
    t.isIdentifier(ref.node.left),
    unexpectedType(ref.get('left'), ref.node.left.type, 'Identifier'),
  );
  let expression = ref.node.right;
  if (isAwaited(expression) || isYielded(expression)) {
    const statement = ref.getStatementParent();
    const functionParent = ref.getFunctionParent();
    if (statement) {
      const awaitedID = generateUniqueName(statement, 'tmp');
      const declaration = t.variableDeclaration('const', [
        t.variableDeclarator(awaitedID, expression),
      ]);

      if (functionParent) {
        if (functionParent.isAncestor(statement)) {
          statement.insertBefore(declaration);
        } else {
          functionParent.scope.push({
            id: awaitedID,
            init: expression,
            kind: 'const',
          });
        }
      } else {
        statement.insertBefore(declaration);
      }
      expression = awaitedID;
    }
  }
  let arg: t.Expression;
  if (ref.node.operator === '=') {
    arg = t.arrowFunctionExpression([], expression);
  } else {
    const param = generateUniqueName(ref, 'current');
    arg = t.arrowFunctionExpression(
      [param],
      t.assignmentExpression(ref.node.operator, param, expression),
    );
  }
  ref.replaceWith(t.callExpression(writeIdentifier, [arg]));
}

function transformSignalWrite(
  ref: babel.NodePath,
  writeIdentifier: t.Identifier,
): void {
  if (isPathValid(ref, t.isUpdateExpression)) {
    transformUpdateExpression(ref, writeIdentifier);
    return;
  }
  if (isPathValid(ref, t.isAssignmentExpression)) {
    transformAssignmentExpression(ref, writeIdentifier);
    return;
  }
}

export function derefSignal(
  path: babel.NodePath,
  signalIdentifier: t.Identifier,
  readIdentifier: t.Identifier,
  writeIdentifier: t.Identifier,
): void {
  const binding = path.scope.getBinding(signalIdentifier.name);
  if (!binding) {
    return;
  }
  // Transform all writes
  for (const ref of binding.constantViolations) {
    transformSignalWrite(ref, writeIdentifier);
  }
  // Transform all reads
  for (const ref of binding.referencePaths) {
    if (transformSignalRead(ref, readIdentifier, writeIdentifier)) {
      assert(
        t.isIdentifier(ref.node),
        unexpectedType(ref, ref.node.type, 'Identifier'),
      );
      ref.replaceWith(t.callExpression(readIdentifier, []));
    }
  }
}


================================================
FILE: packages/core/babel/core/destructure-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { derefMemo } from './deref-memo';
import { unexpectedType } from './errors';
import { generateUniqueName } from './generate-unique-name';
import { getImportIdentifier } from './get-import-identifier';
import { isStatic } from './is-static';
import type { State } from './types';
import { unwrapNode } from './unwrap-node';
import { UNDEFINED } from '../constants';

export function destructureVariable(
  state: State,
  path: babel.NodePath,
  target: t.Expression,
  pattern: t.ObjectPattern | t.ArrayPattern,
  defaultValue?: t.Expression,
): t.VariableDeclarator[] {
  const otherIdentifier = generateUniqueName(path, 'other');
  let declarators: t.VariableDeclarator[] = [];
  const properties: t.Expression[] = [];
  let restIdentifier: t.Identifier | undefined;

  // Destructuring for object patterns
  if (t.isObjectPattern(pattern)) {
    for (let i = 0, len = pattern.properties.length; i < len; i++) {
      const property = pattern.properties[i];
      // Check if this is an object property
      if (t.isObjectProperty(property)) {
        const { value, key } = property;

        if (!property.computed) {
          if (t.isIdentifier(key)) {
            properties.push(t.stringLiteral(key.name));
          }
        } else if (t.isPrivateName(key)) {
          throw unexpectedType(path, 'PrivateName', 'Expression');
        } else {
          properties.push(key);
        }

        // Create a new identifier for the destructure variable
        const newIdentifier = generateUniqueName(path, 'prop');
        let access: t.Expression | t.BlockStatement = t.memberExpression(
          target,
          key,
          property.computed,
        );
        let defaultIdentifier: t.Identifier | undefined;
        if (t.isAssignmentPattern(value)) {
          defaultIdentifier = generateUniqueName(path, 'def');
          const isStaticValue = isStatic(value.right);
          const defValue = isStaticValue
            ? value.right
            : t.callExpression(
                getImportIdentifier(state, path, 'createMemo', 'solid-js'),
                [t.arrowFunctionExpression([], value.right)],
              );
          declarators.push(t.variableDeclarator(defaultIdentifier, defValue));
          const valueIdentifier = generateUniqueName(path, 'value');
          access = t.blockStatement([
            t.variableDeclaration('const', [
              t.variableDeclarator(valueIdentifier, access),
            ]),
            t.returnStatement(
              t.conditionalExpression(
                t.binaryExpression('===', valueIdentifier, UNDEFINED),
                isStaticValue
                  ? defaultIdentifier
                  : t.callExpression(defaultIdentifier, []),
                valueIdentifier,
              ),
            ),
          ]);
        }
        declarators.push(
          t.variableDeclarator(
            newIdentifier,
            t.arrowFunctionExpression([], access),
          ),
        );

        // If the value is an object or array pattern
        // destructure that value again
        // e.g. { x: { y, z }} = w;
        if (t.isObjectPattern(value) || t.isArrayPattern(value)) {
          declarators = [
            ...declarators,
            ...destructureVariable(
              state,
              path,
              t.callExpression(newIdentifier, []),
              value,
            ),
          ];
        } else if (t.isIdentifier(value)) {
          // If the value is just a normal identifier
          // e.g. { x: y } = w;
          // normalize bindings
          derefMemo(path, value, newIdentifier);
        } else if (t.isAssignmentPattern(value)) {
          if (t.isIdentifier(value.left)) {
            // If the value has a default value
            derefMemo(path, value.left, newIdentifier);
          } else if (
            t.isArrayPattern(value.left) ||
            t.isObjectPattern(value.left)
          ) {
            // Otherwise it's just another array/object
            declarators = [
              ...declarators,
              ...destructureVariable(
                state,
                path,
                t.callExpression(newIdentifier, []),
                value.left,
                defaultIdentifier,
              ),
            ];
          }
        } else {
          throw unexpectedType(
            path,
            value.type,
            'Identifier | ObjectPattern | ArrayPattern',
          );
        }
      } else {
        // or it's a rest element
        // make sure that it is an identifier though
        const trueIdentifier = unwrapNode(property.argument, t.isIdentifier);
        if (trueIdentifier) {
          restIdentifier = trueIdentifier;
        }
      }
    }
  } else {
    // Destructure for arrays
    for (let i = 0, len = pattern.elements.length; i < len; i++) {
      const property = pattern.elements[i];
      if (property) {
        const keyExpr = t.numericLiteral(i);

        const newIdentifier = generateUniqueName(path, 'prop');
        let access: t.Expression | t.BlockStatement = t.memberExpression(
          target,
          keyExpr,
          true,
        );
        let defaultIdentifier: t.Identifier | undefined;
        if (t.isAssignmentPattern(property)) {
          defaultIdentifier = generateUniqueName(path, 'def');
          const isStaticValue = isStatic(property.right);
          const defValue = isStaticValue
            ? property.right
            : t.callExpression(
                getImportIdentifier(state, path, 'createMemo', 'solid-js'),
                [t.arrowFunctionExpression([], property.right)],
              );
          declarators.push(t.variableDeclarator(defaultIdentifier, defValue));
          const valueIdentifier = generateUniqueName(path, 'value');
          access = t.blockStatement([
            t.variableDeclaration('const', [
              t.variableDeclarator(valueIdentifier, access),
            ]),
            t.returnStatement(
              t.conditionalExpression(
                t.binaryExpression('===', valueIdentifier, UNDEFINED),
                isStaticValue
                  ? defaultIdentifier
                  : t.callExpression(defaultIdentifier, []),
                valueIdentifier,
              ),
            ),
          ]);
        }
        declarators.push(
          t.variableDeclarator(
            newIdentifier,
            t.arrowFunctionExpression([], access),
          ),
        );

        properties.push(keyExpr);

        if (t.isIdentifier(property)) {
          derefMemo(path, property, newIdentifier);
        } else if (t.isAssignmentPattern(property)) {
          if (t.isIdentifier(property.left)) {
            derefMemo(path, property.left, newIdentifier);
          } else if (
            t.isArrayPattern(property.left) ||
            t.isObjectPattern(property.left)
          ) {
            // Otherwise it's just another array/object
            declarators = [
              ...declarators,
              ...destructureVariable(
                state,
                path,
                t.callExpression(newIdentifier, []),
                property.left,
                defaultIdentifier,
              ),
            ];
          }
        } else if (t.isArrayPattern(property) || t.isObjectPattern(property)) {
          // Otherwise it's just another array/object
          declarators = [
            ...declarators,
            ...destructureVariable(
              state,
              path,
              t.callExpression(newIdentifier, []),
              property,
            ),
          ];
        } else if (t.isRestElement(property)) {
          const trueIdentifier = unwrapNode(property.argument, t.isIdentifier);
          if (trueIdentifier) {
            restIdentifier = trueIdentifier;
          }
        }
      }
    }
  }

  const expr = t.variableDeclarator(
    otherIdentifier,
    properties.length
      ? t.memberExpression(
          t.callExpression(
            getImportIdentifier(state, path, 'splitProps', 'solid-js'),
            [
              defaultValue != null
                ? t.callExpression(
                    getImportIdentifier(state, path, 'mergeProps', 'solid-js'),
                    [target, defaultValue],
                  )
                : target,
              t.arrayExpression(properties),
            ],
          ),
          t.numericLiteral(1),
          true,
        )
      : target,
  );

  declarators.push(expr);

  if (restIdentifier) {
    const binding = path.scope.getBinding(restIdentifier.name);
    if (binding) {
      for (const ref of binding.referencePaths) {
        ref.replaceWith(otherIdentifier);
      }
    }
  }

  return declarators;
}


================================================
FILE: packages/core/babel/core/errors.ts
================================================
import type * as babel from '@babel/core';

export function unexpectedType<T>(
  path: babel.NodePath<T>,
  received: string,
  expected: string,
): Error {
  return path.buildCodeFrameError(
    `Unexpected '${received}' (Expected: ${expected})`,
  );
}

export function unexpectedMissingParent<T>(path: babel.NodePath<T>): Error {
  return path.buildCodeFrameError('Unexpected missing parent.');
}

export function unexpectedArgumentLength<T>(
  path: babel.NodePath<T>,
  received: number,
  expected: number,
): Error {
  return path.buildCodeFrameError(
    `Unexpected argument length of ${received} (Expected: ${expected})`,
  );
}

export function unexpectedAssignmentOperator<T>(
  path: babel.NodePath<T>,
  received: string,
  expected: string,
): Error {
  return path.buildCodeFrameError(
    `Unexpected assignment operator '${received}' (Expected: ${expected})`,
  );
}


================================================
FILE: packages/core/babel/core/generate-unique-name.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';

export function generateUniqueName(
  path: babel.NodePath,
  name: string,
): t.Identifier {
  let uid;
  let i = 1;
  do {
    uid = name + '_' + i;
    i++;
  } while (
    path.scope.hasLabel(uid) ||
    path.scope.hasBinding(uid) ||
    path.scope.hasGlobal(uid) ||
    path.scope.hasReference(uid)
  );

  const program = path.scope.getProgramParent();
  program.references[uid] = true;
  program.uids[uid] = true;

  return t.identifier(uid);
}


================================================
FILE: packages/core/babel/core/get-import-identifier.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import type { State } from './types';

export function getImportIdentifier(
  state: State,
  path: babel.NodePath,
  name: string,
  source: string,
): t.Identifier {
  const target = `${source}[${name}]`;
  const current = state.hooks.get(target);
  if (current) {
    return current;
  }
  const programParent = path.scope.getProgramParent();
  const uid = programParent.generateUidIdentifier(name);
  const newPath = (
    programParent.path as babel.NodePath<t.Program>
  ).unshiftContainer(
    'body',
    t.importDeclaration(
      [t.importSpecifier(uid, t.identifier(name))],
      t.stringLiteral(source),
    ),
  )[0];
  programParent.registerDeclaration(newPath);
  state.hooks.set(target, uid);
  return uid;
}


================================================
FILE: packages/core/babel/core/is-awaited.ts
================================================
import * as t from '@babel/types';

export function isAwaited(node: t.Expression | t.SpreadElement): boolean {
  // Default
  if (t.isAwaitExpression(node)) {
    return true;
  }
  if (t.isTemplateLiteral(node)) {
    return node.expressions.some(
      expr => t.isExpression(expr) && isAwaited(expr),
    );
  }
  if (
    t.isLiteral(node) ||
    t.isIdentifier(node) ||
    t.isArrowFunctionExpression(node) ||
    t.isFunctionExpression(node) ||
    t.isClassExpression(node) ||
    t.isYieldExpression(node) ||
    t.isJSX(node) ||
    t.isMetaProperty(node) ||
    t.isSuper(node) ||
    t.isThisExpression(node) ||
    t.isImport(node) ||
    t.isDoExpression(node)
  ) {
    return false;
  }
  if (t.isTaggedTemplateExpression(node)) {
    return isAwaited(node.tag) || isAwaited(node.quasi);
  }
  if (
    t.isUnaryExpression(node) ||
    t.isUpdateExpression(node) ||
    t.isSpreadElement(node)
  ) {
    return isAwaited(node.argument);
  }
  if (
    t.isParenthesizedExpression(node) ||
    t.isTypeCastExpression(node) ||
    t.isTSAsExpression(node) ||
    t.isTSSatisfiesExpression(node) ||
    t.isTSNonNullExpression(node) ||
    t.isTSTypeAssertion(node) ||
    t.isTSInstantiationExpression(node)
  ) {
    return isAwaited(node.expression);
  }
  // Check for elements
  if (t.isArrayExpression(node) || t.isTupleExpression(node)) {
    return node.elements.some(el => el != null && isAwaited(el));
  }
  // Skip arrow function
  if (t.isAssignmentExpression(node)) {
    if (isAwaited(node.right)) {
      return true;
    }
    if (t.isExpression(node.left)) {
      return isAwaited(node.left);
    }
    return false;
  }
  if (t.isBinaryExpression(node)) {
    if (t.isExpression(node.left) && isAwaited(node.left)) {
      return true;
    }
    return isAwaited(node.right);
  }
  if (
    t.isCallExpression(node) ||
    t.isOptionalCallExpression(node) ||
    t.isNewExpression(node)
  ) {
    if (t.isExpression(node.callee) && isAwaited(node.callee)) {
      return true;
    }
    return node.arguments.some(
      arg =>
        arg &&
        (t.isSpreadElement(arg) || t.isExpression(arg)) &&
        isAwaited(arg),
    );
  }
  if (t.isConditionalExpression(node)) {
    return (
      isAwaited(node.test) ||
      isAwaited(node.consequent) ||
      isAwaited(node.alternate)
    );
  }
  if (t.isLogicalExpression(node)) {
    return isAwaited(node.left) || isAwaited(node.right);
  }
  if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
    return (
      isAwaited(node.object) ||
      (node.computed &&
        t.isExpression(node.property) &&
        isAwaited(node.property))
    );
  }
  if (t.isSequenceExpression(node)) {
    return node.expressions.some(isAwaited);
  }
  if (t.isObjectExpression(node) || t.isRecordExpression(node)) {
    return node.properties.some(prop => {
      if (t.isObjectProperty(prop)) {
        if (t.isExpression(prop.value) && isAwaited(prop.value)) {
          return true;
        }
        if (prop.computed && t.isExpression(prop.key) && isAwaited(prop.key)) {
          return true;
        }
        return false;
      }
      if (t.isSpreadElement(prop)) {
        return isAwaited(prop);
      }
      return false;
    });
  }
  if (t.isBindExpression(node)) {
    return isAwaited(node.object) || isAwaited(node.callee);
  }
  return false;
}


================================================
FILE: packages/core/babel/core/is-in-typescript.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';

export function isInTypescript(path: babel.NodePath): boolean {
  let parent = path.parentPath;
  while (parent) {
    if (t.isTypeScript(parent.node) && !t.isExpression(parent.node)) {
      return true;
    }
    parent = parent.parentPath;
  }
  return false;
}


================================================
FILE: packages/core/babel/core/is-static.ts
================================================
import * as t from '@babel/types';

export function isStatic(
  node:
    | t.Expression
    | t.SpreadElement
    | t.AssignmentPattern
    | t.ArrayPattern
    | t.ObjectPattern
    | t.RestElement,
): boolean {
  // The following types are singular nested expressions
  if (
    t.isParenthesizedExpression(node) ||
    t.isTypeCastExpression(node) ||
    t.isTSAsExpression(node) ||
    t.isTSSatisfiesExpression(node) ||
    t.isTSNonNullExpression(node) ||
    t.isTSTypeAssertion(node) ||
    t.isTSInstantiationExpression(node)
  ) {
    return isStatic(node.expression);
  }
  // Same as above
  if (
    t.isUnaryExpression(node) ||
    t.isUpdateExpression(node) ||
    t.isSpreadElement(node)
  ) {
    return isStatic(node.argument);
  }
  if (t.isRestElement(node)) {
    if (t.isTSParameterProperty(node.argument)) {
      return false;
    }
    return isStatic(node.argument);
  }
  if (t.isLiteral(node)) {
    if (t.isTemplateLiteral(node)) {
      return node.expressions.every(expr => {
        if (t.isExpression(expr)) {
          return isStatic(expr);
        }
        return false;
      });
    }
    return true;
  }
  // The following types are always static
  if (
    t.isIdentifier(node) ||
    t.isArrowFunctionExpression(node) ||
    t.isFunctionExpression(node)
    // ||
    // t.isJSXElement(node) ||
    // t.isJSXFragment(node)
  ) {
    return true;
  }
  // Arrays and tuples might have static values
  if (t.isArrayExpression(node) || t.isTupleExpression(node)) {
    return node.elements.every(el => {
      if (el) {
        return isStatic(el);
      }
      return true;
    });
  }
  if (t.isArrayPattern(node)) {
    return node.elements.every(el => {
      if (t.isTSParameterProperty(el)) {
        return false;
      }
      if (el) {
        return isStatic(el);
      }
      return true;
    });
  }
  if (t.isObjectExpression(node) || t.isRecordExpression(node)) {
    return node.properties.every(prop => {
      if (t.isObjectProperty(prop)) {
        if (t.isExpression(prop.value) && isStatic(prop.value)) {
          return true;
        }
        if (prop.computed && t.isExpression(prop.key) && isStatic(prop.key)) {
          return true;
        }
        return false;
      }
      if (t.isSpreadElement(prop)) {
        return isStatic(prop);
      }
      // Ignore
      return true;
    });
  }
  if (t.isObjectPattern(node)) {
    return node.properties.every(prop => {
      if (t.isObjectProperty(prop)) {
        if (!t.isTSTypeParameter(prop.value) && isStatic(prop.value)) {
          return true;
        }
        if (prop.computed && t.isExpression(prop.key) && isStatic(prop.key)) {
          return true;
        }
        return false;
      }
      if (t.isSpreadElement(prop)) {
        return isStatic(prop);
      }
      // Ignore
      return true;
    });
  }
  if (t.isAssignmentExpression(node) || t.isAssignmentPattern(node)) {
    if (isStatic(node.right)) {
      return true;
    }
    if (!t.isTSParameterProperty(node.left)) {
      return false;
    }
    return isStatic(node);
  }
  if (t.isSequenceExpression(node)) {
    return node.expressions.every(isStatic);
  }
  if (t.isConditionalExpression(node)) {
    return (
      isStatic(node.test) ||
      isStatic(node.consequent) ||
      isStatic(node.alternate)
    );
  }
  if (t.isBinaryExpression(node)) {
    if (t.isExpression(node.left)) {
      return isStatic(node.left);
    }
    if (t.isExpression(node.right)) {
      return isStatic(node.right);
    }
    return false;
  }
  if (t.isLogicalExpression(node)) {
    return isStatic(node.left) || isStatic(node.right);
  }
  return false;
}


================================================
FILE: packages/core/babel/core/is-yielded.ts
================================================
import * as t from '@babel/types';

export function isYielded(node: t.Expression | t.SpreadElement): boolean {
  // Default
  if (t.isYieldExpression(node)) {
    return true;
  }
  if (t.isTemplateLiteral(node)) {
    return node.expressions.some(
      expr => t.isExpression(expr) && isYielded(expr),
    );
  }
  if (
    t.isLiteral(node) ||
    t.isIdentifier(node) ||
    t.isArrowFunctionExpression(node) ||
    t.isFunctionExpression(node) ||
    t.isClassExpression(node) ||
    t.isYieldExpression(node) ||
    t.isJSX(node) ||
    t.isMetaProperty(node) ||
    t.isSuper(node) ||
    t.isThisExpression(node) ||
    t.isImport(node) ||
    t.isDoExpression(node)
  ) {
    return false;
  }
  if (t.isTaggedTemplateExpression(node)) {
    return isYielded(node.tag) || isYielded(node.quasi);
  }
  if (
    t.isUnaryExpression(node) ||
    t.isUpdateExpression(node) ||
    t.isSpreadElement(node)
  ) {
    return isYielded(node.argument);
  }
  if (
    t.isParenthesizedExpression(node) ||
    t.isTypeCastExpression(node) ||
    t.isTSAsExpression(node) ||
    t.isTSSatisfiesExpression(node) ||
    t.isTSNonNullExpression(node) ||
    t.isTSTypeAssertion(node) ||
    t.isTSInstantiationExpression(node)
  ) {
    return isYielded(node.expression);
  }
  // Check for elements
  if (t.isArrayExpression(node) || t.isTupleExpression(node)) {
    return node.elements.some(el => el != null && isYielded(el));
  }
  // Skip arrow function
  if (t.isAssignmentExpression(node)) {
    if (isYielded(node.right)) {
      return true;
    }
    if (t.isExpression(node.left)) {
      return isYielded(node.left);
    }
    return false;
  }
  if (t.isBinaryExpression(node)) {
    if (t.isExpression(node.left) && isYielded(node.left)) {
      return true;
    }
    return isYielded(node.right);
  }
  if (
    t.isCallExpression(node) ||
    t.isOptionalCallExpression(node) ||
    t.isNewExpression(node)
  ) {
    if (t.isExpression(node.callee) && isYielded(node.callee)) {
      return true;
    }
    return node.arguments.some(
      arg =>
        arg &&
        (t.isSpreadElement(arg) || t.isExpression(arg)) &&
        isYielded(arg),
    );
  }
  if (t.isConditionalExpression(node)) {
    return (
      isYielded(node.test) ||
      isYielded(node.consequent) ||
      isYielded(node.alternate)
    );
  }
  if (t.isLogicalExpression(node)) {
    return isYielded(node.left) || isYielded(node.right);
  }
  if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
    return (
      isYielded(node.object) ||
      (node.computed &&
        t.isExpression(node.property) &&
        isYielded(node.property))
    );
  }
  if (t.isSequenceExpression(node)) {
    return node.expressions.some(isYielded);
  }
  if (t.isObjectExpression(node) || t.isRecordExpression(node)) {
    return node.properties.some(prop => {
      if (t.isObjectProperty(prop)) {
        if (t.isExpression(prop.value) && isYielded(prop.value)) {
          return true;
        }
        if (prop.computed && t.isExpression(prop.key) && isYielded(prop.key)) {
          return true;
        }
        return false;
      }
      if (t.isSpreadElement(prop)) {
        return isYielded(prop);
      }
      return false;
    });
  }
  if (t.isBindExpression(node)) {
    return isYielded(node.object) || isYielded(node.callee);
  }
  return false;
}


================================================
FILE: packages/core/babel/core/memo-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { accessorVariable } from './accessor-variable';
import { getImportIdentifier } from './get-import-identifier';
import type { State } from './types';
import { UNDEFINED } from '../constants';

export function memoVariable(
  state: State,
  path: babel.NodePath,
  memoIdentifier: t.Identifier,
  stateIdentifier: t.Expression,
  optionsIdentifier?: t.Expression,
): t.VariableDeclarator {
  const normalIdentifier =
    t.isArrowFunctionExpression(stateIdentifier) ||
    t.isFunctionExpression(stateIdentifier)
      ? stateIdentifier
      : t.arrowFunctionExpression([], stateIdentifier);

  const exprs: t.Expression[] = [normalIdentifier];

  if (state.opts.dev) {
    exprs.push(UNDEFINED);
    if (optionsIdentifier) {
      exprs.push(
        t.callExpression(
          t.memberExpression(t.identifier('Object'), t.identifier('assign')),
          [
            t.objectExpression([
              t.objectProperty(
                t.identifier('name'),
                t.stringLiteral(memoIdentifier.name),
              ),
            ]),
            optionsIdentifier,
          ],
        ),
      );
    } else {
      exprs.push(
        t.objectExpression([
          t.objectProperty(
            t.identifier('name'),
            t.stringLiteral(memoIdentifier.name),
          ),
        ]),
      );
    }
  } else if (optionsIdentifier) {
    exprs.push(UNDEFINED);
    exprs.push(optionsIdentifier);
  }

  return accessorVariable(
    path,
    memoIdentifier,
    getImportIdentifier(state, path, 'createMemo', 'solid-js'),
    exprs,
  );
}


================================================
FILE: packages/core/babel/core/proto.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { generateUniqueName } from './generate-unique-name';

interface ProtoObjectState {
  root: t.ObjectExpression;
  proto: t.ObjectExpression;
}

const ROOT_GET = 'get';
const ROOT_SET = 'set';
const ROOT_SYMBOL = '__$';

const PROTO_STATES = new WeakMap<t.Node, ProtoObjectState>();

function getProtoState(
  path: babel.NodePath<t.ObjectExpression>,
): ProtoObjectState {
  const current = PROTO_STATES.get(path.node);
  if (current) {
    return current;
  }
  const protoID = generateUniqueName(path, 'proto');
  const proto = t.objectExpression([]);
  path.scope.getProgramParent().push({
    id: protoID,
    init: proto,
    kind: 'const',
  });
  path.node.properties.push(
    t.objectProperty(t.identifier('__proto__'), protoID),
  );
  const state: ProtoObjectState = {
    proto,
    root: path.node,
  };
  PROTO_STATES.set(path.node, state);
  return state;
}

function getGetterReplacement(
  key: t.Expression,
  source: t.Expression,
  computed: boolean,
): t.ObjectMethod {
  return t.objectMethod(
    'get',
    key,
    [],
    t.blockStatement([t.returnStatement(t.callExpression(source, []))]),
    computed,
  );
}

function getSetterReplacement(
  path: babel.NodePath,
  key: t.Expression,
  source: t.Expression,
  computed: boolean,
): t.ObjectMethod {
  const param = generateUniqueName(path, 'param');
  return t.objectMethod(
    'set',
    key,
    [param],
    t.blockStatement([
      t.expressionStatement(
        t.callExpression(source, [t.arrowFunctionExpression([], param)]),
      ),
    ]),
    computed,
  );
}

function getNamespacedKey(
  name: string,
  identifier: t.Expression,
): t.Expression | undefined {
  switch (identifier.type) {
    case 'StringLiteral':
    case 'NumericLiteral':
      return t.stringLiteral(`${ROOT_SYMBOL}${name}__${identifier.value}`);
    case 'Identifier':
      return t.identifier(`${ROOT_SYMBOL}${name}__${identifier.name}`);
    case 'NullLiteral':
      return t.identifier(`${ROOT_SYMBOL}${name}__null`);
    default:
      return undefined;
  }
}

function initProtoGetters(
  path: babel.NodePath<t.ObjectExpression>,
  identifier: t.Expression,
  source: t.Identifier,
): void {
  const current = getProtoState(path);
  const key = getNamespacedKey(ROOT_GET, identifier);
  if (key) {
    current.root.properties.push(t.objectProperty(key, source));
  }
}

function registerProtoGetter(
  path: babel.NodePath<t.ObjectExpression>,
  identifier: t.Expression,
): void {
  const current = getProtoState(path);
  const key = getNamespacedKey(ROOT_GET, identifier);
  if (key) {
    const targetProperty = t.memberExpression(
      t.identifier('this'),
      key,
      !t.isIdentifier(key),
    );
    current.proto.properties.push(
      getGetterReplacement(identifier, targetProperty, false),
    );
  }
}

function addUnoptimizedGetter(
  property: babel.NodePath<t.ObjectProperty>,
  key: t.Expression,
  source: t.Identifier,
): void {
  property.replaceWith(
    getGetterReplacement(key, source, property.node.computed),
  );
}

export function addProtoGetter(
  path: babel.NodePath<t.ObjectExpression>,
  property: babel.NodePath<t.ObjectProperty>,
  identifier: t.Expression,
  source: t.Identifier,
): void {
  if (property.node.computed) {
    addUnoptimizedGetter(property, identifier, source);
  } else {
    initProtoGetters(path, identifier, source);
    registerProtoGetter(path, identifier);
    property.remove();
  }
}

function initProtoSetters(
  path: babel.NodePath<t.ObjectExpression>,
  identifier: t.Expression,
  source: t.Identifier,
): void {
  const current = getProtoState(path);
  const key = getNamespacedKey(ROOT_SET, identifier);
  if (key) {
    current.root.properties.push(t.objectProperty(key, source));
  }
}

function registerProtoSetter(
  path: babel.NodePath<t.ObjectExpression>,
  identifier: t.Expression,
): void {
  const current = getProtoState(path);
  const key = getNamespacedKey(ROOT_SET, identifier);
  if (key) {
    const targetProperty = t.memberExpression(
      t.identifier('this'),
      key,
      !t.isIdentifier(key),
    );
    current.proto.properties.push(
      getSetterReplacement(path, identifier, targetProperty, false),
    );
  }
}

function addUnoptimizedSetter(
  property: babel.NodePath<t.ObjectProperty>,
  key: t.Expression,
  source: t.Identifier,
): void {
  property.replaceWith(
    getSetterReplacement(property, key, source, property.node.computed),
  );
}

export function addProtoSetter(
  path: babel.NodePath<t.ObjectExpression>,
  property: babel.NodePath<t.ObjectProperty>,
  identifier: t.Expression,
  source: t.Identifier,
): void {
  if (property.node.computed) {
    addUnoptimizedSetter(property, identifier, source);
  } else {
    initProtoSetters(path, identifier, source);
    registerProtoSetter(path, identifier);
    property.remove();
  }
}

function addUnoptimizedProperty(
  property: babel.NodePath<t.ObjectProperty>,
  key: t.PrivateName | t.Expression,
  readSource: t.Identifier,
  writeSource: t.Identifier,
): void {
  if (!t.isPrivateName(key)) {
    const tmp = generateUniqueName(property, 'tmp');
    property.scope.push({ id: tmp, kind: 'let' });
    const isComputed = property.node.computed;
    property.replaceWithMultiple([
      getGetterReplacement(
        isComputed ? t.assignmentExpression('=', tmp, key) : key,
        readSource,
        isComputed,
      ),
      getSetterReplacement(property, tmp, writeSource, isComputed),
    ]);
  }
}

export function addProtoProperty(
  path: babel.NodePath<t.ObjectExpression>,
  property: babel.NodePath<t.ObjectProperty>,
  identifier: t.Expression,
  readSource: t.Identifier,
  writeSource: t.Identifier,
): void {
  if (property.node.computed) {
    addUnoptimizedProperty(property, identifier, readSource, writeSource);
  } else {
    initProtoGetters(path, identifier, readSource);
    initProtoSetters(path, identifier, writeSource);
    registerProtoGetter(path, identifier);
    registerProtoSetter(path, identifier);
    property.remove();
  }
}


================================================
FILE: packages/core/babel/core/signal-variable.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { derefSignal } from './deref-signal';
import { generateUniqueName } from './generate-unique-name';
import { getImportIdentifier } from './get-import-identifier';
import type { State } from './types';

export function signalVariable(
  state: State,
  path: babel.NodePath,
  signalIdentifier: t.Identifier,
  stateIdentifier: t.Expression,
  optionsIdentifier?: t.Expression,
): t.VariableDeclarator {
  const readIdentifier = generateUniqueName(path, signalIdentifier.name);
  const writeIdentifier = generateUniqueName(
    path,
    `set${signalIdentifier.name}`,
  );

  const callee = getImportIdentifier(state, path, 'createSignal', 'solid-js');
  const args: t.Expression[] = [stateIdentifier];

  if (state.opts.dev) {
    const nameOption = t.objectExpression([
      t.objectProperty(
        t.identifier('name'),
        t.stringLiteral(signalIdentifier.name),
      ),
    ]);
    if (optionsIdentifier) {
      args.push(
        t.callExpression(
          t.memberExpression(t.identifier('Object'), t.identifier('assign')),
          [nameOption, optionsIdentifier],
        ),
      );
    } else {
      args.push(nameOption);
    }
  } else if (optionsIdentifier) {
    args.push(optionsIdentifier);
  }

  derefSignal(path, signalIdentifier, readIdentifier, writeIdentifier);

  return t.variableDeclarator(
    t.arrayPattern([readIdentifier, writeIdentifier]),
    t.callExpression(callee, args),
  );
}


================================================
FILE: packages/core/babel/core/types.ts
================================================
import type * as babel from '@babel/core';
import type * as t from '@babel/types';

export interface Options {
  dev?: boolean;
  disabled?: {
    ctf?: Record<string, boolean>;
    pragma?: Record<string, boolean>;
    label?: Record<string, boolean>;
  };
}

type ImportHook = Map<string, t.Identifier>;

export interface State extends babel.PluginPass {
  hooks: ImportHook;
  opts: Options;
}


================================================
FILE: packages/core/babel/core/unwrap-node.ts
================================================
import type { NodePath } from '@babel/traverse';
import type * as t from '@babel/types';

type TypeFilter<K extends t.Node> = (node: t.Node) => node is K;

type TypeCheck<K> = K extends TypeFilter<infer U> ? U : never;

type NestedExpression =
  | t.ParenthesizedExpression
  | t.TypeCastExpression
  | t.TSAsExpression
  | t.TSSatisfiesExpression
  | t.TSNonNullExpression
  | t.TSInstantiationExpression
  | t.TSTypeAssertion;

function isNestedExpression(node: t.Node): node is NestedExpression {
  switch (node.type) {
    case 'ParenthesizedExpression':
    case 'TypeCastExpression':
    case 'TSAsExpression':
    case 'TSSatisfiesExpression':
    case 'TSNonNullExpression':
    case 'TSTypeAssertion':
    case 'TSInstantiationExpression':
      return true;
    default:
      return false;
  }
}

export function isPathValid<V extends t.Node>(
  path: unknown,
  key: TypeFilter<V>,
): path is NodePath<V> {
  return key((path as NodePath).node);
}

export function unwrapNode<K extends (node: t.Node) => boolean>(
  node: t.Node,
  key: K,
): TypeCheck<K> | undefined {
  if (key(node)) {
    return node as TypeCheck<K>;
  }
  if (isNestedExpression(node)) {
    return unwrapNode(node.expression, key);
  }
  return undefined;
}

export function getProperParentPath<K extends (node: t.Node) => boolean>(
  path: NodePath,
  key: K,
): NodePath<TypeCheck<K>> | undefined {
  let parent = path.parentPath;

  while (parent) {
    if (isNestedExpression(parent.node)) {
      parent = parent.parentPath;
    } else if (key(parent.node)) {
      return parent as NodePath<TypeCheck<K>>;
    } else {
      return undefined;
    }
  }

  return undefined;
}


================================================
FILE: packages/core/babel/index.ts
================================================
import type * as babel from '@babel/core';
import { transformComponents } from './components';
import type { Options, State } from './core/types';
import { transformComments } from './transform-comment';
import { transformCTF } from './transform-ctf';
import { transformLabels } from './transform-label';

export type { Options };

export default function solidLabelsPlugin(): babel.PluginObj<State> {
  return {
    name: 'solid-labels',
    pre(): void {
      this.hooks = new Map();
    },
    visitor: {
      Program(path, state): void {
        transformComments(state, path);
        transformLabels(state, path);
        transformCTF(state, path);
        transformComponents(state, path);
      },
    },
  };
}


================================================
FILE: packages/core/babel/transform-comment.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { accessorVariable } from './core/accessor-variable';
import { deferredVariable } from './core/deferred-variable';
import { destructureVariable } from './core/destructure-variable';
import { getImportIdentifier } from './core/get-import-identifier';
import { memoVariable } from './core/memo-variable';
import { signalVariable } from './core/signal-variable';
import type { State } from './core/types';
import { UNDEFINED } from './constants';

const VARIABLE_LABEL = {
  '@signal': true,
  '@memo': true,
  '@deferred': true,
  '@destructure': true,
  '@children': true,
};

type CallbackLabel = [name: string, source: string, named: boolean];

const CALLBACK_LABEL: Record<string, CallbackLabel> = {
  '@effect': ['createEffect', 'solid-js', true],
  '@computed': ['createComputed', 'solid-js', true],
  '@renderEffect': ['createRenderEffect', 'solid-js', true],
  '@mount': ['onMount', 'solid-js', false],
  '@cleanup': ['onCleanup', 'solid-js', false],
  '@error': ['onError', 'solid-js', false],
  '@root': ['createRoot', 'solid-js', false],
  '@untrack': ['untrack', 'solid-js', false],
  '@batch': ['untrack', 'solid-js', false],
  '@transition': ['startTransition', 'solid-js', false],
};

function getVariableLabelPreference(
  state: State,
  comments: t.Comment[],
): string | undefined {
  let preference: string | undefined;
  for (let i = 0, len = comments.length; i < len; i++) {
    const comment = comments[i];
    const value: string = comment.value.trim();
    if (value in VARIABLE_LABEL && !state.opts.disabled?.pragma?.[value]) {
      preference = value;
      comment.value = '';
    }
  }
  return preference;
}

const LABEL_PATTERN = /^@\w+( .*)?$/;

function getCallbackLabelPreference(state: State, comments: t.Comment[]) {
  let preference: string | undefined;
  let nameOption: string | undefined;
  for (let i = 0, len = comments.length; i < len; i++) {
    const comment = comments[i];
    const value: string = comment.value.trim();
    if (LABEL_PATTERN.test(value)) {
      const [tag, ...debugName] = value.split(' ');
      if (tag in CALLBACK_LABEL && !state.opts.disabled?.pragma?.[value]) {
        preference = tag;
        nameOption = debugName.join(' ');
        comment.value = '';
      }
    }
  }
  return [preference, nameOption];
}

const COMMENT_TRAVERSE: babel.Visitor<State> = {
  VariableDeclaration(path, state) {
    const comments = path.node.leadingComments;
    if (comments) {
      const preference = getVariableLabelPreference(state, comments);
      if (preference) {
        const { declarations } = path.node;
        let declarators: t.VariableDeclarator[] = [];
        for (let i = 0, len = declarations.length; i < len; i++) {
          const declarator = declarations[i];
          switch (preference as keyof typeof VARIABLE_LABEL) {
            case '@signal':
              if (t.isIdentifier(declarator.id)) {
                declarators.push(
                  signalVariable(
                    state,
                    path,
                    declarator.id,
                    declarator.init ?? UNDEFINED,
                  ),
                );
              }
              break;
            case '@memo':
              if (t.isIdentifier(declarator.id)) {
                declarators.push(
                  memoVariable(
                    state,
                    path,
                    declarator.id,
                    declarator.init ?? UNDEFINED,
                  ),
                );
              }
              break;
            case '@deferred':
              if (t.isIdentifier(declarator.id)) {
                declarators.push(
                  deferredVariable(
                    state,
                    path,
                    declarator.id,
                    declarator.init ?? UNDEFINED,
                  ),
                );
              }
              break;
            case '@destructure':
              if (
                (t.isObjectPattern(declarator.id) ||
                  t.isArrayPattern(declarator.id)) &&
                declarator.init
              ) {
                declarators = [
                  ...declarators,
                  ...destructureVariable(
                    state,
                    path,
                    declarator.init,
                    declarator.id,
                  ),
                ];
              }
              break;
            case '@children':
              if (t.isIdentifier(declarator.id)) {
                declarators.push(
                  accessorVariable(
                    path,
                    declarator.id,
                    getImportIdentifier(state, path, 'children', 'solid-js'),
                    [
                      t.arrowFunctionExpression(
                        [],
                        declarator.init ?? UNDEFINED,
                      ),
                    ],
                  ),
                );
              }
              break;
            default:
              break;
          }
        }

        path.replaceWith(t.variableDeclaration('const', declarators));
      }
    }
  },
  BlockStatement(path, state) {
    if (!t.isBlockStatement(path.parent)) {
      return;
    }
    const comments = path.node.leadingComments;
    if (comments) {
      const [preference, nameOption] = getCallbackLabelPreference(
        state,
        comments,
      );
      if (preference) {
        const [name, source, named] = CALLBACK_LABEL[preference];
        const callback = t.arrowFunctionExpression([], path.node);
        const args: t.Expression[] = [callback];
        if (named && nameOption) {
          args.push(
            t.unaryExpression('void', t.numericLiteral(0)),
            t.objectExpression([
              t.objectProperty(
                t.identifier('name'),
                t.stringLiteral(nameOption),
              ),
            ]),
          );
        }
        path.replaceWith(
          t.callExpression(
            getImportIdentifier(state, path, name, source),
            args,
          ),
        );
      }
    }
  },
  ExpressionStatement(path, state) {
    const comments = path.node.leadingComments;
    if (comments) {
      const [preference, nameOption] = getCallbackLabelPreference(
        state,
        comments,
      );
      if (preference) {
        const [name, source, named] = CALLBACK_LABEL[preference];
        const callback = t.arrowFunctionExpression([], path.node.expression);
        const args: t.Expression[] = [callback];
        if (named && nameOption) {
          args.push(
            UNDEFINED,
            t.objectExpression([
              t.objectProperty(
                t.identifier('name'),
                t.stringLiteral(nameOption),
              ),
            ]),
          );
        }
        path.replaceWith(
          t.callExpression(
            getImportIdentifier(state, path, name, source),
            args,
          ),
        );
      }
    }
  },
};

export function transformComments(state: State, path: babel.NodePath): void {
  path.traverse(COMMENT_TRAVERSE, state);
}


================================================
FILE: packages/core/babel/transform-ctf.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { accessorVariable } from './core/accessor-variable';
import { assert } from './core/assert';
import { deferredVariable } from './core/deferred-variable';
import { derefMemoVariable } from './core/deref-memo-variable';
import { derefSignalVariable } from './core/deref-signal-variable';
import { destructureVariable } from './core/destructure-variable';
import { unexpectedArgumentLength, unexpectedType } from './core/errors';
import { generateUniqueName } from './core/generate-unique-name';
import { getImportIdentifier } from './core/get-import-identifier';
import { memoVariable } from './core/memo-variable';
import { signalVariable } from './core/signal-variable';
import type { State } from './core/types';
import { unwrapNode } from './core/unwrap-node';
import { UNDEFINED } from './constants';

type AutoArrowCTF = [name: string, source: string, arguments: number];

const AUTO_ARROW_CTF: Record<string, AutoArrowCTF> = {
  $lazy: ['lazy', 'solid-js', 1],
  $untrack: ['untrack', 'solid-js', 1],
  $batch: ['batch', 'solid-js', 1],
  $observable: ['observable', 'solid-js', 1],
  $selector: ['createSelector', 'solid-js', 1],
  $on: ['on', 'solid-js', 3],
};

type AutoImportAliasCTF = [name: string, source: string];

const AUTO_IMPORT_ALIAS_CTF: Record<string, AutoImportAliasCTF> = {
  $root: ['createRoot', 'solid-js'],
  $useContext: ['useContext', 'solid-js'],
  $createContext: ['createContext', 'solid-js'],
  $uid: ['createUniqueId', 'solid-js'],
  $effect: ['createEffect', 'solid-js'],
  $computed: ['createComputed', 'solid-js'],
  $renderEffect: ['createRenderEffect', 'solid-js'],
  $merge: ['mergeProps', 'solid-js'],
  $resource: ['createResource', 'solid-js'],
  $cleanup: ['onCleanup', 'solid-js'],
  $mount: ['onMount', 'solid-js'],
  $error: ['onError', 'solid-js'],
  $reaction: ['createReaction', 'solid-js'],
  $startTransition: ['startTransition', 'solid-js'],
  $useTransition: ['useTransition', 'solid-js'],
  $owner: ['getOwner', 'solid-js'],
  $runWithOwner: ['runWithOwner', 'solid-js'],
  $catchError: ['catchError', 'solid-js'],

  // Store API
  $store: ['createStore', 'solid-js/store'],
  $mutable: ['createMutable', 'solid-js/store'],
  $produce: ['produce', 'solid-js/store'],
  $reconcile: ['reconcile', 'solid-js/store'],
  $unwrap: ['unwrap', 'solid-js/store'],
};

type AutoAccessorCTF = [
  name: string,
  source: string,
  args: number,
  arrow: boolean,
];

const AUTO_ACCESSOR_CTF: Record<string, AutoAccessorCTF> = {
  $from: ['from', 'solid-js', 1, true],
  $children: ['children', 'solid-js', 1, false],
  $mapArray: ['mapArray', 'solid-js', 3, false],
  $indexArray: ['indexArray', 'solid-js', 3, false],
};

const SIGNAL_CTF = '$signal';
const MEMO_CTF = '$memo';
const DEREF_SIGNAL_CTF = '$derefSignal';
const DEREF_MEMO_CTF = '$derefMemo';
const REACTIVE_CTF = '$';
const DEFERRED_CTF = '$deferred';
const DESTRUCTURE_CTF = '$destructure';
const COMPONENT_CTF = '$component';

const SPECIAL_CTF = new Set([
  SIGNAL_CTF,
  MEMO_CTF,
  DEREF_SIGNAL_CTF,
  DEREF_MEMO_CTF,
  REACTIVE_CTF,
  DEFERRED_CTF,
  DESTRUCTURE_CTF,
  COMPONENT_CTF,
]);

const CTF_TRAVERSE: babel.Visitor<State> = {
  CallExpression(path, state) {
    const trueIdentifier = unwrapNode(path.node.callee, t.isIdentifier);
    if (
      trueIdentifier &&
      !path.scope.hasBinding(trueIdentifier.name) &&
      !state.opts.disabled?.ctf?.[trueIdentifier.name]
    ) {
      // Transform Auto Arrow CTFs
      if (trueIdentifier.name in AUTO_ARROW_CTF) {
        const [name, source, limit] = AUTO_ARROW_CTF[trueIdentifier.name];
        const args = path.node.arguments;
        assert(
          args.length <= limit,
          unexpectedArgumentLength(path, args.length, limit),
        );
        const [argument, ...rest] = args;
        assert(
          t.isExpression(argument),
          unexpectedType(path, argument.type, 'Expression'),
        );
        path.replaceWith(
          t.callExpression(getImportIdentifier(state, path, name, source), [
            t.isArrowFunctionExpression(argument) ||
            t.isFunctionExpression(argument)
              ? argument
              : t.arrowFunctionExpression([], argument),
            ...rest,
          ]),
        );
      }
      if (trueIdentifier.name === COMPONENT_CTF) {
        const args = path.node.arguments;
        assert(
          args.length === 1,
          unexpectedArgumentLength(path, args.length, 1),
        );
        const argument = args[0];
        assert(
          t.isFunctionExpression(argument) ||
            t.isArrowFunctionExpression(argument),
          unexpectedType(
            path,
            argument.type,
            'FunctionExpression | ArrowFunctionExpression',
          ),
        );
        if (argument.params.length > 0) {
          const params = argument.params[0];
          if (t.isObjectPattern(params)) {
            // Generate uid for props
            const props = generateUniqueName(path, 'props');
            // Replace params with props
            argument.params[0] = props;
            const declaration = t.variableDeclaration('const', [
              t.variableDeclarator(
                params,
                t.callExpression(t.identifier('$destructure'), [props]),
              ),
            ]);
            if (t.isExpression(argument.body)) {
              argument.body = t.blockStatement([
                declaration,
                t.returnStatement(argument.body),
              ]);
            } else {
              argument.body.body.unshift(declaration);
            }
          }
        }
        path.replaceWith(argument);
      }
    }
  },
  Expression(path, state) {
    if (t.isIdentifier(path.node) && !path.scope.hasBinding(path.node.name)) {
      if (
        path.node.name in AUTO_IMPORT_ALIAS_CTF &&
        !state.opts.disabled?.ctf?.[path.node.name]
      ) {
        const [name, source] = AUTO_IMPORT_ALIAS_CTF[path.node.name];
        path.replaceWith(getImportIdentifier(state, path, name, source));
      }
    }
  },
  VariableDeclarator(path, state) {
    const { id, init } = path.node;
    if (init) {
      const trueCallExpr = unwrapNode(init, t.isCallExpression);
      if (trueCallExpr) {
        const trueCallee = unwrapNode(trueCallExpr.callee, t.isIdentifier);
        if (
          trueCallee &&
          !path.scope.hasBinding(trueCallee.name) &&
          (SPECIAL_CTF.has(trueCallee.name) ||
            trueCallee.name in AUTO_ACCESSOR_CTF) &&
          !state.opts.disabled?.ctf?.[trueCallee.name]
        ) {
          if (t.isIdentifier(id)) {
            // Transform CTFs with auto-accessor
            if (trueCallee.name in AUTO_ACCESSOR_CTF) {
              const [name, source, limit, arrow] =
                AUTO_ACCESSOR_CTF[trueCallee.name];
              const args = trueCallExpr.arguments;
              assert(
                args.length <= limit,
                unexpectedArgumentLength(path, args.length, limit),
              );
              const [argument, ...rest] = args;
              assert(
                t.isExpression(argument),
                unexpectedType(path, argument.type, 'Expression'),
              );
              path.replaceWith(
                accessorVariable(
                  path,
                  id,
                  getImportIdentifier(state, path, name, source),
                  [
                    arrow ? t.arrowFunctionExpression([], argument) : argument,
                    ...rest,
                  ],
                ),
              );
            } else if (trueCallee.name === SIGNAL_CTF) {
              // Transform $signal
              const args = trueCallExpr.arguments;
              assert(
                args.length <= 2,
                unexpectedArgumentLength(path, args.length, 2),
              );
              let argument: t.Expression | undefined;
              let options: t.Expression | undefined;
              if (trueCallExpr.arguments.length > 0) {
                const initialState = trueCallExpr.arguments[0];
                assert(
                  t.isExpression(initialState),
                  unexpectedType(path, initialState.type, 'Expression'),
                );
                argument = initialState;
                if (trueCallExpr.arguments.length > 1) {
                  const optionsValue = trueCallExpr.arguments[1];
                  assert(
                    t.isExpression(optionsValue),
                    unexpectedType(path, optionsValue.type, 'Expression'),
                  );
                  options = optionsValue;
                }
              }
              path.replaceWith(
                signalVariable(state, path, id, argument || UNDEFINED, options),
              );
            } else if (
              trueCallee.name === MEMO_CTF ||
              trueCallee.name === REACTIVE_CTF
            ) {
              // Transform $memo
              const args = trueCallExpr.arguments;
              assert(
                args.length <= 2,
                unexpectedArgumentLength(path, args.length, 2),
              );
              const argument = args[0];
              assert(
                t.isExpression(argument),
                unexpectedType(path, argument.type, 'Expression'),
              );
              let options: t.Expression | undefined;
              if (args.length > 1) {
                const optionsValue = args[1];
                assert(
                  t.isExpression(optionsValue),
                  unexpectedType(path, optionsValue.type, 'Expression'),
                );
                options = optionsValue;
              }
              path.replaceWith(
                memoVariable(state, path, id, argument, options),
              );
            } else if (trueCallee.name === DEREF_SIGNAL_CTF) {
              // Transform $derefSignal
              const args = trueCallExpr.arguments;
              assert(
                args.length === 1,
                unexpectedArgumentLength(path, args.length, 1),
              );
              const argument = args[0];
              assert(
                t.isExpression(argument),
                unexpectedType(path, argument.type, 'Expression'),
              );
              path.replaceWith(derefSignalVariable(path, id, argument));
            } else if (trueCallee.name === DEREF_MEMO_CTF) {
              // Transform $derefMemo
              const args = trueCallExpr.arguments;
              assert(
                args.length === 1,
                unexpectedArgumentLength(path, args.length, 1),
              );
              const argument = args[0];
              assert(
                t.isExpression(argument),
                unexpectedType(path, argument.type, 'Expression'),
              );
              path.replaceWith(derefMemoVariable(path, id, argument));
            } else if (trueCallee.name === DEFERRED_CTF) {
              // Transform $deferred
              const args = trueCallExpr.arguments;
              assert(
                args.length <= 2,
                unexpectedArgumentLength(path, args.length, 2),
              );
              let argument: t.Expression | undefined;
              let options: t.Expression | undefined;
              if (args.length > 0) {
                const initialState = args[0];
                assert(
                  t.isExpression(initialState),
                  unexpectedType(path, initialState.type, 'Expression'),
                );
                argument = initialState;
                if (args.length > 1) {
                  const optionsValue = args[1];
                  assert(
                    t.isExpression(optionsValue),
                    unexpectedType(path, optionsValue.type, 'Expression'),
                  );
                  options = optionsValue;
                }
              }
              path.replaceWith(
                deferredVariable(state, path, id, argument, options),
              );
            }
          } else if (trueCallee.name === DESTRUCTURE_CTF) {
            const args = trueCallExpr.arguments;
            assert(
              args.length === 1,
              unexpectedArgumentLength(path, args.length, 1),
            );
            const argument = args[0];
            assert(
              t.isExpression(argument),
              unexpectedType(path, argument.type, 'Expression'),
            );
            assert(
              t.isObjectPattern(id) || t.isArrayPattern(id),
              unexpectedType(path, id.type, 'ArrayPattern | ObjectPattern'),
            );
            path.replaceWithMultiple(
              destructureVariable(state, path, argument, id),
            );
          }
          path.scope.crawl();
        }
      }
    }
  },
  ExpressionStatement(path, state) {
    const trueCallExpr = unwrapNode(path.node.expression, t.isCallExpression);
    if (trueCallExpr) {
      const trueCallee = unwrapNode(trueCallExpr.callee, t.isIdentifier);
      if (
        trueCallee &&
        !path.scope.hasBinding(trueCallee.name) &&
        !state.opts.disabled?.ctf?.[trueCallee.name]
      ) {
        // Transform $
        if (trueCallee.name === REACTIVE_CTF) {
          const args = trueCallExpr.arguments;
          assert(
            args.length === 1,
            unexpectedArgumentLength(path, args.length, 1),
          );
          const argument = args[0];
          assert(
            t.isExpression(argument),
            unexpectedType(path, argument.type, 'Expression'),
          );
          path.replaceWith(
            t.expressionStatement(
              t.callExpression(
                getImportIdentifier(state, path, 'createEffect', 'solid-js'),
                [
                  t.isArrowFunctionExpression(argument) ||
                  t.isFunctionExpression(argument)
                    ? argument
                    : t.arrowFunctionExpression([], argument),
                ],
              ),
            ),
          );
        }
      }
    }
  },
};

export function transformCTF(state: State, path: babel.NodePath): void {
  path.traverse(CTF_TRAVERSE, state);
}


================================================
FILE: packages/core/babel/transform-label.ts
================================================
import type * as babel from '@babel/core';
import * as t from '@babel/types';
import { accessorVariable } from './core/accessor-variable';
import { assert } from './core/assert';
import { deferredVariable } from './core/deferred-variable';
import { destructureVariable } from './core/destructure-variable';
import { unexpectedType } from './core/errors';
import { getImportIdentifier } from './core/get-import-identifier';
import { memoVariable } from './core/memo-variable';
import { signalVariable } from './core/signal-variable';
import type { State } from './core/types';
import { UNDEFINED } from './constants';

const REACTIVE_LABEL = '$';

const SPECIAL_LABELS = new Set([REACTIVE_LABEL]);

const VARIABLE_LABEL = {
  signal: true,
  memo: true,
  deferred: true,
  destructure: true,
  children: true,
};

type CallbackLabel = [name: string, source: string, named: boolean];

const CALLBACK_LABEL: Record<string, CallbackLabel> = {
  effect: ['createEffect', 'solid-js', true],
  computed: ['createComputed', 'solid-js', true],
  renderEffect: ['createRenderEffect', 'solid-js', true],
  mount: ['onMount', 'solid-js', false],
  cleanup: ['onCleanup', 'solid-js', false],
  error: ['onError', 'solid-js', false],
  root: ['createRoot', 'solid-js', false],
  untrack: ['untrack', 'solid-js', false],
  batch: ['untrack', 'solid-js', false],
  transition: ['startTransition', 'solid-js', false],
};

function transformReactiveLabel(
  state: State,
  path: babel.NodePath,
  body: t.Statement,
): void {
  let target: t.Expression | t.BlockStatement;
  if (t.isExpressionStatement(body)) {
    target = body.expression;
  } else if (t.isBlockStatement(body)) {
    target = body;
  } else {
    throw unexpectedType(
      path,
      body.type,
      'ExpressionStatement | BlockStatement',
    );
  }
  path.replaceWith(
    t.callExpression(
      getImportIdentifier(state, path, 'createEffect', 'solid-js'),
      [t.arrowFunctionExpression([], target)],
    ),
  );
}

function transformDeclaratorFromVariableLabel(
  state: State,
  path: babel.NodePath,
  labelName: keyof typeof VARIABLE_LABEL,
  declarator: t.VariableDeclarator,
): t.VariableDeclarator[] {
  if (labelName === 'signal' && t.isIdentifier(declarator.id)) {
    return [
      signalVariable(state, path, declarator.id, declarator.init ?? UNDEFINED),
    ];
  }
  if (labelName === 'memo' && t.isIdentifier(declarator.id)) {
    return [
      memoVariable(state, path, declarator.id, declarator.init ?? UNDEFINED),
    ];
  }
  if (labelName === 'deferred' && t.isIdentifier(declarator.id)) {
    return [
      deferredVariable(
        state,
        path,
        declarator.id,
        declarator.init ?? UNDEFINED,
      ),
    ];
  }
  if (
    labelName === 'destructure' &&
    (t.isObjectPattern(declarator.id) || t.isArrayPattern(declarator.id)) &&
    declarator.init
  ) {
    return destructureVariable(state, path, declarator.init, declarator.id);
  }
  if (labelName === 'children' && t.isIdentifier(declarator.id)) {
    return [
      accessorVariable(
        path,
        declarator.id,
        getImportIdentifier(state, path, 'children', 'solid-js'),
        [t.arrowFunctionExpression([], declarator.init ?? UNDEFINED)],
      ),
    ];
  }
  return [];
}

function transformVariableLabel(
  state: State,
  path: babel.NodePath,
  labelName: keyof typeof VARIABLE_LABEL,
  body: t.Statement,
): void {
  assert(
    t.isVariableDeclaration(body),
    unexpectedType(path, path.node.type, 'VariableDeclaration'),
  );

  const declarators: t.VariableDeclarator[] = [];

  for (let i = 0, len = body.declarations.length; i < len; i++) {
    declarators.push.apply(
      declarators,
      transformDeclaratorFromVariableLabel(
        state,
        path,
        labelName,
        body.declarations[i],
      ),
    );
  }

  path.replaceWith(t.variableDeclaration('const', declarators));
}

function transformCallbackLabel(
  state: State,
  path: babel.NodePath,
  labelName: string,
  body: t.Statement,
): void {
  const [name, source, named] = CALLBACK_LABEL[labelName];
  let nameOption: string | undefined;
  let callback: t.Expression;
  let currentBody = body;
  if (named && t.isLabeledStatement(currentBody)) {
    nameOption = currentBody.label.name;
    currentBody = currentBody.body;
  }
  if (t.isBlockStatement(currentBody)) {
    callback = t.arrowFunctionExpression([], currentBody);
  } else if (t.isExpressionStatement(currentBody)) {
    callback = currentBody.expression;
  } else {
    throw unexpectedType(
      path,
      currentBody.type,
      'BlockStatement | ExpressionStatement',
    );
  }
  const args: t.Expression[] = [callback];
  if (named && nameOption) {
    args.push(
      UNDEFINED,
      t.objectExpression([
        t.objectProperty(t.identifier('name'), t.stringLiteral(nameOption)),
      ]),
    );
  }
  path.replaceWith(
    t.callExpression(getImportIdentifier(state, path, name, source), args),
  );
}

const LABEL_TRAVERSE: babel.Visitor<State> = {
  LabeledStatement(path, state) {
    const labelName = path.node.label.name;
    const { body } = path.node;
    if (
      (SPECIAL_LABELS.has(labelName) ||
        labelName in VARIABLE_LABEL ||
        labelName in CALLBACK_LABEL) &&
      !state.opts.disabled?.label?.[labelName]
    ) {
      if (labelName === REACTIVE_LABEL) {
        transformReactiveLabel(state, path, body);
      } else if (labelName in VARIABLE_LABEL) {
        transformVariableLabel(
          state,
          path,
          labelName as keyof typeof VARIABLE_LABEL,
          body,
        );
      } else if (labelName in CALLBACK_LABEL) {
        transformCallbackLabel(state, path, labelName, body);
      }
    }
  },
};

export function transformLabels(state: State, path: babel.NodePath): void {
  path.traverse(LABEL_TRAVERSE, state);
}


================================================
FILE: packages/core/example.js
================================================
import * as babel from '@babel/core';
import plugin from './dist/esm/development/babel.mjs';

async function compile(code, dev) {
  const result = await babel.transformAsync(code, {
    plugins: [[plugin, { dev }]],
    parserOpts: {
      plugins: ['jsx'],
    },
  });

  return result?.code ?? '';
}

console.log(
  await compile(`
let foo = $signal('foo');
let bar = $signal('bar')
let baz = $memo('baz');

const example = {
  foo: $property(foo),
  [baz]: $property(bar),
  baz: baz,
};

$(console.log(example.foo, example.bar));
`),
);


================================================
FILE: packages/core/package.json
================================================
{
  "version": "0.17.0",
  "type": "module",
  "exports": {
    ".": {
      "development": {
        "require": "./dist/cjs/development/index.cjs",
        "import": "./dist/esm/development/index.mjs"
      },
      "require": "./dist/cjs/production/index.cjs",
      "import": "./dist/esm/production/index.mjs",
      "types": "./dist/types/src/index.d.ts"
    },
    "./babel": {
      "development": {
        "require": "./dist/cjs/development/babel.cjs",
        "import": "./dist/esm/development/babel.mjs"
      },
      "require": "./dist/cjs/production/babel.cjs",
      "import": "./dist/esm/production/babel.mjs",
      "types": "./dist/types/babel/index.d.ts"
    }
  },
  "files": [
    "dist",
    "src"
  ],
  "engines": {
    "node": ">=10"
  },
  "license": "MIT",
  "keywords": [
    "pridepack",
    "babel",
    "solid-js",
    "labels",
    "reactivity"
  ],
  "name": "solid-labels",
  "devDependencies": {
    "@babel/core": "^7.26.9",
    "@types/babel__core": "^7.20.5",
    "@types/babel__traverse": "^7.20.6",
    "@types/node": "^22.13.4",
    "pridepack": "2.6.1",
    "solid-js": "^1.9.3",
    "tslib": "^2.8.1",
    "typescript": "^5.8.2",
    "vitest": "^3.0.6"
  },
  "peerDependencies": {
    "@babel/core": "^7.25",
    "solid-js": "^1.3"
  },
  "dependencies": {
    "@babel/traverse": "^7.26.9",
    "@babel/types": "^7.26.9"
  },
  "scripts": {
    "prepublish": "pridepack clean && pridepack build",
    "build": "pridepack build",
    "type-check": "pridepack check",
    "lint": "pridepack lint",
    "clean": "pridepack clean",
    "watch": "pridepack watch",
    "test": "vitest"
  },
  "description": "Simple, reactive labels for SolidJS",
  "repository": {
    "url": "https://github.com/lxsmnsyc/solid-labels.git",
    "type": "git"
  },
  "homepage": "https://github.com/lxsmnsyc/solid-labels/tree/main/packages/core",
  "bugs": {
    "url": "https://github.com/lxsmnsyc/solid-labels/issues"
  },
  "publishConfig": {
    "access": "public"
  },
  "author": "Alexis Munsayac",
  "private": false,
  "typesVersions": {
    "*": {
      "babel": [
        "./dist/types/babel/index.d.ts"
      ]
    }
  },
  "types": "./dist/types/src/index.d.ts",
  "main": "./dist/cjs/production/index.cjs",
  "module": "./dist/esm/production/index.mjs"
}


================================================
FILE: packages/core/pridepack.json
================================================
{
  "target": "es2018",
  "entrypoints": {
    ".": "src/index.ts",
    "./babel": "babel/index.ts"
  }
}


================================================
FILE: packages/core/src/index.ts
================================================
import type * as solid from 'solid-js';
import type * as solidStore from 'solid-js/store';
import type * as solidWeb from 'solid-js/web';

declare global {
  type Accessor<T> = solid.Accessor<T>;
  type Setter<T> = solid.Setter<T>;
  type Context<T> = solid.Context<T>;
  type ObservableObserver<T> = solid.ObservableObserver<T>;
  type Component<T extends Record<string, any> = {}> = solid.Component<T>;

  function $signal<T>(): T | undefined;
  function $signal<T>(
    value: T,
    options?: {
      equals?: false | ((prev: T, next: T) => boolean);
      name?: string;
      internal?: boolean;
    },
  ): T;

  function $memo<T>(
    value: T,
    options?: {
      equals?: false | ((prev: T, next: T) => boolean);
      name?: string;
    },
  ): T;
  function $memo<T>(
    value: T,
    options?: {
      equals?: false | ((prev: T, next: T) => boolean);
      name?: string;
    },
  ): T;

  function $untrack<T>(value: T): T;
  function $batch<T>(value: T): T;

  function $<T>(value: T): T;

  function $derefSignal<T>(value: [Accessor<T>, Setter<T>]): T;
  function $refSignal<T>(value: T): [Accessor<T>, Setter<T>];
  function $derefMemo<T>(value: Accessor<T>): T;
  function $refMemo<T>(value: T): Accessor<T>;

  function $get<T>(value: T): Accessor<T>;
  function $set<T>(value: T): Setter<T>;

  // Object property transforms
  function $getter<T>(value: T): T;
  function $setter<T>(value: T): T;
  function $property<T>(value: T): T;

  function $selector<T, U>(
    source: T,
    fn?: (a: U, b: T) => boolean,
    options?: { name?: string },
  ): (key: U) => boolean;

  function $on<T, U>(
    deps: T,
    fn: (input: T, prevInput: T, prevValue?: U) => U,
    options?: { defer?: boolean },
  ): (prevValue?: U) => U;

  function $deferred<T>(
    source: T,
    options?: {
      equals?: false | ((prev: T, next: T) => boolean);
      name?: string;
      timeoutMs?: number;
    },
  ): T;

  function $lazy<T extends Component<any>>(
    fn: Promise<{ default: T }>,
  ): T & {
    preload: () => void;
  };

  function $children(value: solid.JSX.Element): solid.JSX.Element;

  interface Observable<T> {
    subscribe(
      observer: ObservableObserver<T>,
    ): { unsubscribe(): void } | (() => void);
  }

  function $observable<T>(value: T): Observable<T>;
  function $from<T>(observable: Observable<T>): T;
  function $from<T>(produce: (setter: Setter<T>) => () => void): T;

  function $mapArray<T, U>(
    arr: readonly T[] | undefined | null | false,
    mapFn: (v: T, i: Accessor<number>) => U,
    options?: {
      fallback?: Accessor<any>;
    },
  ): U[];
  function $indexArray<T, U>(
    arr: readonly T[] | undefined | null | false,
    mapFn: (v: Accessor<T>, i: number) => U,
    options?: {
      fallback?: Accessor<any>;
    },
  ): U[];

  function $destructure<T>(value: T): T;

  // Auto imports

  const $effect: typeof solid.createEffect;
  const $computed: typeof solid.createComputed;
  const $renderEffect: typeof solid.createRenderEffect;

  const $useContext: typeof solid.useContext;
  const $createContext: typeof solid.createContext;

  const $uid: typeof solid.createUniqueId;
  const $root: typeof solid.createRoot;
  const $resource: typeof solid.createResource;
  const $merge: typeof solid.mergeProps;

  const $reaction: typeof solid.createReaction;
  const $mount: typeof solid.onMount;
  // @deprecated
  const $error: typeof solid.onError;
  const $cleanup: typeof solid.onCleanup;
  const $catchError: typeof solid.catchError;

  const $startTransition: typeof solid.startTransition;
  const $useTransition: typeof solid.useTransition;

  const $owner: typeof solid.getOwner;
  const $runWithOwner: typeof solid.runWithOwner;

  // store
  const $store: typeof solidStore.createStore;
  const $mutable: typeof solidStore.createMutable;
  const $produce: typeof solidStore.produce;
  const $reconcile: typeof solidStore.reconcile;
  const $unwrap: typeof solidStore.unwrap;

  // components
  const For: typeof solid.For;
  const Show: typeof solid.Show;
  const Switch: typeof solid.Switch;
  const Match: typeof solid.Match;
  const Index: typeof solid.Index;
  const ErrorBoundary: typeof solid.ErrorBoundary;
  const Suspense: typeof solid.Suspense;
  const SuspenseList: typeof solid.SuspenseList;
  const Dynamic: typeof solidWeb.Dynamic;
  const Portal: typeof solidWeb.Portal;
  const Assets: typeof solidWeb.Assets;
  const HydrationScript: typeof solidWeb.HydrationScript;
  const NoHydration: typeof solidWeb.NoHydration;

  function $component<P>(
    Comp: (props: P) => solid.JSX.Element,
  ): (props: P) => solid.JSX.Element;
}

type Props<T> = T extends (props: infer P) => solid.JSX.Element ? P : never;

declare module 'solid-js' {
  // biome-ignore lint/style/noNamespace: <explanation>
  namespace JSX {
    interface IntrinsicElements {
      'solid:error-boundary': Props<typeof ErrorBoundary>;
      'solid:suspense': Props<typeof Suspense>;
      'solid:suspense-list': Props<typeof SuspenseList>;
      'solid:portal': Props<typeof solidWeb.Portal>;
      'solid:assets': Props<typeof solidWeb.Assets>;
      'solid:hydration-script': Props<typeof solidWeb.HydrationScript>;
      'solid:no-hydration': Props<typeof solidWeb.NoHydration>;
    }
  }
}


================================================
FILE: packages/core/test/__snapshots__/ctf.test.ts.snap
================================================
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`ctf > $component > should transform $component 1`] = `
"import { splitProps as _splitProps } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
};"
`;

exports[`ctf > $component > should transform $component bindings 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log(prop_2(), prop_3());
  });
  _createEffect(() => {
    console.log(prop_5(), prop_6());
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $component > should transform $component bindings 2`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log({
      b: prop_2()
    }, {
      c: prop_3()
    });
  });
  _createEffect(() => {
    console.log({
      d: prop_5()
    }, {
      e: prop_6()
    });
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $component > should transform $component bindings on $get 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log(prop_2, prop_3);
  });
  _createEffect(() => {
    console.log(prop_5, prop_6);
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $component > should transform $component bindings on $getter 1`] = `
"const proto_1 = {
    get b() {
      return this.__$get__b();
    }
  },
  proto_2 = {
    get c() {
      return this.__$get__c();
    }
  },
  proto_3 = {
    get d() {
      return this.__$get__d();
    }
  },
  proto_4 = {
    get e() {
      return this.__$get__e();
    }
  };
import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log({
      __proto__: proto_1,
      __$get__b: prop_2
    }, {
      __proto__: proto_2,
      __$get__c: prop_3
    });
  });
  _createEffect(() => {
    console.log({
      __proto__: proto_3,
      __$get__d: prop_5
    }, {
      __proto__: proto_4,
      __$get__e: prop_6
    });
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $component > should transform $component bindings on $property 1`] = `
"const proto_1 = {
    get b() {
      return this.__$get__b();
    }
  },
  proto_2 = {
    get c() {
      return this.__$get__c();
    }
  },
  proto_3 = {
    get d() {
      return this.__$get__d();
    }
  },
  proto_4 = {
    get e() {
      return this.__$get__e();
    }
  };
import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log({
      __proto__: proto_1,
      __$get__b: prop_2
    }, {
      __proto__: proto_2,
      __$get__c: prop_3
    });
  });
  _createEffect(() => {
    console.log({
      __proto__: proto_3,
      __$get__d: prop_5
    }, {
      __proto__: proto_4,
      __$get__e: prop_6
    });
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $component > should transform $component bindings on $refMemo 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
props_1 => {
  const prop_1 = () => props_1.a,
    prop_2 = () => prop_1().b,
    prop_3 = () => prop_1().c,
    other_2 = _splitProps(prop_1(), ["b", "c"])[1],
    prop_4 = () => props_1.b,
    def_1 = defaultD,
    prop_5 = () => {
      const value_1 = prop_4().d;
      return value_1 === void 0 ? def_1 : value_1;
    },
    def_2 = defaultE,
    prop_6 = () => {
      const value_2 = prop_4().e;
      return value_2 === void 0 ? def_2 : value_2;
    },
    other_3 = _splitProps(prop_4(), ["d", "e"])[1],
    other_1 = _splitProps(props_1, ["a", "b"])[1];
  _createEffect(() => {
    console.log(prop_2, prop_3);
  });
  _createEffect(() => {
    console.log(prop_5, prop_6);
  });
  _createEffect(() => {
    console.log(other_1);
  });
};"
`;

exports[`ctf > $derefMemo > should transform $derefMemo 1`] = `"const message_1 = () => \`Count: \${count}\`;"`;

exports[`ctf > $derefMemo > should transform $derefMemo bindings 1`] = `
"const message_1 = () => \`Count: \${count}\`;
const value = message_1();"
`;

exports[`ctf > $derefMemo > should transform $derefMemo bindings 2`] = `
"const message_1 = () => \`Count: \${count}\`;
const value = {
  message: message_1()
};"
`;

exports[`ctf > $derefMemo > should transform $derefMemo on $get 1`] = `
"const message_1 = () => \`Count: \${count}\`;
const value = message_1;"
`;

exports[`ctf > $derefMemo > should transform $derefMemo on $getter 1`] = `
"const proto_1 = {
  get message() {
    return this.__$get__message();
  }
};
const message_1 = () => \`Count: \${count}\`;
const value = {
  __proto__: proto_1,
  __$get__message: message_1
};"
`;

exports[`ctf > $derefMemo > should transform $derefMemo on $property 1`] = `
"const proto_1 = {
  get message() {
    return this.__$get__message();
  }
};
const message_1 = () => \`Count: \${count}\`;
const value = {
  __proto__: proto_1,
  __$get__message: message_1
};"
`;

exports[`ctf > $derefMemo > should transform $derefMemo on $refMemo 1`] = `
"const message_1 = () => \`Count: \${count}\`;
const value = message_1;"
`;

exports[`ctf > $derefSignal > should transform $derefSignal 1`] = `"const [count_1, setcount_1] = createSignal(0);"`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings 1`] = `
"const [count_1, setcount_1] = createSignal(0);
const value = count_1();"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings 2`] = `
"const [count_1, setcount_1] = createSignal(0);
const value = {
  count: count_1()
};"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $get 1`] = `
"const [count_1, setcount_1] = createSignal(0);
const value = count_1;"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $getter 1`] = `
"const proto_1 = {
  get count() {
    return this.__$get__count();
  }
};
const [count_1, setcount_1] = createSignal(0);
const value = {
  __proto__: proto_1,
  __$get__count: setcount_1
};"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $property 1`] = `
"const proto_1 = {
  get count() {
    return this.__$get__count();
  },
  set count(param_1) {
    this.__$set__count(() => param_1);
  }
};
const [count_1, setcount_1] = createSignal(0);
const value = {
  __proto__: proto_1,
  __$get__count: count_1,
  __$set__count: setcount_1
};"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $refSignal 1`] = `
"const [count_1, setcount_1] = createSignal(0);
const value = [count_1, setcount_1];"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $set 1`] = `
"const [count_1, setcount_1] = createSignal(0);
const value = setcount_1;"
`;

exports[`ctf > $derefSignal > should transform $derefSignal bindings for $setter 1`] = `
"const proto_1 = {
  set count(param_1) {
    this.__$set__count(() => param_1);
  }
};
const [count_1, setcount_1] = createSignal(0);
const value = {
  __proto__: proto_1,
  __$set__count: setcount_1
};"
`;

exports[`ctf > $destructure > should transform $destructure 1`] = `
"import { splitProps as _splitProps } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];"
`;

exports[`ctf > $destructure > should transform $destructure bindings 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(prop_2(), prop_3());
});
_createEffect(() => {
  console.log(prop_5(), prop_6());
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $destructure > should transform $destructure bindings 2`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log({
    b: prop_2()
  }, {
    c: prop_3()
  });
});
_createEffect(() => {
  console.log({
    d: prop_5()
  }, {
    e: prop_6()
  });
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $destructure > should transform $destructure bindings on $get 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(prop_2, prop_3);
});
_createEffect(() => {
  console.log(prop_5, prop_6);
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $destructure > should transform $destructure bindings on $getter 1`] = `
"const proto_1 = {
    get b() {
      return this.__$get__b();
    }
  },
  proto_2 = {
    get c() {
      return this.__$get__c();
    }
  },
  proto_3 = {
    get d() {
      return this.__$get__d();
    }
  },
  proto_4 = {
    get e() {
      return this.__$get__e();
    }
  };
import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log({
    __proto__: proto_1,
    __$get__b: prop_2
  }, {
    __proto__: proto_2,
    __$get__c: prop_3
  });
});
_createEffect(() => {
  console.log({
    __proto__: proto_3,
    __$get__d: prop_5
  }, {
    __proto__: proto_4,
    __$get__e: prop_6
  });
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $destructure > should transform $destructure bindings on $property 1`] = `
"const proto_1 = {
    get b() {
      return this.__$get__b();
    }
  },
  proto_2 = {
    get c() {
      return this.__$get__c();
    }
  },
  proto_3 = {
    get d() {
      return this.__$get__d();
    }
  },
  proto_4 = {
    get e() {
      return this.__$get__e();
    }
  };
import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log({
    __proto__: proto_1,
    __$get__b: prop_2
  }, {
    __proto__: proto_2,
    __$get__c: prop_3
  });
});
_createEffect(() => {
  console.log({
    __proto__: proto_3,
    __$get__d: prop_5
  }, {
    __proto__: proto_4,
    __$get__e: prop_6
  });
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $destructure > should transform $destructure bindings on $refMemo 1`] = `
"import { splitProps as _splitProps } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
let prop_1 = () => x.a,
  prop_2 = () => prop_1().b,
  prop_3 = () => prop_1().c,
  other_2 = _splitProps(prop_1(), ["b", "c"])[1],
  prop_4 = () => x.b,
  def_1 = defaultD,
  prop_5 = () => {
    const value_1 = prop_4().d;
    return value_1 === void 0 ? def_1 : value_1;
  },
  def_2 = defaultE,
  prop_6 = () => {
    const value_2 = prop_4().e;
    return value_2 === void 0 ? def_2 : value_2;
  },
  other_3 = _splitProps(prop_4(), ["d", "e"])[1],
  other_1 = _splitProps(x, ["a", "b"])[1];
_createEffect(() => {
  console.log(prop_2, prop_3);
});
_createEffect(() => {
  console.log(prop_5, prop_6);
});
_createEffect(() => {
  console.log(other_1);
});"
`;

exports[`ctf > $effect, $renderEffect, $computed > should transform $effect, $renderEffect, $computed 1`] = `
"import { createRenderEffect as _createRenderEffect } from "solid-js";
import { createComputed as _createComputed } from "solid-js";
import { createEffect as _createEffect } from "solid-js";
import { createSignal as _createSignal } from "solid-js";
let [x_1, setx_1] = _createSignal(0);
_createEffect(() => {
  console.log('Count', x_1());
});
_createComputed(() => {
  console.log('Count', x_1());
});
_createRenderEffect(() => {
  console.log('Count', x_1());
});"
`;

exports[`ctf > $memo > should transform $memo 1`] = `
"import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);"
`;

exports[`ctf > $memo > should transform $memo bindings 1`] = `
"import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = message_1();"
`;

exports[`ctf > $memo > should transform $memo bindings 2`] = `
"import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = {
  message: message_1()
};"
`;

exports[`ctf > $memo > should transform $memo on $get 1`] = `
"import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = message_1;"
`;

exports[`ctf > $memo > should transform $memo on $getter 1`] = `
"const proto_1 = {
  get message() {
    return this.__$get__message();
  }
};
import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = {
  __proto__: proto_1,
  __$get__message: message_1
};"
`;

exports[`ctf > $memo > should transform $memo on $property 1`] = `
"const proto_1 = {
  get message() {
    return this.__$get__message();
  }
};
import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = {
  __proto__: proto_1,
  __$get__message: message_1
};"
`;

exports[`ctf > $memo > should transform $memo on $refMemo 1`] = `
"import { createMemo as _createMemo } from "solid-js";
const message_1 = _createMemo(() => \`Count: \${count}\`);
const value = message_1;"
`;

exports[`ctf > $signal > should transform $signal 1`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);"
`;

exports[`ctf > $signal > should transform $signal bindings 1`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = count_1();"
`;

exports[`ctf > $signal > should transform $signal bindings 2`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = {
  count: count_1()
};"
`;

exports[`ctf > $signal > should transform $signal bindings 3`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
async function exampleA() {
  const tmp_1 = await asyncValue();
  setcount_1(() => tmp_1);
}
function* exampleB() {
  const tmp_2 = yield asyncValue();
  setcount_1(() => tmp_2);
}
async function* exampleC() {
  const tmp_3 = yield asyncValue();
  setcount_1(() => tmp_3);
}
const example = async () => {
  const tmp_4 = await asyncValue();
  return setcount_1(() => tmp_4);
};"
`;

exports[`ctf > $signal > should transform $signal bindings for $get 1`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = count_1;"
`;

exports[`ctf > $signal > should transform $signal bindings for $getter 1`] = `
"const proto_1 = {
  get count() {
    return this.__$get__count();
  }
};
import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = {
  __proto__: proto_1,
  __$get__count: setcount_1
};"
`;

exports[`ctf > $signal > should transform $signal bindings for $property 1`] = `
"const proto_1 = {
  get count() {
    return this.__$get__count();
  },
  set count(param_1) {
    this.__$set__count(() => param_1);
  }
};
import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = {
  __proto__: proto_1,
  __$get__count: count_1,
  __$set__count: setcount_1
};"
`;

exports[`ctf > $signal > should transform $signal bindings for $refSignal 1`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = [count_1, setcount_1];"
`;

exports[`ctf > $signal > should transform $signal bindings for $set 1`] = `
"import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = setcount_1;"
`;

exports[`ctf > $signal > should transform $signal bindings for $setter 1`] = `
"const proto_1 = {
  set count(param_1) {
    this.__$set__count(() => param_1);
  }
};
import { createSignal as _createSignal } from "solid-js";
let [count_1, setcount_1] = _createSignal(0);
const value = {
  __proto__: proto_1,
  __$set__count: setcount_1
};"
`;

exports[`ctf > variable shadowing > should respect variable shadowing 1`] = `
"import { createSignal as _createSignal } from "solid-js";
const [selected_1, setselected_1] = _createSignal('root');
{
  const selected = 'local';
  console.log(selected); // 'local'
  {
    console.log(selected); // 'local'
    {
      const [selected_2, setselected_2] = _createSignal('inner');
      console.log(selected_2()); // 'inner'
      {
        console.log(selected_2()); // 'inner'
      }
    }
  }
}"
`;


================================================
FILE: packages/core/test/ctf.test.ts
================================================
import * as babel from '@babel/core';
import { describe, expect, it } from 'vitest';
import plugin from '../babel';

async function compile(code: string, dev?: boolean): Promise<string> {
  const result = await babel.transformAsync(code, {
    plugins: [[plugin, { dev }]],
    parserOpts: {
      plugins: ['jsx'],
    },
  });

  return result?.code ?? '';
}

describe('ctf', () => {
  describe('$signal', () => {
    it('should transform $signal', async () => {
      expect(await compile('let count = $signal(0);')).toMatchSnapshot();
    });
    it('should transform $signal bindings', async () => {
      let code = `
      let count = $signal(0);
      const value = count;
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      let count = $signal(0);
      const value = { count };
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      let count = $signal(0);

      async function exampleA() {
        count = await asyncValue();
      }
      function* exampleB() {
        count = yield asyncValue();
      }
      async function* exampleC() {
        count = yield asyncValue();
      }

      const example = async () => (count = await asyncValue());
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $set', async () => {
      const code = `
      let count = $signal(0);
      const value = $set(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $get', async () => {
      const code = `
      let count = $signal(0);
      const value = $get(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $refSignal', async () => {
      const code = `
      let count = $signal(0);
      const value = $refSignal(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $getter', async () => {
      const code = `
      let count = $signal(0);
      const value = { count: $getter(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $setter', async () => {
      const code = `
      let count = $signal(0);
      const value = { count: $setter(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $signal bindings for $property', async () => {
      const code = `
      let count = $signal(0);
      const value = { count: $property(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$memo', () => {
    it('should transform $memo', async () => {
      const code = 'const message = $memo(`Count: ${count}`);';
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $memo bindings', async () => {
      let code = `
      const message = $memo(\`Count: \${count}\`)
      const value = message;
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      const message = $memo(\`Count: \${count}\`)
      const value = { message };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $memo on $get', async () => {
      const code = `
      const message = $memo(\`Count: \${count}\`)
      const value = $get(message);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $memo on $refMemo', async () => {
      const code = `
      const message = $memo(\`Count: \${count}\`)
      const value = $refMemo(message);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $memo on $getter', async () => {
      const code = `
      const message = $memo(\`Count: \${count}\`)
      const value = { message: $getter(message) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $memo on $property', async () => {
      const code = `
      const message = $memo(\`Count: \${count}\`)
      const value = { message: $property(message) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$derefSignal', () => {
    it('should transform $derefSignal', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings', async () => {
      let code = `
      const count = $derefSignal(createSignal(0));
      const value = count;
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      const count = $derefSignal(createSignal(0));
      const value = { count };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $set', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = $set(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $get', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = $get(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $refSignal', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = $refSignal(count);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $getter', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = { count: $getter(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $setter', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = { count: $setter(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefSignal bindings for $property', async () => {
      const code = `
      const count = $derefSignal(createSignal(0));
      const value = { count: $property(count) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$derefMemo', () => {
    it('should transform $derefMemo', async () => {
      const code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefMemo bindings', async () => {
      let code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = message;
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = { message };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefMemo on $get', async () => {
      const code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = $get(message);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefMemo on $refMemo', async () => {
      const code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = $refMemo(message);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefMemo on $getter', async () => {
      const code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = { message: $getter(message) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $derefMemo on $property', async () => {
      const code = `
      const message = $derefMemo(() => \`Count: \${count}\`);
      const value = { message: $property(message) };
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$destructure', () => {
    it('should transform $destructure', async () => {
      const code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $destructure bindings', async () => {
      let code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log(b, c);
      }
      effect: {
        console.log(d, e);
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log({ b }, { c });
      }
      effect: {
        console.log({ d }, { e });
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $destructure bindings on $get', async () => {
      const code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log($get(b), $get(c));
      }
      effect: {
        console.log($get(d), $get(e));
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $destructure bindings on $refMemo', async () => {
      const code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log($refMemo(b), $refMemo(c));
      }
      effect: {
        console.log($refMemo(d), $refMemo(e));
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $destructure bindings on $getter', async () => {
      const code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log({ b: $getter(b) }, { c: $getter(c) });
      }
      effect: {
        console.log({ d: $getter(d) }, { e: $getter(e) });
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $destructure bindings on $property', async () => {
      const code = `
      let { a: { b, c }, b: { d = defaultD, e = defaultE }, ...f } = $destructure(x);

      effect: {
        console.log({ b: $property(b) }, { c: $property(c) });
      }
      effect: {
        console.log({ d: $property(d) }, { e: $property(e) });
      }
      effect: {
        console.log(f);
      }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$component', () => {
    it('should transform $component', async () => {
      const code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $component bindings', async () => {
      let code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
        effect: {
          console.log(b, c);
        }
        effect: {
          console.log(d, e);
        }
        effect: {
          console.log(f);
        }
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
      code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
        effect: {
          console.log({ b }, { c });
        }
        effect: {
          console.log({ d }, { e });
        }
        effect: {
          console.log(f);
        }
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $component bindings on $get', async () => {
      const code = `
        $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
          effect: {
            console.log($get(b), $get(c));
          }
          effect: {
            console.log($get(d), $get(e));
          }
          effect: {
            console.log(f);
          }
        });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $component bindings on $refMemo', async () => {
      const code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
        effect: {
          console.log($refMemo(b), $refMemo(c));
        }
        effect: {
          console.log($refMemo(d), $refMemo(e));
        }
        effect: {
          console.log(f);
        }
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $component bindings on $getter', async () => {
      const code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
        effect: {
          console.log({ b: $getter(b) }, { c: $getter(c) });
        }
        effect: {
          console.log({ d: $getter(d) }, { e: $getter(e) });
        }
        effect: {
          console.log(f);
        }
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
    it('should transform $component bindings on $property', async () => {
      const code = `
      $component(({ a: { b, c }, b: { d = defaultD, e = defaultE }, ...f }) => {
        effect: {
          console.log({ b: $property(b) }, { c: $property(c) });
        }
        effect: {
          console.log({ d: $property(d) }, { e: $property(e) });
        }
        effect: {
          console.log(f);
        }
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
  describe('$effect, $renderEffect, $computed', () => {
    it('should transform $effect, $renderEffect, $computed', async () => {
      const code = `
      let x = $signal(0);

      $effect(() => {
        console.log('Count', x);
      });
      $computed(() => {
        console.log('Count', x);
      });
      $renderEffect(() => {
        console.log('Count', x);
      });
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });

  describe('variable shadowing', () => {
    it('should respect variable shadowing', async () => {
      const code = `
        const selected = $signal('root');
        {
          const selected = 'local';
          console.log(selected); // 'local'
          {
            console.log(selected); // 'local'
            {
              const selected = $signal('inner');
              console.log(selected); // 'inner'
              {
                console.log(selected); // 'inner'
              }
            }   
          }
        }
      `;
      expect(await compile(code)).toMatchSnapshot();
    });
  });
});


================================================
FILE: packages/core/tsconfig.json
================================================
{
  "exclude": ["node_modules"],
  "include": ["src", "types", "babel"],
  "compilerOptions": {
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "importHelpers": true,
    "declaration": true,
    "sourceMap": true,
    "rootDir": "./",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "Bundler",
    "jsx": "react",
    "esModuleInterop": true,
    "target": "ES2017",
    "useDefineForClassFields": false,
    "declarationMap": true
  }
}


================================================
FILE: packages/rollup/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc


================================================
FILE: packages/rollup/README.md
================================================
# rollup-plugin-solid-labels

> Rollup plugin for [`solid-labels`](https://github.com/lxsmnsyc/solid-labels)

[![NPM](https://img.shields.io/npm/v/rollup-plugin-solid-labels.svg)](https://www.npmjs.com/package/rollup-plugin-solid-labels) [![JavaScript Style Guide](https://badgen.net/badge/code%20style/airbnb/ff5a5f?icon=airbnb)](https://github.com/airbnb/javascript)

## Install

```bash
npm install --D solid-labels rollup-plugin-solid-labels
```

```bash
yarn add -D solid-labels rollup-plugin-solid-labels
```

```bash
pnpm add -D solid-labels rollup-plugin-solid-labels
```

## Usage

```js
import solidLabels from 'rollup-plugin-solid-labels';

///...
solidLabels({
  dev: true, // defaults to false
Download .txt
gitextract_zomu0hq3/

├── .github/
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .npmrc
├── .vscode/
│   └── settings.json
├── LICENSE
├── README.md
├── biome.json
├── docs/
│   ├── comments.md
│   ├── ctf.md
│   ├── labels.md
│   └── namespace.md
├── examples/
│   ├── comments/
│   │   ├── .gitignore
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.js
│   ├── ctf/
│   │   ├── .gitignore
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.js
│   └── labels/
│       ├── .gitignore
│       ├── index.html
│       ├── package.json
│       ├── src/
│       │   ├── App.tsx
│       │   └── main.tsx
│       ├── tsconfig.json
│       └── vite.config.js
├── lerna.json
├── package.json
├── packages/
│   ├── core/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── babel/
│   │   │   ├── components.ts
│   │   │   ├── constants.ts
│   │   │   ├── core/
│   │   │   │   ├── accessor-variable.ts
│   │   │   │   ├── assert.ts
│   │   │   │   ├── deferred-variable.ts
│   │   │   │   ├── deref-memo-variable.ts
│   │   │   │   ├── deref-memo.ts
│   │   │   │   ├── deref-signal-variable.ts
│   │   │   │   ├── deref-signal.ts
│   │   │   │   ├── destructure-variable.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── generate-unique-name.ts
│   │   │   │   ├── get-import-identifier.ts
│   │   │   │   ├── is-awaited.ts
│   │   │   │   ├── is-in-typescript.ts
│   │   │   │   ├── is-static.ts
│   │   │   │   ├── is-yielded.ts
│   │   │   │   ├── memo-variable.ts
│   │   │   │   ├── proto.ts
│   │   │   │   ├── signal-variable.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── unwrap-node.ts
│   │   │   ├── index.ts
│   │   │   ├── transform-comment.ts
│   │   │   ├── transform-ctf.ts
│   │   │   └── transform-label.ts
│   │   ├── example.js
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── test/
│   │   │   ├── __snapshots__/
│   │   │   │   └── ctf.test.ts.snap
│   │   │   └── ctf.test.ts
│   │   └── tsconfig.json
│   ├── rollup/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── unplugin/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── pridepack.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── vite/
│       ├── .gitignore
│       ├── README.md
│       ├── package.json
│       ├── pridepack.json
│       ├── src/
│       │   └── index.ts
│       └── tsconfig.json
└── pnpm-workspace.yaml
Download .txt
SYMBOL INDEX (145 symbols across 33 files)

FILE: examples/comments/src/App.tsx
  function App (line 3) | function App(): JSX.Element {

FILE: examples/ctf/src/App.tsx
  function useCounter (line 3) | function useCounter(): [Accessor<number>, Setter<number>] {
  function App (line 13) | function App(): JSX.Element {

FILE: examples/labels/src/App.tsx
  function App (line 3) | function App(): JSX.Element {

FILE: packages/core/babel/components.ts
  type ComponentImport (line 6) | type ComponentImport = [name: string, source: string];
  constant COMPONENTS (line 8) | const COMPONENTS: Record<string, ComponentImport> = {
  constant NAMESPACE (line 25) | const NAMESPACE = 'solid';
  constant NAMESPACE_COMPONENTS (line 27) | const NAMESPACE_COMPONENTS: Record<string, ComponentImport> = {
  constant COMPONENT_TRAVERSE (line 44) | const COMPONENT_TRAVERSE: Visitor<State> = {
  method Expression (line 45) | Expression(p, state) {
  method JSXElement (line 55) | JSXElement(p, state) {
  function transformComponents (line 87) | function transformComponents(state: State, path: NodePath): void {

FILE: packages/core/babel/constants.ts
  constant UNDEFINED (line 3) | const UNDEFINED = t.unaryExpression('void', t.numericLiteral(0));

FILE: packages/core/babel/core/accessor-variable.ts
  function accessorVariable (line 6) | function accessorVariable(

FILE: packages/core/babel/core/assert.ts
  function assert (line 1) | function assert<T extends Error>(cond: unknown, error: T): asserts cond {

FILE: packages/core/babel/core/deferred-variable.ts
  function deferredVariable (line 8) | function deferredVariable(

FILE: packages/core/babel/core/deref-memo-variable.ts
  function derefMemoVariable (line 6) | function derefMemoVariable(

FILE: packages/core/babel/core/deref-memo.ts
  constant REF_MEMO_CTF (line 8) | const REF_MEMO_CTF = '$refMemo';
  constant GET_CTF (line 9) | const GET_CTF = '$get';
  constant GETTER_CTF (line 11) | const GETTER_CTF = '$getter';
  constant PROPERTY_CTF (line 12) | const PROPERTY_CTF = '$property';
  constant CALL_CTF (line 14) | const CALL_CTF = new Set([REF_MEMO_CTF, GET_CTF, GETTER_CTF, PROPERTY_CT...
  function transformGetter (line 16) | function transformGetter(
  function transformReferencePath (line 40) | function transformReferencePath(
  function derefMemo (line 70) | function derefMemo(

FILE: packages/core/babel/core/deref-signal-variable.ts
  function derefSignalVariable (line 6) | function derefSignalVariable(

FILE: packages/core/babel/core/deref-signal.ts
  constant REF_SIGNAL_CTF (line 11) | const REF_SIGNAL_CTF = '$refSignal';
  constant GET_CTF (line 12) | const GET_CTF = '$get';
  constant SET_CTF (line 13) | const SET_CTF = '$set';
  constant GETTER_CTF (line 15) | const GETTER_CTF = '$getter';
  constant SETTER_CTF (line 16) | const SETTER_CTF = '$setter';
  constant PROPERTY_CTF (line 17) | const PROPERTY_CTF = '$property';
  constant CALL_CTF (line 19) | const CALL_CTF = new Set([
  function transformProperty (line 28) | function transformProperty(
  function transformSignalRead (line 70) | function transformSignalRead(
  function transformUpdateExpression (line 114) | function transformUpdateExpression(
  function transformAssignmentExpression (line 161) | function transformAssignmentExpression(
  function transformSignalWrite (line 208) | function transformSignalWrite(
  function derefSignal (line 222) | function derefSignal(

FILE: packages/core/babel/core/destructure-variable.ts
  function destructureVariable (line 12) | function destructureVariable(

FILE: packages/core/babel/core/errors.ts
  function unexpectedType (line 3) | function unexpectedType<T>(
  function unexpectedMissingParent (line 13) | function unexpectedMissingParent<T>(path: babel.NodePath<T>): Error {
  function unexpectedArgumentLength (line 17) | function unexpectedArgumentLength<T>(
  function unexpectedAssignmentOperator (line 27) | function unexpectedAssignmentOperator<T>(

FILE: packages/core/babel/core/generate-unique-name.ts
  function generateUniqueName (line 4) | function generateUniqueName(

FILE: packages/core/babel/core/get-import-identifier.ts
  function getImportIdentifier (line 5) | function getImportIdentifier(

FILE: packages/core/babel/core/is-awaited.ts
  function isAwaited (line 3) | function isAwaited(node: t.Expression | t.SpreadElement): boolean {

FILE: packages/core/babel/core/is-in-typescript.ts
  function isInTypescript (line 4) | function isInTypescript(path: babel.NodePath): boolean {

FILE: packages/core/babel/core/is-static.ts
  function isStatic (line 3) | function isStatic(

FILE: packages/core/babel/core/is-yielded.ts
  function isYielded (line 3) | function isYielded(node: t.Expression | t.SpreadElement): boolean {

FILE: packages/core/babel/core/memo-variable.ts
  function memoVariable (line 8) | function memoVariable(

FILE: packages/core/babel/core/proto.ts
  type ProtoObjectState (line 5) | interface ProtoObjectState {
  constant ROOT_GET (line 10) | const ROOT_GET = 'get';
  constant ROOT_SET (line 11) | const ROOT_SET = 'set';
  constant ROOT_SYMBOL (line 12) | const ROOT_SYMBOL = '__$';
  constant PROTO_STATES (line 14) | const PROTO_STATES = new WeakMap<t.Node, ProtoObjectState>();
  function getProtoState (line 16) | function getProtoState(
  function getGetterReplacement (line 41) | function getGetterReplacement(
  function getSetterReplacement (line 55) | function getSetterReplacement(
  function getNamespacedKey (line 75) | function getNamespacedKey(
  function initProtoGetters (line 92) | function initProtoGetters(
  function registerProtoGetter (line 104) | function registerProtoGetter(
  function addUnoptimizedGetter (line 122) | function addUnoptimizedGetter(
  function addProtoGetter (line 132) | function addProtoGetter(
  function initProtoSetters (line 147) | function initProtoSetters(
  function registerProtoSetter (line 159) | function registerProtoSetter(
  function addUnoptimizedSetter (line 177) | function addUnoptimizedSetter(
  function addProtoSetter (line 187) | function addProtoSetter(
  function addUnoptimizedProperty (line 202) | function addUnoptimizedProperty(
  function addProtoProperty (line 223) | function addProtoProperty(

FILE: packages/core/babel/core/signal-variable.ts
  function signalVariable (line 8) | function signalVariable(

FILE: packages/core/babel/core/types.ts
  type Options (line 4) | interface Options {
  type ImportHook (line 13) | type ImportHook = Map<string, t.Identifier>;
  type State (line 15) | interface State extends babel.PluginPass {

FILE: packages/core/babel/core/unwrap-node.ts
  type TypeFilter (line 4) | type TypeFilter<K extends t.Node> = (node: t.Node) => node is K;
  type TypeCheck (line 6) | type TypeCheck<K> = K extends TypeFilter<infer U> ? U : never;
  type NestedExpression (line 8) | type NestedExpression =
  function isNestedExpression (line 17) | function isNestedExpression(node: t.Node): node is NestedExpression {
  function isPathValid (line 32) | function isPathValid<V extends t.Node>(
  function unwrapNode (line 39) | function unwrapNode<K extends (node: t.Node) => boolean>(
  function getProperParentPath (line 52) | function getProperParentPath<K extends (node: t.Node) => boolean>(

FILE: packages/core/babel/index.ts
  function solidLabelsPlugin (line 10) | function solidLabelsPlugin(): babel.PluginObj<State> {

FILE: packages/core/babel/transform-comment.ts
  constant VARIABLE_LABEL (line 12) | const VARIABLE_LABEL = {
  type CallbackLabel (line 20) | type CallbackLabel = [name: string, source: string, named: boolean];
  constant CALLBACK_LABEL (line 22) | const CALLBACK_LABEL: Record<string, CallbackLabel> = {
  function getVariableLabelPreference (line 35) | function getVariableLabelPreference(
  constant LABEL_PATTERN (line 51) | const LABEL_PATTERN = /^@\w+( .*)?$/;
  function getCallbackLabelPreference (line 53) | function getCallbackLabelPreference(state: State, comments: t.Comment[]) {
  constant COMMENT_TRAVERSE (line 71) | const COMMENT_TRAVERSE: babel.Visitor<State> = {
  method VariableDeclaration (line 72) | VariableDeclaration(path, state) {
  method BlockStatement (line 161) | BlockStatement(path, state) {
  method ExpressionStatement (line 195) | ExpressionStatement(path, state) {
  function transformComments (line 228) | function transformComments(state: State, path: babel.NodePath): void {

FILE: packages/core/babel/transform-ctf.ts
  type AutoArrowCTF (line 18) | type AutoArrowCTF = [name: string, source: string, arguments: number];
  constant AUTO_ARROW_CTF (line 20) | const AUTO_ARROW_CTF: Record<string, AutoArrowCTF> = {
  type AutoImportAliasCTF (line 29) | type AutoImportAliasCTF = [name: string, source: string];
  constant AUTO_IMPORT_ALIAS_CTF (line 31) | const AUTO_IMPORT_ALIAS_CTF: Record<string, AutoImportAliasCTF> = {
  type AutoAccessorCTF (line 59) | type AutoAccessorCTF = [
  constant AUTO_ACCESSOR_CTF (line 66) | const AUTO_ACCESSOR_CTF: Record<string, AutoAccessorCTF> = {
  constant SIGNAL_CTF (line 73) | const SIGNAL_CTF = '$signal';
  constant MEMO_CTF (line 74) | const MEMO_CTF = '$memo';
  constant DEREF_SIGNAL_CTF (line 75) | const DEREF_SIGNAL_CTF = '$derefSignal';
  constant DEREF_MEMO_CTF (line 76) | const DEREF_MEMO_CTF = '$derefMemo';
  constant REACTIVE_CTF (line 77) | const REACTIVE_CTF = '$';
  constant DEFERRED_CTF (line 78) | const DEFERRED_CTF = '$deferred';
  constant DESTRUCTURE_CTF (line 79) | const DESTRUCTURE_CTF = '$destructure';
  constant COMPONENT_CTF (line 80) | const COMPONENT_CTF = '$component';
  constant SPECIAL_CTF (line 82) | const SPECIAL_CTF = new Set([
  constant CTF_TRAVERSE (line 93) | const CTF_TRAVERSE: babel.Visitor<State> = {
  method CallExpression (line 94) | CallExpression(path, state) {
  method Expression (line 167) | Expression(path, state) {
  method VariableDeclarator (line 178) | VariableDeclarator(path, state) {
  method ExpressionStatement (line 351) | ExpressionStatement(path, state) {
  function transformCTF (line 391) | function transformCTF(state: State, path: babel.NodePath): void {

FILE: packages/core/babel/transform-label.ts
  constant REACTIVE_LABEL (line 14) | const REACTIVE_LABEL = '$';
  constant SPECIAL_LABELS (line 16) | const SPECIAL_LABELS = new Set([REACTIVE_LABEL]);
  constant VARIABLE_LABEL (line 18) | const VARIABLE_LABEL = {
  type CallbackLabel (line 26) | type CallbackLabel = [name: string, source: string, named: boolean];
  constant CALLBACK_LABEL (line 28) | const CALLBACK_LABEL: Record<string, CallbackLabel> = {
  function transformReactiveLabel (line 41) | function transformReactiveLabel(
  function transformDeclaratorFromVariableLabel (line 66) | function transformDeclaratorFromVariableLabel(
  function transformVariableLabel (line 112) | function transformVariableLabel(
  function transformCallbackLabel (line 140) | function transformCallbackLabel(
  constant LABEL_TRAVERSE (line 179) | const LABEL_TRAVERSE: babel.Visitor<State> = {
  method LabeledStatement (line 180) | LabeledStatement(path, state) {
  function transformLabels (line 205) | function transformLabels(state: State, path: babel.NodePath): void {

FILE: packages/core/example.js
  function compile (line 4) | async function compile(code, dev) {

FILE: packages/core/src/index.ts
  type Accessor (line 6) | type Accessor<T> = solid.Accessor<T>;
  type Setter (line 7) | type Setter<T> = solid.Setter<T>;
  type Context (line 8) | type Context<T> = solid.Context<T>;
  type ObservableObserver (line 9) | type ObservableObserver<T> = solid.ObservableObserver<T>;
  type Component (line 10) | type Component<T extends Record<string, any> = {}> = solid.Component<T>;
  type Observable (line 84) | interface Observable<T> {
  type Props (line 165) | type Props<T> = T extends (props: infer P) => solid.JSX.Element ? P : ne...
  type IntrinsicElements (line 170) | interface IntrinsicElements {

FILE: packages/core/test/ctf.test.ts
  function compile (line 5) | async function compile(code: string, dev?: boolean): Promise<string> {

FILE: packages/unplugin/src/index.ts
  type SolidLabelsPluginFilter (line 11) | interface SolidLabelsPluginFilter {
  type SolidLabelsPluginOptions (line 16) | interface SolidLabelsPluginOptions extends Options {
  function repushPlugin (line 21) | function repushPlugin(
  constant DEFAULT_INCLUDE (line 52) | const DEFAULT_INCLUDE = 'src/**/*.{jsx,tsx,ts,js,mjs,cjs}';
  constant DEFAULT_EXCLUDE (line 53) | const DEFAULT_EXCLUDE = 'node_modules/**/*.{jsx,tsx,ts,js,mjs,cjs}';
  constant FILE_FILTER (line 55) | const FILE_FILTER = /\.[mc]?tsx?$/i;
  method transformInclude (line 68) | transformInclude(id): boolean {
  method transform (line 71) | async transform(code, id): Promise<TransformResult> {
  method configResolved (line 109) | configResolved(config): void {
Condensed preview — 88 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (225K chars).
[
  {
    "path": ".github/workflows/main.yml",
    "chars": 588,
    "preview": "name: CI\non:\n  - push\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - us"
  },
  {
    "path": ".gitignore",
    "chars": 1120,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directo"
  },
  {
    "path": ".npmrc",
    "chars": 90,
    "preview": "strict-peer-dependencies=false\nprefer-workspace-packages=true\nlink-workspace-packages=true"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 336,
    "preview": "{\n  \"editor.defaultFormatter\": \"biomejs.biome\",\n  \"[typescript]\": {\n    \"editor.defaultFormatter\": \"biomejs.biome\"\n  },\n"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "MIT License\n\nCopyright (c) 2025 Alexis Munsayac\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README.md",
    "chars": 2806,
    "preview": "\n# `solid-labels`\n\n[![NPM](https://img.shields.io/npm/v/solid-labels.svg)](https://www.npmjs.com/package/solid-labels) ["
  },
  {
    "path": "biome.json",
    "chars": 4207,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/@biomejs/biome/configuration_schema.json\",\n  \"files\": {\n    \"ignore\": [\"node_modules/*"
  },
  {
    "path": "docs/comments.md",
    "chars": 7040,
    "preview": "# Comments\n\n## Utilities\n\n### `@signal`\n\nTransforms into `createSignal`:\n\n```js\nfunction Counter() {\n  // @signal\n  let "
  },
  {
    "path": "docs/ctf.md",
    "chars": 20829,
    "preview": "# Compile-Time Functions\n\n## Reactivity\n\n### `$signal`\n\n```ts\nfunction $signal<T>(): T | undefined;\nfunction $signal<T>("
  },
  {
    "path": "docs/labels.md",
    "chars": 8476,
    "preview": "# Labels\n\n## Utilities\n\n### `signal`\n\nTransforms into `createSignal`:\n\n```js\nfunction Counter() {\n  signal: x = 0;\n\n  fu"
  },
  {
    "path": "docs/namespace.md",
    "chars": 5696,
    "preview": "# Namespace\n\n## `<solid:for>`\n\nAlias for [`<For>`](https://www.solidjs.com/docs/latest#%3Cfor%3E)\n\n```jsx\n<solid:for eac"
  },
  {
    "path": "examples/comments/.gitignore",
    "chars": 44,
    "preview": "node_modules\n.DS_Store\ndist\ndist-ssr\n*.local"
  },
  {
    "path": "examples/comments/index.html",
    "chars": 340,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"favico"
  },
  {
    "path": "examples/comments/package.json",
    "chars": 482,
    "preview": "{\n  \"name\": \"vite-example-comments\",\n  \"type\": \"module\",\n  \"version\": \"0.17.0\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"b"
  },
  {
    "path": "examples/comments/src/App.tsx",
    "chars": 377,
    "preview": "import type { JSX } from 'solid-js/jsx-runtime';\n\nexport default function App(): JSX.Element {\n  /* @signal */\n  let cou"
  },
  {
    "path": "examples/comments/src/main.tsx",
    "chars": 153,
    "preview": "import { render } from 'solid-js/web';\nimport App from './App';\n\nconst app = document.getElementById('app');\n\nif (app) {"
  },
  {
    "path": "examples/comments/tsconfig.json",
    "chars": 531,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"module\": \"ESNext\",\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"moduleResolu"
  },
  {
    "path": "examples/comments/vite.config.js",
    "chars": 358,
    "preview": "import { defineConfig } from 'vite';\nimport solidPlugin from 'vite-plugin-solid';\nimport solidLabels from 'vite-plugin-s"
  },
  {
    "path": "examples/ctf/.gitignore",
    "chars": 44,
    "preview": "node_modules\n.DS_Store\ndist\ndist-ssr\n*.local"
  },
  {
    "path": "examples/ctf/index.html",
    "chars": 340,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"favico"
  },
  {
    "path": "examples/ctf/package.json",
    "chars": 477,
    "preview": "{\n  \"name\": \"vite-example-ctf\",\n  \"type\": \"module\",\n  \"version\": \"0.17.0\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\""
  },
  {
    "path": "examples/ctf/src/App.tsx",
    "chars": 691,
    "preview": "import type { Accessor, JSX, Setter } from 'solid-js';\n\nfunction useCounter(): [Accessor<number>, Setter<number>] {\n  co"
  },
  {
    "path": "examples/ctf/src/main.tsx",
    "chars": 153,
    "preview": "import { render } from 'solid-js/web';\nimport App from './App';\n\nconst app = document.getElementById('app');\n\nif (app) {"
  },
  {
    "path": "examples/ctf/tsconfig.json",
    "chars": 531,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"module\": \"ESNext\",\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"moduleResolu"
  },
  {
    "path": "examples/ctf/vite.config.js",
    "chars": 358,
    "preview": "import { defineConfig } from 'vite';\nimport solidPlugin from 'vite-plugin-solid';\nimport solidLabels from 'vite-plugin-s"
  },
  {
    "path": "examples/labels/.gitignore",
    "chars": 44,
    "preview": "node_modules\n.DS_Store\ndist\ndist-ssr\n*.local"
  },
  {
    "path": "examples/labels/index.html",
    "chars": 358,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"f"
  },
  {
    "path": "examples/labels/package.json",
    "chars": 480,
    "preview": "{\n  \"name\": \"vite-example-labels\",\n  \"type\": \"module\",\n  \"version\": \"0.17.0\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"bui"
  },
  {
    "path": "examples/labels/src/App.tsx",
    "chars": 352,
    "preview": "import type { JSX } from 'solid-js/jsx-runtime';\n\nexport default function App(): JSX.Element {\n  signal: var count = 0;\n"
  },
  {
    "path": "examples/labels/src/main.tsx",
    "chars": 153,
    "preview": "import { render } from 'solid-js/web';\nimport App from './App';\n\nconst app = document.getElementById('app');\n\nif (app) {"
  },
  {
    "path": "examples/labels/tsconfig.json",
    "chars": 531,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"module\": \"ESNext\",\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"moduleResolu"
  },
  {
    "path": "examples/labels/vite.config.js",
    "chars": 358,
    "preview": "import { defineConfig } from 'vite';\nimport solidPlugin from 'vite-plugin-solid';\nimport solidLabels from 'vite-plugin-s"
  },
  {
    "path": "lerna.json",
    "chars": 285,
    "preview": "{\n  \"npmClient\": \"npm\",\n  \"packages\": [\n    \"packages/*\",\n    \"examples/*\"\n  ],\n  \"command\": {\n    \"version\": {\n      \"e"
  },
  {
    "path": "package.json",
    "chars": 196,
    "preview": "{\n  \"name\": \"root\",\n  \"private\": true,\n  \"workspaces\": [\"packages/*\", \"examples/*\"],\n  \"devDependencies\": {\n    \"@biomej"
  },
  {
    "path": "packages/core/.gitignore",
    "chars": 1641,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "packages/core/README.md",
    "chars": 2806,
    "preview": "\n# `solid-labels`\n\n[![NPM](https://img.shields.io/npm/v/solid-labels.svg)](https://www.npmjs.com/package/solid-labels) ["
  },
  {
    "path": "packages/core/babel/components.ts",
    "chars": 2869,
    "preview": "import type { NodePath, Visitor } from '@babel/traverse';\nimport * as t from '@babel/types';\nimport { getImportIdentifie"
  },
  {
    "path": "packages/core/babel/constants.ts",
    "chars": 109,
    "preview": "import * as t from '@babel/types';\n\nexport const UNDEFINED = t.unaryExpression('void', t.numericLiteral(0));\n"
  },
  {
    "path": "packages/core/babel/core/accessor-variable.ts",
    "chars": 638,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { derefMemo } from './deref-memo';\n"
  },
  {
    "path": "packages/core/babel/core/assert.ts",
    "chars": 119,
    "preview": "export function assert<T extends Error>(cond: unknown, error: T): asserts cond {\n  if (!cond) {\n    throw error;\n  }\n}\n"
  },
  {
    "path": "packages/core/babel/core/deferred-variable.ts",
    "chars": 1521,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { accessorVariable } from './access"
  },
  {
    "path": "packages/core/babel/core/deref-memo-variable.ts",
    "chars": 523,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { derefMemo } from './deref-memo';\n"
  },
  {
    "path": "packages/core/babel/core/deref-memo.ts",
    "chars": 2435,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { assert } from './assert';\nimport "
  },
  {
    "path": "packages/core/babel/core/deref-signal-variable.ts",
    "chars": 697,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { derefSignal } from './deref-signa"
  },
  {
    "path": "packages/core/babel/core/deref-signal.ts",
    "chars": 6693,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { assert } from './assert';\nimport "
  },
  {
    "path": "packages/core/babel/core/destructure-variable.ts",
    "chars": 8833,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { derefMemo } from './deref-memo';\n"
  },
  {
    "path": "packages/core/babel/core/errors.ts",
    "chars": 885,
    "preview": "import type * as babel from '@babel/core';\n\nexport function unexpectedType<T>(\n  path: babel.NodePath<T>,\n  received: st"
  },
  {
    "path": "packages/core/babel/core/generate-unique-name.ts",
    "chars": 531,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\n\nexport function generateUniqueName(\n  pat"
  },
  {
    "path": "packages/core/babel/core/get-import-identifier.ts",
    "chars": 804,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport type { State } from './types';\n\nexp"
  },
  {
    "path": "packages/core/babel/core/is-awaited.ts",
    "chars": 3362,
    "preview": "import * as t from '@babel/types';\n\nexport function isAwaited(node: t.Expression | t.SpreadElement): boolean {\n  // Defa"
  },
  {
    "path": "packages/core/babel/core/is-in-typescript.ts",
    "chars": 344,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\n\nexport function isInTypescript(path: babe"
  },
  {
    "path": "packages/core/babel/core/is-static.ts",
    "chars": 3659,
    "preview": "import * as t from '@babel/types';\n\nexport function isStatic(\n  node:\n    | t.Expression\n    | t.SpreadElement\n    | t.A"
  },
  {
    "path": "packages/core/babel/core/is-yielded.ts",
    "chars": 3362,
    "preview": "import * as t from '@babel/types';\n\nexport function isYielded(node: t.Expression | t.SpreadElement): boolean {\n  // Defa"
  },
  {
    "path": "packages/core/babel/core/memo-variable.ts",
    "chars": 1652,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { accessorVariable } from './access"
  },
  {
    "path": "packages/core/babel/core/proto.ts",
    "chars": 6104,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { generateUniqueName } from './gene"
  },
  {
    "path": "packages/core/babel/core/signal-variable.ts",
    "chars": 1512,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { derefSignal } from './deref-signa"
  },
  {
    "path": "packages/core/babel/core/types.ts",
    "chars": 397,
    "preview": "import type * as babel from '@babel/core';\nimport type * as t from '@babel/types';\n\nexport interface Options {\n  dev?: b"
  },
  {
    "path": "packages/core/babel/core/unwrap-node.ts",
    "chars": 1667,
    "preview": "import type { NodePath } from '@babel/traverse';\nimport type * as t from '@babel/types';\n\ntype TypeFilter<K extends t.No"
  },
  {
    "path": "packages/core/babel/index.ts",
    "chars": 722,
    "preview": "import type * as babel from '@babel/core';\nimport { transformComponents } from './components';\nimport type { Options, St"
  },
  {
    "path": "packages/core/babel/transform-comment.ts",
    "chars": 7207,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { accessorVariable } from './core/a"
  },
  {
    "path": "packages/core/babel/transform-ctf.ts",
    "chars": 14258,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { accessorVariable } from './core/a"
  },
  {
    "path": "packages/core/babel/transform-label.ts",
    "chars": 5841,
    "preview": "import type * as babel from '@babel/core';\nimport * as t from '@babel/types';\nimport { accessorVariable } from './core/a"
  },
  {
    "path": "packages/core/example.js",
    "chars": 542,
    "preview": "import * as babel from '@babel/core';\nimport plugin from './dist/esm/development/babel.mjs';\n\nasync function compile(cod"
  },
  {
    "path": "packages/core/package.json",
    "chars": 2288,
    "preview": "{\n  \"version\": \"0.17.0\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"development\": {\n        \"require\": \"./dist"
  },
  {
    "path": "packages/core/pridepack.json",
    "chars": 113,
    "preview": "{\r\n  \"target\": \"es2018\",\r\n  \"entrypoints\": {\r\n    \".\": \"src/index.ts\",\r\n    \"./babel\": \"babel/index.ts\"\r\n  }\r\n}\r\n"
  },
  {
    "path": "packages/core/src/index.ts",
    "chars": 5255,
    "preview": "import type * as solid from 'solid-js';\nimport type * as solidStore from 'solid-js/store';\nimport type * as solidWeb fro"
  },
  {
    "path": "packages/core/test/__snapshots__/ctf.test.ts.snap",
    "chars": 23161,
    "preview": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`ctf > $component > should transform $component 1"
  },
  {
    "path": "packages/core/test/ctf.test.ts",
    "chars": 14953,
    "preview": "import * as babel from '@babel/core';\nimport { describe, expect, it } from 'vitest';\nimport plugin from '../babel';\n\nasy"
  },
  {
    "path": "packages/core/tsconfig.json",
    "chars": 576,
    "preview": "{\n  \"exclude\": [\"node_modules\"],\n  \"include\": [\"src\", \"types\", \"babel\"],\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n"
  },
  {
    "path": "packages/rollup/.gitignore",
    "chars": 1641,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "packages/rollup/README.md",
    "chars": 1217,
    "preview": "# rollup-plugin-solid-labels\n\n> Rollup plugin for [`solid-labels`](https://github.com/lxsmnsyc/solid-labels)\n\n[![NPM](ht"
  },
  {
    "path": "packages/rollup/package.json",
    "chars": 1732,
    "preview": "{\n  \"version\": \"0.17.0\",\n  \"type\": \"module\",\n  \"types\": \"./dist/types/index.d.ts\",\n  \"main\": \"./dist/cjs/production/inde"
  },
  {
    "path": "packages/rollup/pridepack.json",
    "chars": 28,
    "preview": "{\r\n  \"target\": \"es2018\"\r\n}\r\n"
  },
  {
    "path": "packages/rollup/src/index.ts",
    "chars": 412,
    "preview": "import type { SolidLabelsPluginOptions } from 'unplugin-solid-labels';\nimport solidLabelsUnplugin from 'unplugin-solid-l"
  },
  {
    "path": "packages/rollup/tsconfig.json",
    "chars": 570,
    "preview": "{\n  \"exclude\": [\"node_modules\"],\n  \"include\": [\"src\", \"types\"],\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n    \"lib\""
  },
  {
    "path": "packages/unplugin/.gitignore",
    "chars": 1641,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "packages/unplugin/README.md",
    "chars": 1121,
    "preview": "# unplugin-solid-labels\n\n> [Unplugin](https://github.com/unjs/unplugin) for [`solid-labels`](https://github.com/lxsmnsyc"
  },
  {
    "path": "packages/unplugin/package.json",
    "chars": 2025,
    "preview": "{\n  \"name\": \"unplugin-solid-labels\",\n  \"version\": \"0.17.0\",\n  \"type\": \"module\",\n  \"files\": [\n    \"dist\",\n    \"babel\",\n  "
  },
  {
    "path": "packages/unplugin/pridepack.json",
    "chars": 25,
    "preview": "{\n  \"target\": \"es2018\"\n}\n"
  },
  {
    "path": "packages/unplugin/src/index.ts",
    "chars": 3669,
    "preview": "import * as babel from '@babel/core';\nimport type { FilterPattern } from '@rollup/pluginutils';\nimport { createFilter } "
  },
  {
    "path": "packages/unplugin/tsconfig.json",
    "chars": 561,
    "preview": "{\n  \"exclude\": [\"node_modules\"],\n  \"include\": [\"src\"],\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n    \"lib\": [\"ESNex"
  },
  {
    "path": "packages/vite/.gitignore",
    "chars": 1641,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "packages/vite/README.md",
    "chars": 1104,
    "preview": "# vite-plugin-solid-labels\n\n> Vite plugin for [`solid-labels`](https://github.com/lxsmnsyc/solid-labels)\n\n[![NPM](https:"
  },
  {
    "path": "packages/vite/package.json",
    "chars": 1786,
    "preview": "{\n  \"version\": \"0.17.0\",\n  \"type\": \"module\",\n  \"types\": \"./dist/types/index.d.ts\",\n  \"main\": \"./dist/cjs/production/inde"
  },
  {
    "path": "packages/vite/pridepack.json",
    "chars": 28,
    "preview": "{\r\n  \"target\": \"es2018\"\r\n}\r\n"
  },
  {
    "path": "packages/vite/src/index.ts",
    "chars": 408,
    "preview": "import type { SolidLabelsPluginOptions } from 'unplugin-solid-labels';\nimport solidLabelsUnplugin from 'unplugin-solid-l"
  },
  {
    "path": "packages/vite/tsconfig.json",
    "chars": 570,
    "preview": "{\n  \"exclude\": [\"node_modules\"],\n  \"include\": [\"src\", \"types\"],\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n    \"lib\""
  },
  {
    "path": "pnpm-workspace.yaml",
    "chars": 45,
    "preview": "packages:\n- 'packages/**/*'\n- 'examples/**/*'"
  }
]

About this extraction

This page contains the full source code of the lxsmnsyc/solid-labels GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 88 files (203.3 KB), approximately 57.7k tokens, and a symbol index with 145 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!