Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ryansolid committed Apr 27, 2020
1 parent 811911a commit 91787da
Show file tree
Hide file tree
Showing 13 changed files with 353 additions and 391 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ What is the reactive core file. It exports an object with the methods required b
Example:

```js
import S, { value, sample } from "s-js";
import S, { root, value, sample } from "s-js";

export default {
root,
effect: S,
memo: (fn, equal) => {
if (!equal) return S(fn);
Expand Down
3 changes: 2 additions & 1 deletion packages/dom-expressions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ What is the reactive core file. It exports an object with the methods required b
Example:

```js
import S, { value, sample } from "s-js";
import S, { root, value, sample } from "s-js";

export default {
root,
effect: S,
memo: (fn, equal) => {
if (!equal) return S(fn);
Expand Down
41 changes: 23 additions & 18 deletions packages/dom-expressions/src/runtime.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
export function render(code: () => any, element: MountableElement): () => void
export function renderToString(
fn: (done?: (rendered: any) => void) => any,
options?: {
timeoutMs?: number;
}
): Promise<string>;
export function renderDOMToString(
fn: (done?: (rendered: any) => void) => any,
options?: {
timeoutMs?: number;
}
): Promise<string>;
export function hydrate(
fn: () => unknown,
node: MountableElement
): void;

export function template(html: string, count: number, isSVG?: boolean): Element;
export function effect<T>(fn: (prev?: T) => T, init?: T): any;
export function memo(fn: () => any, equal: boolean): () => any;
export function insert(
parent: Element | Document | ShadowRoot | DocumentFragment | Node,
parent: MountableElement,
accessor: any,
init?: any,
marker?: Node
marker?: Node | null
): any;
export function createComponent(Comp: (props: any) => any, props: any, dynamicKeys?: string[]): any;
export function delegateEvents(eventNames: string[]): void;
Expand All @@ -22,26 +41,12 @@ export function style(
prev?: { [k: string]: string }
): void;
export function currentContext(): any;
export function renderToString(
fn: (done?: (rendered: any) => void) => any,
options?: {
timeoutMs?: number;
}
): Promise<string>;

export function ssr(template: TemplateStringsArray, ...nodes: any[]): () => string;
export function ssrClassList(value: { [k: string]: boolean }): string;
export function ssrStyle(value: { [k: string]: string }): string;
export function ssrSpread(accessor: any, isSVG: boolean, skipChildren: boolean): () => string;
export function renderDOMToString(
fn: (done?: (rendered: any) => void) => any,
options?: {
timeoutMs?: number;
}
): Promise<string>;
export function hydrate(
fn: () => unknown,
node: Element | Document | ShadowRoot | DocumentFragment | Node
): void;

export function getHydrationKey(): string;
export function getNextElement(template: HTMLTemplateElement, isSSR: boolean): Node;
export function getNextMarker(start: Node): [Node, Array<Node>];
Expand Down
116 changes: 63 additions & 53 deletions packages/dom-expressions/src/runtime.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,70 @@
import { Attributes, SVGAttributes, NonComposedEvents } from "./constants";
import { dynamicProp, cleanChildren, appendNodes, normalizeIncomingArray } from "./utils";
import { dynamicProperty, cleanChildren, appendNodes, normalizeIncomingArray } from "./utils";
import reconcileArrays from "./reconcile";
import core from "rxcore";

const eventRegistry = new Set();
let { config = {}, effect, memo, ignore, currentContext, createComponent } = core;
const eventRegistry = new Set(),
{ config = {}, root, effect, memo, ignore, currentContext, createComponent: cc } = core,
createComponent =
cc ||
((Comp, props, dynamicKeys) => {
if (dynamicKeys) {
for (let i = 0; i < dynamicKeys.length; i++) dynamicProperty(props, dynamicKeys[i]);
}
return ignore(() => Comp(props));
});

createComponent ||
(createComponent = (Comp, props, dynamicKeys) => {
if (dynamicKeys) {
for (let i = 0; i < dynamicKeys.length; i++) dynamicProp(props, dynamicKeys[i]);
}
return ignore(() => Comp(props));
export { effect, memo, createComponent, currentContext };

export function render(code, element) {
let disposer;
root(dispose => {
disposer = dispose;
insert(element, code());
});
return disposer;
}

export { effect, memo, createComponent, currentContext };
export function renderToString(code, options = {}) {
options = { timeoutMs: 30000, ...options };
config.hydrate = { id: "", count: 0 };
return root(async () => {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject("renderToString timed out"), options.timeoutMs)
);
const rendered = await Promise.race([code(), timeout]);
return resolveSSRNode(rendered);
});
}

export function renderDOMToString(code, options = {}) {
options = { timeoutMs: 30000, ...options };
config.hydrate = { id: "", count: 0 };
const container = document.createElement("div");
document.body.appendChild(container);
return root(async d1 => {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject("renderDOMToString timed out"), options.timeoutMs)
);
const rendered = await Promise.race([code(), timeout]);
root(d2 => (insert(container, rendered), d1(), d2()));
const html = container.innerHTML;
document.body.removeChild(container);
return html;
});
}

export function hydrate(code, element) {
config.hydrate = { id: "", count: 0, registry: new Map() };
const templates = element.querySelectorAll(`*[_hk]`);
for (let i = 0; i < templates.length; i++) {
const node = templates[i];
config.hydrate.registry.set(node.getAttribute("_hk"), node);
}
const dispose = render(code, element);
delete config.hydrate;
return dispose;
}

export function template(html, check, isSVG) {
const t = document.createElement("template");
Expand Down Expand Up @@ -86,19 +136,6 @@ export function insert(parent, accessor, marker, initial) {
}

// SSR
export function renderToString(code, options = {}) {
options = { timeoutMs: 30000, ...options };
config.hydrate = { id: "", count: 0 };
return new Promise((resolve, reject) => {
setTimeout(() => reject("renderToString timed out"), options.timeoutMs);
function render(rendered) {
if (typeof rendered === "function") resolve(rendered());
else resolve(rendered);
}
!code.length ? render(code()) : code(render);
});
}

export function ssr(template, ...nodes) {
const rNodes = [];
for (let i = 0; i < nodes.length; i++) {
Expand Down Expand Up @@ -162,33 +199,6 @@ export function ssrSpread(props, isSVG) {
}

// Hydrate
export function renderDOMToString(code, options = {}) {
options = { timeoutMs: 30000, ...options };
config.hydrate = { id: "", count: 0 };
const container = document.createElement("div");
document.body.appendChild(container);
return new Promise((resolve, reject) => {
setTimeout(() => reject("renderDOMToString timed out"), options.timeoutMs);
function render(rendered) {
insert(container, rendered);
resolve(container.innerHTML);
document.body.removeChild(container);
}
!code.length ? render(code()) : code(render);
});
}

export function hydrate(code, root) {
config.hydrate = { id: "", count: 0, registry: new Map() };
const templates = root.querySelectorAll(`*[_hk]`);
for (let i = 0; i < templates.length; i++) {
const node = templates[i];
config.hydrate.registry.set(node.getAttribute("_hk"), node);
}
code();
delete config.hydrate;
}

export function getHydrationKey() {
const hydrate = config.hydrate;
return `${hydrate.id}:${hydrate.count++}`;
Expand Down Expand Up @@ -310,7 +320,7 @@ function spreadExpression(node, props, prevProps = {}, isSVG, skipChildren) {
if (info.type === "attribute") {
node.setAttribute(prop, value);
} else node[info.alias] = value;
} else if (isSVG) {
} else if (isSVG || prop.indexOf("-") > -1) {
if ((info = SVGAttributes[prop])) {
if (info.alias) node.setAttribute(info.alias, value);
else node.setAttribute(prop, value);
Expand Down Expand Up @@ -402,7 +412,7 @@ function toSSRAttribute(key, isSVG) {
}

function resolveSSRNode(node) {
if (Array.isArray(node)) node.map(resolveSSRNode);
if (typeof node === "function") node = node();
if (Array.isArray(node)) return node.map(resolveSSRNode).join("");
if (typeof node === "function") node = resolveSSRNode(node());
return typeof node === "string" ? node : JSON.stringify(node);
}
2 changes: 1 addition & 1 deletion packages/dom-expressions/src/utils.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function dynamicProp(props: any, key: string): void;
export function dynamicProperty(props: any, key: string): void;

export function normalizeIncomingArray(normalized: any[], array: any[], unwrap: boolean): boolean;

Expand Down
2 changes: 1 addition & 1 deletion packages/dom-expressions/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function dynamicProp(props, key) {
export function dynamicProperty(props, key) {
const src = props[key];
Object.defineProperty(props, key, {
get() {
Expand Down
7 changes: 4 additions & 3 deletions packages/dom-expressions/test/core.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import S, { value, sample } from "s-js";
import S, { root, value, sample } from "s-js";
import { sharedConfig } from "./hydrate.config";
import { dynamicProp } from "../src/utils";
import { dynamicProperty } from "../src/utils";

export default {
config: sharedConfig,
createComponent(Comp, props, dynamicKeys) {
if (dynamicKeys) {
for (let i = 0; i < dynamicKeys.length; i++) dynamicProp(props, dynamicKeys[i]);
for (let i = 0; i < dynamicKeys.length; i++) dynamicProperty(props, dynamicKeys[i]);
}

if (Comp.prototype && Comp.prototype.isClassComponent) {
Expand All @@ -18,6 +18,7 @@ export default {

return sample(() => Comp(props));
},
root,
effect: S,
memo: (fn, equal) => {
if (!equal) return S(fn);
Expand Down
Loading

0 comments on commit 91787da

Please sign in to comment.