Skip to content

Commit

Permalink
uhtml/ssr - Added both easy SSR and worker.js target
Browse files Browse the repository at this point in the history
  • Loading branch information
WebReflection committed Apr 13, 2024
1 parent a6f032c commit 0155993
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 126 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ types/
cjs/*
!cjs/package.json
dom.js
esm/init.js
init.js
esm/init*.js
init*.js
worker.js
keyed.js
!esm/keyed.js
!esm/dom/keyed.js
Expand All @@ -24,4 +25,4 @@ signal.js
!esm/signal.js
!esm/render/signal.js
preactive.js
!test/preactive.js
!test/preactive.js
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* **[uhtml/keyed](https://cdn.jsdelivr.net/npm/uhtml/keyed.js)** with extras `{ Hole, render, html, svg, htmlFor, svgFor, attr }`, providing keyed utilities - read [keyed or not ?](https://webreflection.github.io/uhtml/#keyed-or-not-) paragraph to know more
* **[uhtml/node](https://cdn.jsdelivr.net/npm/uhtml/node.js)** with *same default* exports but it's for *one-off* nodes creation only so that no cache or updates are available and it's just an easy way to hook *uhtml* into your existing project for DOM creation (not manipulation!)
* **[uhtml/init](https://cdn.jsdelivr.net/npm/uhtml/init.js)** which returns a `document => uhtml/keyed` utility that can be bootstrapped with `uhtml/dom`, [LinkeDOM](https://github.com/WebReflection/linkedom), [JSDOM](https://github.com/jsdom/jsdom) for either *SSR* or *Workers* support
* **uhtml/ssr** which exports an utility that both SSR or Workers can use to parse and serve documents. This export provides same keyed utilities except the keyed feature is implicitly disabled as that's usually not desirable at all for SSR or rendering use cases, actually just an overhead. This might change in the future but for now I want to benchmark and see how competitive is `uhtml/ssr` out there. The `uhtml/dom` is also embedded in this export because the `Comment` class needs an override to produce a super clean output (at least until hydro story is up and running).
* **[uhtml/dom](https://cdn.jsdelivr.net/npm/uhtml/dom.js)** which returns a specialized *uhtml* compliant DOM environment that can be passed to the `uhtml/init` export to have 100% same-thing running on both client or Web Worker / Server. This entry exports `{ Document, DOMParser }` where the former can be used to create a new *document* while the latter one can parse well formed HTML or SVG content and return the document out of the box.
* **[uhtml/reactive](https://cdn.jsdelivr.net/npm/uhtml/reactive.js)** which allows usage of symbols within the optionally *keyed* render function. The only difference with other exports, beside exporting a `reactive` field instead of `render`, so that `const render = reactive(effect)` creates a reactive render per each library, is that the `render(where, () => what)`, with a function as second argument is mandatory when the rendered stuff has signals in it, otherwise these can't side-effect properly.
* **[uhtml/signal](https://cdn.jsdelivr.net/npm/uhtml/signal.js)** is an already bundled `uhtml/reactive` with `@webreflection/signal` in it, so that its `render` exported function is already reactive. This is the smallest possible bundle as it's ~3.3Kb but it's not nearly as complete, in terms of features, as *preact* signals are.
Expand Down
10 changes: 1 addition & 9 deletions esm/creator.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { PersistentFragment } from './persistent-fragment.js';
import { bc, detail } from './literals.js';
import { array, hole } from './handler.js';
import { empty } from './utils.js';
import { empty, find } from './utils.js';
import { cache } from './literals.js';

/**
* @param {DocumentFragment} content
* @param {number[]} path
* @returns {Element}
*/
const find = (content, path) => path.reduceRight(childNodesIndex, content);
const childNodesIndex = (node, i) => node.childNodes[i];

/** @param {(template: TemplateStringsArray, values: any[]) => import("./parser.js").Resolved} parse */
export default parse => (
/**
Expand Down
3 changes: 2 additions & 1 deletion esm/persistent-fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class PersistentFragment extends custom(DocumentFragment) {
remove(this, true).replaceWith(node);
}
valueOf() {
let { firstChild, lastChild, parentNode } = this;
const { parentNode } = this;
if (parentNode === this) {
if (this.#nodes === empty)
this.#nodes = [...this.childNodes];
Expand All @@ -65,6 +65,7 @@ export class PersistentFragment extends custom(DocumentFragment) {
// This is a render-only specific issue but it's tested and
// it's worth fixing to me to have more consistent fragments.
if (parentNode) {
let { firstChild, lastChild } = this;
this.#nodes = [firstChild];
while (firstChild !== lastChild)
this.#nodes.push((firstChild = firstChild.nextSibling));
Expand Down
6 changes: 3 additions & 3 deletions esm/rabbit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { cache } from './literals.js';
import create from './creator.js';
import parser from './parser.js';

const parseHTML = create(parser(false));
const parseSVG = create(parser(true));
const createHTML = create(parser(false));
const createSVG = create(parser(true));

/**
* @param {import("./literals.js").Cache} info
Expand All @@ -13,7 +13,7 @@ const parseSVG = create(parser(true));
*/
const unroll = (info, { s, t, v }) => {
if (info.a !== t) {
const { b, c } = (s ? parseSVG : parseHTML)(t, v);
const { b, c } = (s ? createSVG : createHTML)(t, v);
info.a = t;
info.b = b;
info.c = c;
Expand Down
6 changes: 6 additions & 0 deletions esm/ssr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Hole, render, html, svg, attr } from './index.js';

const htmlFor = () => html;
const svgFor = () => svg;

export { Hole, render, html, svg, htmlFor, svgFor, attr };
10 changes: 10 additions & 0 deletions esm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ export const gPD = (ref, prop) => {
while(!desc && (ref = getPrototypeOf(ref)));
return desc;
};

/* c8 ignore start */
/**
* @param {DocumentFragment} content
* @param {number[]} path
* @returns {Element}
*/
export const find = (content, path) => path.reduceRight(childNodesIndex, content);
const childNodesIndex = (node, i) => node.childNodes[i];
/* c8 ignore stop */
138 changes: 69 additions & 69 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0155993

Please sign in to comment.