Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript definition changes and explaining Sinuous internals #114

Closed
wants to merge 9 commits into from
Closed
7 changes: 5 additions & 2 deletions packages/sinuous/h/src/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ const castNode = (value) => {
if (typeof value === 'string') {
return document.createTextNode(value);
}
// Note that a DocumentFragment is an instance of Node
if (!(value instanceof Node)) {
// Passing an empty array creates a DocumentFragment.
// Passing an empty array creates a DocumentFragment
// Note this means api.add is not purely a subcall of api.h; it can nest
return api.h(EMPTY_ARR, value);
}
return value;
Expand All @@ -32,7 +34,8 @@ const frag = (value) => {

/**
* Add a string or node before a reference node or at the end.
* @typedef {(parent: Node, value: Node | string | number, endMark: Node?) => Node | Frag} hAdd
* @typedef {Node | string | number} Value
* @typedef {(parent: Node, value: Value | Value[], endMark: Node?) => Node | Frag} hAdd
* @type {hAdd}
*/
export const add = (parent, value, endMark) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/sinuous/h/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Internal API.
* Consumer must provide an observable at api.subscribe<T>(observer: () => T).
*
* @typedef {0 | 1} hSVG Determines if `h` will build HTML or SVG elements
* @typedef {boolean} hSVG Determines if `h` will build HTML or SVG elements
* @type {{
* h: import('./h.js').hTag
* s: hSVG
Expand Down
2 changes: 1 addition & 1 deletion packages/sinuous/h/src/h.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { api } from './api.js';
* @typedef {(tag: string? | [], props: object?, ...children: Node | *) => DOM} hTag
* @type {hTag}
*/
// eslint-disable-next-line fp/no-rest-parameters

export const h = (...args) => {
let el;
const item = (/** @type {*} */ arg) => {
Expand Down
14 changes: 9 additions & 5 deletions packages/sinuous/h/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,35 @@ declare namespace _h {
Record<string, unknown>
| null,
...children: ElementChildren[]
): HTMLElement;
): HTMLElement | SVGElement;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We merged this file earlier in my ts-work branch but really I'm lying to people to say it's only HTMLElement in h/index.d.ts - It's true that later on in src/index.d.ts and jsx/index.d.ts the types are redefined to be more narrow, but until then it's good to define the reviver as generic for both HTML/SVG

function h(
type: FunctionComponent,
props:
| (JSXInternal.HTMLAttributes | JSXInternal.SVGAttributes) &
Record<string, unknown>
| null,
...children: ElementChildren[]
): HTMLElement;
): HTMLElement | SVGElement | DocumentFragment;
function h(
children: ElementChildren[]
tag: ElementChildren[] | [],
...children: ElementChildren[]
): DocumentFragment;
namespace h {
export import JSX = JSXInternal;
}
}

type Frag = { _startMark: Text }
type Value = Node | DocumentFragment | string | number

export interface HyperscriptApi {
// Hyperscript
h: typeof _h.h;

// Internal API
insert<T>(el: Node, value: T, endMark?: Node, current?: T, startNode?: Node): T;
insert<T>(el: Node, value: T, endMark?: Node, current?: T | Frag, startNode?: Node): T | Frag;
property(el: Node, value: unknown, name: string, isAttr?: boolean, isCss?: boolean): void;
add(parent: Node, value: Node | string, endMark?: Node): Node;
add(parent: Node, value: Value | Value[], endMark?: Node): Node | Frag;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... Frag is mostly an internal concept, but for anyone writing wrappers (aka anyone actually bothering to touch api.add) it's probably good to mention

rm(parent: Node, startNode: Node, endMark: Node): void;

// Required from an observable implmentation
Expand Down
5 changes: 3 additions & 2 deletions packages/sinuous/h/src/insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { api } from './api.js';

/**
* @typedef {import('./add.js').Frag} Frag
* @typedef {(el: Node, value: *, endMark: Node?, current: (Node | Frag)?, startNode: Node?) => Node} hInsert
* @typedef {(el: Node, value: *, endMark: Node?, current: (Node | Frag)?,
* startNode: Node?) => Node | Frag } hInsert
* @type {hInsert}
*/
export const insert = (el, value, endMark, current, startNode) => {
Expand Down Expand Up @@ -64,5 +65,5 @@ export const insert = (el, value, endMark, current, startNode) => {
}
}

return /** @type {Node} */ (current);
return current;
};
13 changes: 7 additions & 6 deletions packages/sinuous/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ declare namespace sinuous {
Record<string, unknown>
| null,
...children: ElementChildren[]
): HTMLElement;
): HTMLElement | DocumentFragment;
function h(
children: ElementChildren[]
tag: ElementChildren[] | [],
...children: ElementChildren[]
): DocumentFragment;
namespace h {
export import JSX = JSXInternal;
Expand All @@ -62,9 +63,10 @@ declare namespace sinuous {
Record<string, unknown>
| null,
...children: ElementChildren[]
): SVGElement;
): SVGElement | DocumentFragment;
function hs(
children: ElementChildren[]
tag: ElementChildren[] | [],
...children: ElementChildren[]
): DocumentFragment;
namespace hs {
export import JSX = JSXInternal;
Expand All @@ -73,8 +75,7 @@ declare namespace sinuous {
/** Sinuous API */
interface SinuousApi extends HyperscriptApi {
// Hyperscript
h: typeof h;
hs: typeof hs;
hs: <T extends () => unknown>(closure: T) => ReturnType<T>;

// Observable
subscribe: typeof _o.subscribe;
Expand Down
6 changes: 3 additions & 3 deletions packages/sinuous/src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Sinuous by Wesley Luyten (@luwes).
* Really ties all the packages together.
*/
* Sinuous by Wesley Luyten (@luwes).
* Really ties all the packages together.
*/
import {
o,
observable,
Expand Down