@mindees/renderer 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.
Files changed (43) hide show
  1. package/LICENSE +31 -0
  2. package/README.md +129 -0
  3. package/dist/backend.d.ts +68 -0
  4. package/dist/backend.d.ts.map +1 -0
  5. package/dist/backend.js +9 -0
  6. package/dist/backend.js.map +1 -0
  7. package/dist/dom.d.ts +39 -0
  8. package/dist/dom.d.ts.map +1 -0
  9. package/dist/dom.js +125 -0
  10. package/dist/dom.js.map +1 -0
  11. package/dist/headless.d.ts +25 -0
  12. package/dist/headless.d.ts.map +1 -0
  13. package/dist/headless.js +116 -0
  14. package/dist/headless.js.map +1 -0
  15. package/dist/index.d.ts +32 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +36 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/native-command-backend.d.ts +71 -0
  20. package/dist/native-command-backend.d.ts.map +1 -0
  21. package/dist/native-command-backend.js +246 -0
  22. package/dist/native-command-backend.js.map +1 -0
  23. package/dist/native-host.d.ts +56 -0
  24. package/dist/native-host.d.ts.map +1 -0
  25. package/dist/native-host.js +125 -0
  26. package/dist/native-host.js.map +1 -0
  27. package/dist/native-protocol.d.ts +141 -0
  28. package/dist/native-protocol.d.ts.map +1 -0
  29. package/dist/native-protocol.js +135 -0
  30. package/dist/native-protocol.js.map +1 -0
  31. package/dist/native.d.ts +42 -0
  32. package/dist/native.d.ts.map +1 -0
  33. package/dist/native.js +59 -0
  34. package/dist/native.js.map +1 -0
  35. package/dist/render.d.ts +28 -0
  36. package/dist/render.d.ts.map +1 -0
  37. package/dist/render.js +145 -0
  38. package/dist/render.js.map +1 -0
  39. package/dist/ssr.d.ts +40 -0
  40. package/dist/ssr.d.ts.map +1 -0
  41. package/dist/ssr.js +31 -0
  42. package/dist/ssr.js.map +1 -0
  43. package/package.json +35 -0
package/dist/ssr.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { DomDocument, DomNode } from "./dom.js";
2
+ import { Mounted } from "./render.js";
3
+ import { Component, MindeesNode } from "@mindees/core";
4
+
5
+ //#region src/ssr.d.ts
6
+ /**
7
+ * Render an element tree (or component + props) to an HTML string on the server.
8
+ *
9
+ * Reactive bindings run once to produce the initial snapshot, then the scope is
10
+ * disposed (SSR is a one-shot render — no live updates on the server).
11
+ *
12
+ * @example
13
+ * const html = renderToString(App, {})
14
+ * // → "<div><span>hello</span></div>"
15
+ */
16
+ declare function renderToString(node: MindeesNode): string;
17
+ declare function renderToString<P>(component: Component<P>, props: P): string;
18
+ /**
19
+ * Hydrate a server-rendered container on the client: render the same tree with
20
+ * the DOM backend so reactive bindings attach and take over updates.
21
+ *
22
+ * NOTE: this is a **developer-preview** hydration. It currently renders into the
23
+ * (cleared) container rather than adopting existing DOM nodes in place;
24
+ * node-adopting hydration (zero re-create) is tracked for a later phase. The
25
+ * observable result — a live, reactive tree matching the server HTML — is
26
+ * correct today.
27
+ *
28
+ * @param container - The element whose contents were server-rendered.
29
+ * @param node - The same tree (element or component+props) used on the server.
30
+ * @param options - Optionally supply a `document` (e.g. for tests).
31
+ */
32
+ declare function hydrate(container: DomNode, node: MindeesNode, options?: {
33
+ document?: DomDocument;
34
+ }): Mounted<DomNode>;
35
+ declare function hydrate<P>(container: DomNode, component: Component<P>, props: P, options?: {
36
+ document?: DomDocument;
37
+ }): Mounted<DomNode>;
38
+ //#endregion
39
+ export { hydrate, renderToString };
40
+ //# sourceMappingURL=ssr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.d.ts","names":[],"sources":["../src/ssr.ts"],"mappings":";;;;;;;;;;;;;;;iBA0BgB,cAAA,CAAe,IAAiB,EAAX,WAAW;AAAA,iBAChC,cAAA,IAAkB,SAAA,EAAW,SAAA,CAAU,CAAA,GAAI,KAAA,EAAO,CAAA;AAAC;AAmCnE;;;;;;;;;;;;;AAnCmE,iBAmCnD,OAAA,CACd,SAAA,EAAW,OAAA,EACX,IAAA,EAAM,WAAA,EACN,OAAA;EAAY,QAAA,GAAW,WAAA;AAAA,IACtB,OAAA,CAAQ,OAAA;AAAA,iBACK,OAAA,IACd,SAAA,EAAW,OAAA,EACX,SAAA,EAAW,SAAA,CAAU,CAAA,GACrB,KAAA,EAAO,CAAA,EACP,OAAA;EAAY,QAAA,GAAW,WAAA;AAAA,IACtB,OAAA,CAAQ,OAAA"}
package/dist/ssr.js ADDED
@@ -0,0 +1,31 @@
1
+ import { createDomBackend, domTagFor } from "./dom.js";
2
+ import { createHeadlessBackend, createHeadlessRoot } from "./headless.js";
3
+ import { render } from "./render.js";
4
+ //#region src/ssr.ts
5
+ function renderToString(...args) {
6
+ const backend = createHeadlessBackend();
7
+ const root = createHeadlessRoot("#root");
8
+ const mounted = args.length === 2 ? render(args[0], args[1], backend, root) : render(args[0], backend, root);
9
+ try {
10
+ return root.children.map((child) => backend.serialize(child, { mapTag: domTagFor })).join("");
11
+ } finally {
12
+ mounted.dispose();
13
+ }
14
+ }
15
+ function hydrate(container, a, b, c) {
16
+ const looksLikeOptions = (v) => v === void 0 || typeof v === "object" && v !== null && Object.keys(v).every((k) => k === "document");
17
+ const isComponent = c !== void 0 || b !== void 0 && !looksLikeOptions(b);
18
+ const props = isComponent ? b : void 0;
19
+ const backend = createDomBackend(((isComponent ? c : b) ?? {}).document);
20
+ let child = container.firstChild ?? null;
21
+ while (child) {
22
+ const next = child.nextSibling;
23
+ container.removeChild(child);
24
+ child = next;
25
+ }
26
+ return isComponent ? render(a, props, backend, container) : render(a, backend, container);
27
+ }
28
+ //#endregion
29
+ export { hydrate, renderToString };
30
+
31
+ //# sourceMappingURL=ssr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.js","names":[],"sources":["../src/ssr.ts"],"sourcesContent":["/**\n * Server-side rendering for the web target.\n *\n * `renderToString` renders an element/component tree to crawlable HTML using the\n * headless backend (no DOM needed) — giving MindeesNative real SSR + SEO, which\n * Flutter Web's canvas renderer cannot. `hydrate` then attaches reactive\n * bindings to the server-rendered DOM on the client.\n *\n * @module\n */\n\nimport type { Component, MindeesNode } from '@mindees/core'\nimport { createDomBackend, type DomDocument, type DomNode, domTagFor } from './dom'\nimport { createHeadlessBackend, createHeadlessRoot } from './headless'\nimport { type Mounted, render } from './render'\n\n/**\n * Render an element tree (or component + props) to an HTML string on the server.\n *\n * Reactive bindings run once to produce the initial snapshot, then the scope is\n * disposed (SSR is a one-shot render — no live updates on the server).\n *\n * @example\n * const html = renderToString(App, {})\n * // → \"<div><span>hello</span></div>\"\n */\nexport function renderToString(node: MindeesNode): string\nexport function renderToString<P>(component: Component<P>, props: P): string\nexport function renderToString<P>(...args: [MindeesNode] | [Component<P>, P]): string {\n const backend = createHeadlessBackend()\n const root = createHeadlessRoot('#root')\n // Component form is the 2-arg call (a component + its props). A 1-arg call is\n // a node — including an accessor node `() => MindeesNode` — so we dispatch by\n // arity, not `typeof`.\n const mounted =\n args.length === 2\n ? render(args[0] as Component<P>, args[1] as P, backend, root)\n : render(args[0] as MindeesNode, backend, root)\n try {\n // Serialize with the web tag mapping so SSR HTML matches what the DOM\n // backend produces on hydration (view→div, text→span, …).\n return root.children.map((child) => backend.serialize(child, { mapTag: domTagFor })).join('')\n } finally {\n // SSR is one-shot: dispose bindings so nothing leaks on the server.\n mounted.dispose()\n }\n}\n\n/**\n * Hydrate a server-rendered container on the client: render the same tree with\n * the DOM backend so reactive bindings attach and take over updates.\n *\n * NOTE: this is a **developer-preview** hydration. It currently renders into the\n * (cleared) container rather than adopting existing DOM nodes in place;\n * node-adopting hydration (zero re-create) is tracked for a later phase. The\n * observable result — a live, reactive tree matching the server HTML — is\n * correct today.\n *\n * @param container - The element whose contents were server-rendered.\n * @param node - The same tree (element or component+props) used on the server.\n * @param options - Optionally supply a `document` (e.g. for tests).\n */\nexport function hydrate(\n container: DomNode,\n node: MindeesNode,\n options?: { document?: DomDocument },\n): Mounted<DomNode>\nexport function hydrate<P>(\n container: DomNode,\n component: Component<P>,\n props: P,\n options?: { document?: DomDocument },\n): Mounted<DomNode>\nexport function hydrate<P>(\n container: DomNode,\n a: MindeesNode | Component<P>,\n b?: P | { document?: DomDocument },\n c?: { document?: DomDocument },\n): Mounted<DomNode> {\n type Options = { document?: DomDocument }\n const looksLikeOptions = (v: unknown): v is Options =>\n v === undefined ||\n (typeof v === 'object' && v !== null && Object.keys(v).every((k) => k === 'document'))\n\n // `MindeesNode` includes the accessor form `() => MindeesNode`, so `typeof a`\n // can't tell a component from a node. Dispatch by arity/shape instead:\n // - a 4th arg (`c`) present ⇒ component form `(container, Component, props, options?)`.\n // - a 3rd arg (`b`) that is NOT a bare `{ document }` options object ⇒ also the\n // component form (props supplied without options).\n // - otherwise ⇒ node form `(container, node, options?)` where `b` is options.\n const isComponent = c !== undefined || (b !== undefined && !looksLikeOptions(b))\n const props = isComponent ? (b as P) : undefined\n const options: Options = (isComponent ? c : (b as Options | undefined)) ?? {}\n\n const backend = createDomBackend(options.document)\n\n // Current preview: clear server-rendered children, then render fresh and\n // attach bindings. Adopt-in-place hydration is a documented follow-up.\n let child = (container as DomNode & { firstChild?: DomNode | null }).firstChild ?? null\n while (child) {\n const next = child.nextSibling\n container.removeChild(child)\n child = next\n }\n\n return isComponent\n ? render(a as Component<P>, props as P, backend, container)\n : render(a as MindeesNode, backend, container)\n}\n"],"mappings":";;;;AA4BA,SAAgB,eAAkB,GAAG,MAAiD;CACpF,MAAM,UAAU,sBAAsB;CACtC,MAAM,OAAO,mBAAmB,OAAO;CAIvC,MAAM,UACJ,KAAK,WAAW,IACZ,OAAO,KAAK,IAAoB,KAAK,IAAS,SAAS,IAAI,IAC3D,OAAO,KAAK,IAAmB,SAAS,IAAI;CAClD,IAAI;EAGF,OAAO,KAAK,SAAS,KAAK,UAAU,QAAQ,UAAU,OAAO,EAAE,QAAQ,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE;CAC9F,UAAU;EAER,QAAQ,QAAQ;CAClB;AACF;AA2BA,SAAgB,QACd,WACA,GACA,GACA,GACkB;CAElB,MAAM,oBAAoB,MACxB,MAAM,KAAA,KACL,OAAO,MAAM,YAAY,MAAM,QAAQ,OAAO,KAAK,CAAC,EAAE,OAAO,MAAM,MAAM,UAAU;CAQtF,MAAM,cAAc,MAAM,KAAA,KAAc,MAAM,KAAA,KAAa,CAAC,iBAAiB,CAAC;CAC9E,MAAM,QAAQ,cAAe,IAAU,KAAA;CAGvC,MAAM,UAAU,mBAFU,cAAc,IAAK,MAA8B,CAAC,GAEnC,QAAQ;CAIjD,IAAI,QAAS,UAAwD,cAAc;CACnF,OAAO,OAAO;EACZ,MAAM,OAAO,MAAM;EACnB,UAAU,YAAY,KAAK;EAC3B,QAAQ;CACV;CAEA,OAAO,cACH,OAAO,GAAmB,OAAY,SAAS,SAAS,IACxD,OAAO,GAAkB,SAAS,SAAS;AACjD"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@mindees/renderer",
3
+ "version": "0.1.0",
4
+ "description": "MindeesNative Helix — fine-grained reactive renderer with a web/DOM backend, SSR + hydration, and a headless test backend. Native and GPU-canvas backends are research tracks.",
5
+ "license": "MIT OR Apache-2.0",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/mindees/mindees.git",
23
+ "directory": "packages/renderer"
24
+ },
25
+ "dependencies": {
26
+ "@mindees/core": "0.1.0"
27
+ },
28
+ "devDependencies": {
29
+ "happy-dom": "20.9.0"
30
+ },
31
+ "scripts": {
32
+ "build": "tsdown",
33
+ "typecheck": "tsc --noEmit"
34
+ }
35
+ }