@mantaq/lit 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anders Can
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,41 @@
1
- # Temporary Holding Version
1
+ > Experimental: API may change.
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # @mantaq/lit
4
+
5
+ Bind a mantaq actor into a [lit-html](https://lit.dev/docs/libraries/standalone-templates/) template with one function, `watch(actor, select)`. It renders `select(snapshot)` now and again on every change, synchronously, so the DOM is current when `send` returns.
6
+
7
+ ```sh
8
+ pnpm add @mantaq/lit lit-html
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { html, render } from "lit-html";
15
+ import { repeat } from "lit-html/directives/repeat.js";
16
+ import { watch } from "@mantaq/lit";
17
+
18
+ const row = (t: Todo) => html`<li data-id=${t.id}><span>${t.text}</span></li>`;
19
+
20
+ render(
21
+ html`<ul>
22
+ ${watch(todos, (s) => repeat(s.context.items, (t) => t.id, row))}
23
+ </ul>`,
24
+ document.body,
25
+ );
26
+ ```
27
+
28
+ `watch` subscribes while the part is connected and unsubscribes when it is cleared. Passing a new inline `select` on each render does not resubscribe, and the latest `select` is the one used. Passing a different actor moves the subscription.
29
+
30
+ ## Gotchas
31
+
32
+ These are pinned by `src/lit-assumptions.test.ts`.
33
+
34
+ - **Key lists by `id`.** `repeat(items, (t) => t.id, row)` keeps and moves the existing `<li>` elements and writes only the text that changed. Keying by object identity recreates every row whenever items are cloned, and a plain `items.map(row)` reuses rows by index, so removing the first item rewrites the text of every row after it.
35
+ - **Components that take an item as a property do not see in-place edits.** A custom element with `.item=${t}` compares by `Object.is`, so a handler that mutates `t` leaves it stale. Bind the fields (`.text=${t.text}`), or replace the changed item with a new object.
36
+ - **Selectors run on every change.** `watch` does not compare values, because an in-place edit returns the same array again and must still update the list. lit already skips equal primitives, so keep selectors cheap.
37
+ - **`prev.context === snap.context` after an in-place edit.** Compare fields, not contexts, when you detect changes yourself.
38
+
39
+ ## Not included
40
+
41
+ Scheduling options, value dedupe and a view-transition option (mantaq #296) are not part of this package yet.
@@ -0,0 +1,11 @@
1
+ import { DirectiveResult } from "lit-html/directive.js";
2
+ import { Snapshot } from "@mantaq/core";
3
+ type Watchable<C> = {
4
+ snapshot(): Snapshot<C>;
5
+ on(event: "change", options: {
6
+ fn: (snapshot: Snapshot<C>) => void;
7
+ }): () => void;
8
+ };
9
+ /** Binds a lit part to an actor: renders `select(snapshot)` now and on every change. */
10
+ export declare function watch<C, R>(actor: Watchable<C>, select: (snapshot: Snapshot<C>) => R): DirectiveResult;
11
+ export {};
package/dist/index.mjs ADDED
@@ -0,0 +1,48 @@
1
+ import { AsyncDirective } from "lit-html/async-directive.js";
2
+ import { directive } from "lit-html/directive.js";
3
+ // src/watch.ts
4
+ var WatchDirective = class extends AsyncDirective {
5
+ #actor;
6
+ #source;
7
+ #unsubscribe;
8
+ render(source) {
9
+ this.#source = source;
10
+ if (source.actor !== this.#actor) {
11
+ this.#stop();
12
+ this.#actor = source.actor;
13
+ if (this.isConnected) this.#start();
14
+ }
15
+ return source.read();
16
+ }
17
+ disconnected() {
18
+ this.#stop();
19
+ }
20
+ reconnected() {
21
+ this.#start();
22
+ if (this.#source) this.setValue(this.#source.read());
23
+ }
24
+ #start() {
25
+ const source = this.#source;
26
+ if (!source || this.#unsubscribe) return;
27
+ let seeding = true;
28
+ this.#unsubscribe = source.listen(() => {
29
+ if (seeding || !this.#source) return;
30
+ this.setValue(this.#source.read());
31
+ });
32
+ seeding = false;
33
+ }
34
+ #stop() {
35
+ this.#unsubscribe?.();
36
+ this.#unsubscribe = void 0;
37
+ }
38
+ };
39
+ const watchDirective = directive(WatchDirective);
40
+ /** Binds a lit part to an actor: renders `select(snapshot)` now and on every change. */
41
+ function watch(actor, select) {
42
+ return watchDirective({
43
+ actor,
44
+ read: () => select(actor.snapshot()),
45
+ listen: (fn) => actor.on("change", { fn })
46
+ });
47
+ }
48
+ export { watch };
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@mantaq/lit",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Bind mantaq actors into lit-html templates with one directive.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/AndersCan/mantaq",
9
+ "directory": "packages/lit"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "type": "module",
15
+ "exports": {
16
+ ".": "./dist/index.mjs",
17
+ "./package.json": "./package.json"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "devDependencies": {
23
+ "@typescript/native-preview": "7.0.0-dev.20260707.2",
24
+ "happy-dom": "^21.0.4",
25
+ "lit": "^3.3.0",
26
+ "lit-html": "^3.3.0",
27
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
28
+ "vite-plus": "1.4.0",
29
+ "@mantaq/core": "^0.6.0"
30
+ },
31
+ "peerDependencies": {
32
+ "lit-html": "^3.3.0",
33
+ "@mantaq/core": "^0.6.0"
34
+ },
35
+ "scripts": {
36
+ "build": "vp pack",
37
+ "dev": "vp pack --watch",
38
+ "test": "vp test",
39
+ "check": "vp check"
40
+ }
6
41
  }