obix-adapter-native 0.2.1

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/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # obix-adapter-native
2
+
3
+ **The Native projection — the only OBIX adapter that touches the DOM.**
4
+
5
+ ```bash
6
+ npm install obix-adapter-native
7
+ ```
8
+
9
+ ## API
10
+
11
+ ```ts
12
+ import { mount } from "obix-adapter-native";
13
+ const handle = mount(artifact, document.querySelector("#app"), { props: { limitSeconds: 5 } });
14
+ handle.instance.dispatch("Start");
15
+ handle.unmount();
16
+ ```
17
+
18
+ Builds the DOM from `artifact.template`, wires `obix-runtime` bindings by
19
+ child-index path, and drives state through the **reactive** projection — so every
20
+ transition still goes through `obix-ir.applyAction`.
21
+
22
+ ## Dependency role
23
+
24
+ `obix-spec`, `obix-ir`, `obix-adapter-reactive`, `obix-runtime`. It is the single
25
+ DOM boundary: SSR and the four pure adapters never import it, and
26
+ `obix-adapter-ssr` structurally cannot.
27
+
28
+ ## Level 0 status
29
+
30
+ ✅ `mount`, text / attribute / boolean / ARIA bindings, single-element `obix:if`,
31
+ native events, `every` effects. Deferred: loops, slots, composition, hydration.
@@ -0,0 +1,12 @@
1
+ import { type ReactiveInstance } from "obix-adapter-reactive";
2
+ import type { DOPArtifact, State, Props } from "obix-spec";
3
+ export interface MountHandle<S extends object, P extends object> {
4
+ instance: ReactiveInstance<S, P>;
5
+ unmount(): void;
6
+ }
7
+ export interface MountOptions<S extends object, P extends object> {
8
+ state?: S;
9
+ props?: Partial<P>;
10
+ }
11
+ export declare function mount<S extends object = State, P extends object = Props>(artifact: DOPArtifact<S, P>, container: Element, opts?: MountOptions<S, P>): MountHandle<S, P>;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAW1E,OAAO,KAAK,EACV,WAAW,EACX,KAAK,EACL,KAAK,EAGN,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IAC7D,QAAQ,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IAC9D,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpB;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAAE,CAAC,SAAS,MAAM,GAAG,KAAK,EACtE,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAM,GAC5B,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CA0EnB"}
package/dist/index.js ADDED
@@ -0,0 +1,112 @@
1
+ import { toReactive } from "obix-adapter-reactive";
2
+ import { bindText, bindAttr, bindBool, bindAria, bindEvent, bindPresence, createBindingGroup, } from "obix-runtime";
3
+ import { SCOPE_ATTR } from "obix-spec";
4
+ export function mount(artifact, container, opts = {}) {
5
+ if (!artifact.template) {
6
+ throw new Error(`[OBIX] mount("${artifact.name}"): artifact has no template descriptor`);
7
+ }
8
+ const instance = toReactive(artifact)(opts);
9
+ const group = createBindingGroup();
10
+ const scope = () => {
11
+ const s = instance.state;
12
+ const p = instance.props;
13
+ const d = {};
14
+ for (const [k, fn] of Object.entries(artifact.derived)) {
15
+ try {
16
+ d[k] = fn(instance.state, instance.props);
17
+ }
18
+ catch {
19
+ d[k] = undefined;
20
+ }
21
+ }
22
+ return { ...p, ...s, ...d };
23
+ };
24
+ const resolve = (expr) => {
25
+ const parts = expr.trim().split(".");
26
+ let cur = scope()[parts[0]];
27
+ for (let i = 1; i < parts.length && cur != null; i++)
28
+ cur = cur[parts[i]];
29
+ return cur;
30
+ };
31
+ const nodeByPath = new Map();
32
+ const root = buildElement(artifact.template.root, [], nodeByPath);
33
+ for (const b of artifact.template.bindings) {
34
+ const key = b.path.join(".");
35
+ const node = nodeByPath.get(key);
36
+ if (!node)
37
+ continue;
38
+ if (b.kind === "text") {
39
+ group.add(bindText(node, () => resolve(b.expr)));
40
+ }
41
+ else if (b.kind === "attr") {
42
+ group.add(bindAttr(node, b.target, () => resolve(b.expr)));
43
+ }
44
+ else if (b.kind === "bool") {
45
+ group.add(bindBool(node, b.target, () => resolve(b.expr)));
46
+ }
47
+ else if (b.kind === "aria") {
48
+ group.add(bindAria(node, b.target, () => resolve(b.expr)));
49
+ }
50
+ else if (b.kind === "conditional") {
51
+ const el = node;
52
+ const anchor = document.createComment(`obix:if ${b.expr}`);
53
+ el.parentNode?.insertBefore(anchor, el.nextSibling);
54
+ group.add(bindPresence(el, anchor, () => resolve(b.expr)));
55
+ }
56
+ }
57
+ for (const ev of artifact.template.events) {
58
+ const node = nodeByPath.get(ev.path.join("."));
59
+ if (!node)
60
+ continue;
61
+ group.addCleanup(bindEvent(node, ev.event, () => instance.dispatch(ev.action)));
62
+ }
63
+ const unsub = instance.subscribe(() => group.update());
64
+ if (artifact.style?.token)
65
+ root.setAttribute(SCOPE_ATTR, artifact.style.token);
66
+ container.appendChild(root);
67
+ instance.startEffects();
68
+ return {
69
+ instance,
70
+ unmount() {
71
+ instance.stopEffects();
72
+ unsub();
73
+ group.dispose();
74
+ root.remove();
75
+ },
76
+ };
77
+ }
78
+ function buildElement(el, path, index) {
79
+ const node = document.createElement(el.tag);
80
+ index.set(path.join("."), node);
81
+ for (const a of el.attrs) {
82
+ if (a.directive === "event" || a.directive === "conditional")
83
+ continue;
84
+ if (a.interpolation != null)
85
+ continue;
86
+ if (a.value === null)
87
+ node.setAttribute(a.name, "");
88
+ else
89
+ node.setAttribute(a.name, a.value);
90
+ }
91
+ el.children.forEach((child, i) => {
92
+ const childPath = [...path, i];
93
+ const dom = buildNode(child, childPath, index);
94
+ if (dom)
95
+ node.appendChild(dom);
96
+ });
97
+ return node;
98
+ }
99
+ function buildNode(node, path, index) {
100
+ if (node.kind === "text") {
101
+ const t = document.createTextNode(node.value.replace(/\s+/g, " "));
102
+ index.set(path.join("."), t);
103
+ return t;
104
+ }
105
+ if (node.kind === "interpolation") {
106
+ const t = document.createTextNode("");
107
+ index.set(path.join("."), t);
108
+ return t;
109
+ }
110
+ return buildElement(node, path, index);
111
+ }
112
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "obix-adapter-native",
3
+ "version": "0.2.1",
4
+ "description": "OBIX Native projection — the only adapter that touches the DOM. Mounts a component using the reactive projection + obix-runtime bindings. Depends on spec, ir, obix-adapter-reactive and obix-runtime.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "private": false,
8
+ "sideEffects": false,
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": ["dist", "README.md", "LICENSE"],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json"
21
+ },
22
+ "dependencies": {
23
+ "obix-spec": "0.2.1",
24
+ "obix-ir": "0.2.1",
25
+ "obix-adapter-reactive": "0.2.1",
26
+ "obix-runtime": "0.2.1"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "engines": {
32
+ "node": ">=20.11.0"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/obinexusmk2/obix-monorepo-2026.git",
37
+ "directory": "packages/obix-adapter-native"
38
+ }
39
+ }