---
# System prepended metadata

title: QRL brainstorm

---

# QRL brainstorm



## File extensions
- `.event.js`
    - `qwikloader.js` always loads this. `@builder.io/core` will never runtime import `.event.js` (there are `import` statements which the tooling rewrites to QRLs.)
- `.method.js` ????
    - These are needed by the Entity. more brainstorming needed here.
- `.template.js`
    - Needed by `decl:template="..."` attribute. These will be used by the renderer. 
- `.css.js`
    - These are derived by ther rendere from the `decl:template` to load CSS on as needed basis.



```htmlembedded=
<style decl:style="QXK"> import(foo:MyItem.css) </style>
<div decl:template="foo:MyItem" class="QXK-HOST">
  <span class="QXK">...</span>
</div>
```

- `MyItem.template.js`
- `MyItem.css`
    - `MyItem.css`
    - `MyTime.css.sub-chunkA`
    - `MyTime.css.sub-chunkB`


---

```typescript=
function MyComponent() {
  return (
    <div class="MyClass">
      <span></span>
    </div>
  );
}
```

```htmlembedded=
<div class="MyComponent-h MyClass">
  <span class="MyComponent"></span>
  <span class="MyComponent"></span>
</div>
```

---

## Style

```typescript=
import {PRIMARY, SECONDARY} from './material';
import PRIMARY from './material.css.primary';
  // <style decl:style="XYZ"> class-name {...}</styl>
  // PRIMARY === class-name
import from './a.css';

// PRIMARY => scoped-CSS-class.

function AComponent() {
  return  <md-button style={style(PRIMARY)}></md-button>
}

function BComponent() {
  return  <md-button class={SECONDARY}></md-button>
}
```

- `FooComponent` => `foo.component.ts`
- `foo.template.ts`
- `foo.css`
- `foo.css.primary` / `foo.primary.css`

```typescript=
(await someFunction(QRL<()=>string>`./adsf`))() => string
someFunction(`./adsf`)
```

```typescript=
import { applyStyles } from '@builder.io/qwik/internal'
```

---


```typescript=
import {onButtonClick} from 'Foo_onClick';

<button on:click={onButtonClick}>
<button on:click="????">

// Optimizer Converts above to bellow.

<button on:click={QRL`./Foo_onClick#onButtonClick`}>

```


----


```typescript=
// MyComponent.component.tsx
export function MyComponent() {}
```

```typescript=
// index.ts
export {MyComponent} from './MyComponent.component';
```

```typescript=
// MyApp.tsx
import {MyComponent} from './index';

function MyApp() {
  return <MyComponent/>

}
```


```typescript=
function EvilComponent() {
  return exp ? <bar/> : <foo/>
}
```


```typescript=
function CmpA() {
    return (
        <CmpB style="..."/>
    )
}

interface SomeProps extends HTMLAttributes {}

function CmpB<SomeProps>(props: {}) {
    return (
        <div style="..."></div>
    )
}
```



```typescript=
// MyComponent.component.tsx
export function MyComponent(props: {name: string}) {
  return <div style="color: red; width: 20px">...</div>
}
```


```typescript=
// MyApp.tsx
import {MyComponent} from './MyComponent.component';

const MyComponent2 = defineComponent<{name: string}>(QRL`...`, div')

function MyApp() {
  return <>
      <MyComponent style="width: 40px" name="bla"/> // <-- TYPE ERROR
      <MyComponent2 style="width: 40px" name="BLA"/> // WORKS
    </>

}
```

[HostElements](https://www.typescriptlang.org/play?jsx=1&ssl=31&ssc=24&pln=31&pc=34#code/KYDwDg9gTgLgBAE2AYwDYEMrDgO3QW2AGcx1lsApAZQA04BvAKDjgEscZgoAzM7ASQ5R2RVsgCiqYIQ5EGzFolYA3AFzzFmuGnREiAfnVEYwnAHMANAq1xjATymHbJ9petaA2gHIIOVWjEAay8AXSdjUzdNAF8AbncSdD8NG20MPXCXcytU5wdgTMic1O9ff1Qg0MLXYpY4hWjGRsZuAFccZBhWXzgACQhjAAowKAgwInUkuwBKeSbGFvbO7pw4AEcAYQh8SBxgDgAeABUAPkGACwGYADkCYCMsyzhuZOHR8fUj2YBeE7gp6bqfrGSTSfYwY5-JgsLAwVpQVY4VqoVAAQnizUYMDsYGwwJgoJkENOcG+cEhcHcbzGEwYOgyDyKeUcjNc0TgADI4F9SX8pvEFowAPRCuAAcSwwE4UAAdDAiCBGKBILBtL5jOLJdLSestjtfODBl4ECovBZnksuj0JcApVwAEzUj4MPCEVnmaKA-44OwpWHw1YHRKrelEb4AIgAYhAIOHmcAI8gIKhoOosAhwydesAURAXXdogchcGTk1pgLldB4EmcBqbXaoPadZttrtDcbTea2h0rat69LHSMaep6K77s5Ip7Jj6-VKA+T8WldGGozG4-YpInk6m4OnM9nc-nCIWhfjS56BcLRQBBMBgOUKq9sfWq+j92D29ncUb4OBeGVCv2XBeBW4BVhaPYrHAACydi3mAjqzNCu5zgi5KljYBxAVAuB3BGADq0CoBmS56BGABCmDrtim7hkmKZQOoABGqCtMAcZlAEyCBBGMp8eGQoYVoWFag6uGEARREkaGFFUfGW4McxrHsXAnEVNxvH8YJChFueCxAA)

--- 

```
// Item

- Item.component.tsx // template
- Item.ts
- Item_remove.handler.ts
- Item_add.handler.ts

- User.entity.ts
- User_login.method.ts
```

```typescript=
import {Item} from './Item.component';

export function MyApp() {
  return <Item/>
}
```

```typescript=
// Item_click.state.ts
export default function () {}
```

```typescript=
import * as Item_click from './Item_click.handler';

export function Item() {
  return <button on:click={Item_click}>add</button>
    // <button on:click="./Item_click">add</button>
    // QRL 'Item_click' => 'Item_click.handler.js'
}
```


## No bundling magic breaking apart the imports:

```typescript=

function qComponent(tag:string, fn: () => any);
function qComponent(tag:string, props: any, fn: () => any);
function qComponent(fn: () => any);

function qComponent(...args[]: any[]) {

    return fn;
}

// Greeter.component.tsx
const Greeter = qComponent(() => {...});
const Greeter = qComponent('div', () => {...});
export Greeter;

// Main.component.tsx
import Greeter from './Greeter.component';
function Main() {
    return (
        <div>
            <Greeter/>
        </div>
    );
}
```


## Bundling magic by breaking apart the imports:

```typescript=

// Greeter.component.tsx
const Greeter = qComponent(..);
export Greeter;


// Main.component.tsx
import { jsxDeclareTemplate } from '@builder.io/qwik/internal';

// const Greeter = import('./Greeter.component');
const Greeter = jsxDeclareComponent('./some-path-123.js');

function Main() {
    return (
        <div>
            <Greeter/>
        </div>
    );
}
```


```typescript=
const GreeterB = qComponent(async (props: GreeterProps, ref: any) => {
  const state = await getState<GreeterComponentState>(ref);
  const { name } = state;
  return (
    <div>
      <div>
        Your name:
        <input value={name} on:keyup={QRL`./Greeter_input_onKeyup#?name=.target.value`} />
      </div>
      <span>Hello {name}!</span>
    </div>
  );
});
```

```typescript=
async function Greet(this: Ref, props: {name: string}) {
  const salutation = await inject(this, Salutation);
  const salutation = await useState(this, Salutation);
  return <span>{salutation} {name}!</span>
}


inject(
  Salutation, 
  function Greet(salutation: any, props: {name: string}) {
    return <span>{salutation} {name}!</span>
  }
)


async function Greet(this: Ref, props: {name: string}) {
  const salutationPromise = useState(this, Salutation);
  
  if (Build.isClient && isLoading) {
      return <span>loading...</span>
  } else {
    await salutationPromise;
    return <span>{salutation} {name}!</span>
  }
}
```

## Component import transformations

Developer Code:

```typescript=
import SomeEsmImport from './some.component';
```

Internally, while bundling the module, its source is rewritten to:

```typescript=
import {jsxDeclareComponent} from '@builder.io/qwik';
const SomeEsmImport = jsxDeclareComponent(import('./some.component'));
```

While generating the JavaScript output, it’s written as:

```typescript=
import {jsxDeclareComponent} from '@builder.io/qwik';
const SomeEsmImport = jsxDeclareComponent('./abc123-hash.js', 'tag-name');
```


## Synthetic Entry Points

Developer Code:

```typescript=

// cmp.a.tsx
export default function(){...}
 
// cmp.b.tsx
import CmpA from './cmp.a'

export default function(){
    return (
        <div>
            <CmpA/>
        </div>
    )
}
```

Output Code:

```typescript=

// @entry1.tsx (generated file)
import { jsxDeclareComponent } from '@builder.io/qwik';
export { CmpA } = jsxDeclareComponent('./cmp.a', 'a-name');
export { CmpC } = jsxDeclareComponent('./cmp.c', 'c-name');


// cmp.a.tsx
export default function(){...}
 
// cmp.b.tsx
import { CmpA } from '@entry1'

export default function(){
    return (
        <div>
            <CmpA/>
        </div>
    )
}
```

----
`my-counter.tsx`
```typescript=
// First declare the component interface types.
export interface MyCounterProps {
  step?: number;
}
export interface MyCounterState {
  count: number;
}

// Next declare the component's state factory. This will be used when new component is
// being created to initialize the state. (It will not be used on rehydration.)
export const MyCounterStateFactory = qStateFactory<MyCounterProps, MyCounterState>(() => ({
  count: 0,
}));

export const MyCounterView = qView<typeof MyCounter>((props) => {
    const state = getState(props);
    return (
      <div>
        <button on:click={MyCounterDecrement}>-</button>
        <span>{state.count}</span>
        <button on:click={MyCounterDecrement}>+</button>
      </div>
    );
  });

// Next declare the component
export const MyCounter = qComponent<MyCounterProps, MyCounterState>({
  stateFactory: MyCounterStateFactory,
  template: MyCounterView,
});

// Finally declare the component's behavior (event handlers)
export const MyCounterIncrement = qHandler<typeof MyCounter>((props) => {
  const state = getState(props);
  state.count += props.step || 1;
  markDirty(props);
});

export const MyCounterDecrement = qHandler<typeof MyCounter>((props) => {
  const state = getState(props);
  state.count -= props.step || 1;
  markDirty(props);
});
```

```typescript=
import {MyCounter} from './my-counter'; 

function MyApp() {
  return <MyCounter/>
}
```

REWRITE

```typescript=
import {MyCounter} from './@entry-group-123'; 

function MyApp() {
  return <MyCounter/>
}
```

`@@entry-group-123`
```typescript=
export MyCounter from './my-counter';
```

`my-counter.js`
```typescript=
// qComponent internally calls jsxDeclareComponent
export const MyCounter = qComponent<MyCounterProps, MyCounterState>({
  stateFactory: './@entry-group-123',
  template: './@entry-group-123',
});

export const MyComponentView = (props) => {
    const state = getState(props);
    return (
      <div>
        <button on:click="./@my-counter-123">-</button>
        <span>{state.count}</span>
        <button on:click="./@my-counter-123#MyCounterDecrement">+</button>
      </div>
    );
  }
```

------

## 1) Developer's Source Code

**my-counter.tsx**

```typescript=

export const MyCounterView = qView<MyCounter>((props) => {
  const state = getState(props);
  return (
    <div>
      <button on:click={MyCounterIncrement}>+</button>
      <span>{state.count}</span>
    </div>
  );
});

export const MyCounterIncrement = qHandler<MyCounter>((props) => {
  const state = getState(props);
  state.count += props.step || 1;
  markDirty(props);
});

export const MyCounter = qComponent<MyCounter>({
  view: MyCounterView,
});
```

**my-app.tsx**

```typescript=

import { MyCounter } from './my-counter';

const MyAppView = qView<MyApp>(() => {
  return (
    <section>
      <MyCounter/>
    </section>
  );
});

export const MyApp = qComponent<MyApp>({
  view: MyAppView,
});
```


## 2) Generate Entry Files rollup will use as "input" option to start with

**entry-0**

```typescript=

export { MyCounterIncrement } from './my-counter';
```

**entry-1**

```typescript=

export { MyCounterView } from './my-counter';
```

**entry-2**

```typescript=

export { MyCounter } from './my-counter';
``` 

**entry-3**

```typescript=

export { MyAppView } from './my-app';
``` 

**entry-4**

```typescript=

export { MyApp } from './my-app';
``` 


## 3) Rewrite imports, after typescript to js transpiling, but before final JavaScript output

**my-counter.js**

- Rewrite local vars to dynamic imports of the generated entry paths

```typescript=
export const MyCounterView = qView((props) => {
  const state = getState(props);
  return (
    h("div", null, 
        h("button", { onClick: import("entry-0#MyCounterIncrement")}, "+"), 
        h("span", null, state.count)
    );
  );
});

export const MyCounterIncrement = qHandler((props) => {
  const state = getState(props);
  state.count += props.step || 1;
  markDirty(props);
});

export const MyCounter = qComponent({ 
  view: import('entry-1#MyCounterView'),
});
```

**my-app.js**

- Change ESM import url to generated entry paths

```typescript=
import { MyCounter } from 'entry-2';

const MyAppView = qView(() => {
    return h("section", null, h(MyCounter, null));
});

export const MyApp = qComponent({
  view: import('entry-3#MyAppView'),
});
```


## 4) Output JavaScript Files, rendering changes dynamic import()s to strings

**chunk-abc.js**

```typescript=

export const MyCounterIncrement = qHandler((props) => {
  const state = getState(props);
  state.count += props.step || 1;
  markDirty(props);
});
```

**chunk-cde.js**

```typescript=

export const MyCounterView = qView((props) => {
  const state = getState(props);
  return (
    <div>
      <button on:click="./chunk-abc#MyCounterIncrement">+</button>
      <span>{state.count}</span>
    </div>
  );
  return (
    h("div", null, 
        h("button", { onClick: './chunk-abc#MyCounterIncrement'}, "+"), 
        h("span", null, state.count)
    );
  );
});
```

**chunk-qrs.js**

```typescript=

export const MyCounter = qComponent({
  view: './chunk-cde.js#MyCounterView',
});
```

**chunk-xyz.js**

```typescript=

export const MyApp = qComponent({
  view: './chunk-qrs.js#MyCounterView'
});
```



---
```typescript=
export MyTestView = qView(() => (<button on:click={MyHandle}>...</button>));
```

```typescript=
export MyTestView = qView(() => (<button on:click={QRLSSR`my-handle.js#MyHandle`}>...</button>));
```

chunkMap = {
  'my-handle.js#MyHandle': './chunk-abc#click'
}

```htmlembedded=
<button on:click="./chunk-abc#click">...</button>
```

```typescript=
const qrlMap = /* @PURE */ new Map();

function h() {
  const symbol = prop['on:click'];
  if (DEV_MODE && isSymbol(symbol)) {
    const uuid = generateUUID();
    qrlMap.set(uuid, symbol);
    prop['on:click'] = uuid;
  }
}


export MyTestView = qView(() => (<button on:click={"UUID"}>...</button>));
```