open-index/open-npm huggingface dataset:
npm package: @li3/browser
Description: Browser APIs used to declare Li3 components
Latest version: 0.0.11

# @li3/browser

Browser APIs used to declare Li3 components

## Using it with HTML

```html
<template component="my-counter">
  <div>
    Count: {{ count }}
    <button on-click="add()">+</button>
    <button on-click="remove()">-</button>
  </div>
  <script setup>
    import { ref } from '@li3/browser';

    export default function () {
      const count = ref(0);

      return {
        count,
        add() { count.value++; },
        remove() { count.value--; },
      };
    }
  </script>
</template>
```

## Using it with ESM

```js
import { ref, createComponent } from '@li3/browser';

export const template = `
<div>
  Count: {{ count }}
  <button on-click="add()">+</button>
  <button on-click="remove()">-</button>
</div>
`

export function setup() {
  const count = ref(0);

  return {
    count,
    add() { count.value++; },
    remove() { count.value--; },
  };
}

createComponent('my-counter', { template, setup });
```
npm package: @li3/reactive
Description: Bring life to objects and react to their changes
Latest version: 0.0.23

# @li3/reactive

Bring life to objects and react to their changes

## Usage

Observe an object:

```ts
import { reactive } from "@li3/reactive";

const callback = () => console.log("A property has changed");
const object = { name: "", address: { street: "", number: 0 } };
const reactiveObject = reactive(object, callback);

// any value assigned to the reactive object properties (including objects) triggers a callback
reactiveObject.name = "Alice";
reactiveObject.address = { street: "1 Main St", number: 123 };
reactiveObject.address.number = 456;

// get back the original object
const originalObject = unwrap(reactiveObject);
```

Observe value holders (Refs):

```js
import { signal, effect, observer } from "@li3/reactive";

const value1 = signal(1);
const value2 = signal(2);
const computed = effect(() => value1.value + value2.value);

observer(computed, console.log);

// outputs "3" to console

value2.value = 5;

// outputs "6" to console
```
npm package: @li3/sfc
Description: Transform a single-file component into a component definition, or into an executable ES module with a custom element.
Latest version: 0.0.4

# @li3/sfc

Transform a single-file component into a component definition, or into an executable ES module with a custom element.

## Usage

```js
import { parseSFC, getComponentCode } from '@li3/sfc';

const sfc = parseSFC('<template><div>hello!</div></template>');
const code = getComponentCode('hello-world', sfc);
```

## Single-file components

A single-file component has usually two parts: a `template` and a `script`. Optionally, it can also have a `style` tag.

## `<template>`

A `template` can define options for [ShadowDOM](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow) in an attribute.
`shadow-dom` can either be a string or a JSON. For simplicity, `open` or `closed` are accepted as strings.
Otherwise, a JSON object with the same options passed to `element.attachShadow()` can also be provided.

If no shadow-dom attribute is provided, the component behaves like a regular DOM structure, with the content of `<template>` processed and appended to the custom element's root node.

## `<script>`

A `script` tag defines the code executed for every component instance.
The content inside the script tag is _implicitly_ wrapped by a function, which is then executed every time a new instance of a component
is initialized.

If a component has any `import` or `export` statement, any code between the _last_ import and the _first_ export is considered as setup code. Because export statements can use values that would be part of the source, in case a component needs to export values, a `setup` function **must** be defined, and called `defineComponent`. The conversion will fail otherwise.

## `<style>`

A `style` tag can be defined with styles that will be added to every component instance.

## Examples

A component with only setup code:

```html
<script>
  import { onInit } from '@li3/web';

  function componentLoaded() {
    // do something
  }

  onInit(componentLoaded);
</script>
```

A component with a template using shadowDom, a script and styles:

```html
<template component="greeting-card" shadow-dom="open">
  <div class="hello">Hello, {{ name }}!</div>

  <script setup>
    import { defineProps } from '@li3/web';

    export default function () {
      defineProps(['name']);
    }
  </script>

  <style>
    .hello {
      font-size: 3rem;
    }
  </style>
</template>
```

A component that has only a template:

```html
<template shadow-dom="open">
  <div>A static text with a tiny font size</div>
</template>
<style>
  div {
    font-size: 0.25rem;
  }
</style>
```

A component with imports and exports:

```html
<template>
  <div>{{color}}</div>
</template>
<script>
  import { defineProps } from '@li3/web';

  const validColors = ['red', 'blue', 'green'];

  function defineComponent() {
    defineProps(['color']);
  }

  export { validColors };
</script>
```
npm package: @li3/store
Description: Manage state and logic in one place.
Latest version: 0.1.76

# @li3/store

Manage state and logic in one place.

## What is a store?

Stores are a concept used in many different languages and frameworks.

In this library, a store is a place for adding _methods_ and keeping track of _state_ in one unit.
Methods, sometimes called **actions**, can change the internal state of a store.

The internal **state** is stored as a [Signal](/lib/reactive). To access that state, use `selectors`.

## Usage

First declare a store in a module

```js
// count-store.js
import { createStore } from '@li3/store';

export default createStore(
  { count: 0 },
  {
    add(state, amount) {
      state.count += amount;
    },
    remove(state, amount) {
      state.count -= amount;
    }
  }
);
```

Then import the store and dispatch actions:

```js
import countStore from './count-store.js';

// it's safe to import the same store many times
const { select, store } = countStore;

store.add(10)
store.remove(5);

// counter is a computed value
const counter = select((s) => s.count);
```

## Transactions

Stores can push multiple changes and run side effects within a single update cycle.
That can be done with a `.transaction()` call in the store:

```js
import countStore from './count-store.js';

const { store, transaction, events } = countStore;

events.addEventListener('commit', (state) => {...})

transaction(async () => {
  await store.increment(1);
  await store.increment(10);
  await store.decrement(5);
});
```

All intermediate states are not propagated to any selector.
When all actions are completely dispatched, the state is pushed into the store and all computed values reflect the changes.
npm package: @li3/web
Description: Browser APIs used to declare Li3 components
Latest version: 0.1.7

# @li3/web

Browser APIs used to declare Li3 components

## Feature flags

| Feature              | Description                                             | Default |
| -------------------- | ------------------------------------------------------- | ------- |
| debugEnabled         | Enable debug logs and throw exceptions                  | false   |
| useModuleExpressions | Use URL and import() to create expresions as modules    | false   |
| cachedTemplateFor    | Optimize DOM manipulation of template[for] with a cache | false   |

Set `window.name` to `debug` in any page to enable debugging on spot.
The name persists after a page reload.