+149
-161
| // Minimum TypeScript Version: 4.2 | ||
| // This requires every property of an object or none at all. | ||
| type AllOrNothing<T> = T | { [K in keyof T]?: never } | ||
| // This ensures at least one property in an object is present. | ||
| type AtLeastOne<T> = { [K in keyof T]: Pick<T, K> }[keyof T] | ||
| // Credit: https://stackoverflow.com/a/59987826/1935675 | ||
| // This ensures at least one object property group is present. | ||
| type AtLeastSomething<T, U> = U | AtLeastOne<T> & AllOrNothing<U> | ||
| // Most event typings are provided by TypeScript itself. | ||
| type EventsMap = | ||
| & { [K in keyof HTMLElementEventMap as `on${K}`]: HTMLElementEventMap[K] } | ||
| & { [K in keyof WindowEventMap as `on${K}`]: WindowEventMap[K] } | ||
| & { onsearch: Event } | ||
| // Indexable values are able to use subscripting. | ||
| type Indexable = string | unknown[] | Record<string, any> | ||
| // This validates plain objects while invalidating array objects and string | ||
| // objects by disallowing numerical indexing. | ||
| type IndexableByKey = Record<number, never> | ||
| // Empty strings can cause issues in certain places. | ||
| type NonEmptyString<T> = T extends "" ? never : T | ||
| // ----------------------------------------------------------------------------- | ||
| declare module "hyperapp" { | ||
| // `app()` initiates a Hyperapp instance. `app()` along with runners and | ||
| // subscribers are the only places where side effects are allowed. | ||
| // `app()` initiates a Hyperapp instance. Only `app()`'s `node:` property and | ||
| // effecters and subscribers are allowed to have side effects. | ||
| function app<S>(props: App<S>): Dispatch<S> | ||
@@ -10,105 +38,81 @@ | ||
| function h<S, C = unknown, T extends string = string>( | ||
| // Tags cannot be empty strings. | ||
| tag: T extends "" ? never : T, | ||
| props: ValidateCustomPayloads<S, C> & PropList<S>, | ||
| children?: MaybeVDOM<S> | readonly MaybeVDOM<S>[] | ||
| ): VDOM<S> | ||
| tag: NonEmptyString<T>, | ||
| props: CustomPayloads<S, C> & Props<S>, | ||
| children?: MaybeVNode<S> | readonly MaybeVNode<S>[] | ||
| ): VNode<S> | ||
| // `memo()` stores a view along with any given data for it. | ||
| function memo< | ||
| S, | ||
| D extends string | unknown[] | Record<string, any> = | ||
| | string | ||
| | unknown[] | ||
| | Record<string, any> | ||
| >(view: View<D>, data: D): VDOM<S> | ||
| function memo<S, D extends Indexable = Indexable>( | ||
| view: (data: D) => VNode<S>, | ||
| data: D | ||
| ): VNode<S> | ||
| // `text()` creates a virtual DOM node representing plain text. | ||
| function text<S, T = unknown>( | ||
| // While most values can be stringified, symbols and functions cannot. | ||
| value: T extends symbol | ((..._: any[]) => any) ? never : T | ||
| ): VDOM<S> | ||
| // Values, aside from symbols and functions, can be handled. | ||
| value: T extends symbol | ((..._: unknown[]) => unknown) ? never : T | ||
| ): VNode<S> | ||
| // --------------------------------------------------------------------------- | ||
| // This lets you use a version of `h` which assumes your particular app state. | ||
| // The `_ extends never` ensures that any such state-aware `h` doesn't have | ||
| // an explicitly set state type that contradicts the type it actually uses. | ||
| // This lets you make a variant of `h()` which is aware of your Hyperapp | ||
| // instance's state. The `_ extends never` ensures that any state-aware | ||
| // `h()` doesn't have an explicit state type that contradicts the | ||
| // state type it actually uses. | ||
| interface TypedH<S> { | ||
| <_ extends never, T extends string = string>( | ||
| tag: T extends "" ? never : T, | ||
| props: PropList<S>, | ||
| children?: MaybeVDOM<S> | readonly MaybeVDOM<S>[] | ||
| ): VDOM<S> | ||
| <_ extends never, C = unknown, T extends string = string>( | ||
| tag: NonEmptyString<T>, | ||
| props: CustomPayloads<S, C> & Props<S>, | ||
| children?: MaybeVNode<S> | readonly MaybeVNode<S>[] | ||
| ): VNode<S> | ||
| } | ||
| // This helper for `h` lets event handling actions accept custom payloads. | ||
| type ValidateCustomPayloads<S, T> = { | ||
| [K in keyof T]?: K extends "style" | ||
| ? StyleProp | ||
| : T[K] extends [Action<S, infer P>, unknown] | ||
| ? [Action<S, P>, P] | ||
| : T[K] | ||
| } | ||
| // --------------------------------------------------------------------------- | ||
| // This utility type requires every property of an object or none at all. | ||
| // `App` uses this to make sure `view:` always appears alongside `node:`. | ||
| type AllOrNothing<T> = T | { [K in keyof T]?: never } | ||
| // An action transforms existing state and/or wraps another action. | ||
| type Action<S, P = any> = (state: S, payload: P) => Dispatchable<S> | ||
| // This utility type ensures at least one property in an object to be present. | ||
| // `App` uses this to conveniently invalidate `app({})` because that is | ||
| // basically a fancy no-op. | ||
| type AtLeastOne<T> = { [K in keyof T]: Pick<T, K> }[keyof T] | ||
| // Credit: https://stackoverflow.com/a/59987826/1935675 | ||
| // This utility type validates plain objects while invalidating array objects | ||
| // and string objects by disallowing numerical indexing. Used by `StyleProp`. | ||
| type IndexableByKey = Record<number, never> | ||
| // --------------------------------------------------------------------------- | ||
| // A Hyperapp instance generally has an initial state and a base view and is | ||
| // A Hyperapp instance typically has an initial state and a top-level view | ||
| // mounted over an available DOM element. | ||
| type App<S> = Readonly< | ||
| | { | ||
| view: View<S> | ||
| node: Node | ||
| } | ||
| | (AtLeastOne<{ | ||
| init: Dispatchable<S> | ||
| subscriptions: Subscriptions<S> | ||
| dispatch: DispatchInitializer<S> | ||
| }> & | ||
| AllOrNothing<{ | ||
| view: View<S> | ||
| node: Node | ||
| }>) | ||
| > | ||
| type App<S> = | ||
| Readonly<AtLeastSomething<{ | ||
| // State is established through either direct assignment or an action. | ||
| init: Dispatchable<S> | ||
| // A view builds a virtual DOM node representation of the application state. | ||
| type View<S> = (state: S) => VDOM<S> | ||
| // The subscriptions function manages a set of subscriptions. | ||
| subscriptions: (state: S) => | ||
| readonly (boolean | undefined | Subscription<S>)[] | ||
| // The subscriptions function manages a set of subscriptions. | ||
| type Subscriptions<S> = ( | ||
| state: S | ||
| ) => (boolean | undefined | Subscription<S> | Unsubscribe)[] | ||
| // Dispatching can be augmented to do custom processing. | ||
| dispatch: (dispatch: Dispatch<S>) => Dispatch<S> | ||
| }, { | ||
| // The top-level view can build a virtual DOM node depending on the state. | ||
| view: (state: S) => VNode<S> | ||
| // A subscription reacts to external activity. | ||
| type Subscription<S, P = any> = [ | ||
| subscriber: (dispatch: Dispatch<S>, payload: P) => void | Unsubscribe, | ||
| payload: P | ||
| ] | ||
| // The mount node is where a Hyperapp instance will get placed. | ||
| node: Node | ||
| }>> | ||
| // An unsubscribe function cleans up a canceled subscription. | ||
| type Unsubscribe = () => void | ||
| // The `class` property represents an HTML class attribute string. | ||
| type ClassProp = | ||
| | boolean | ||
| | string | ||
| | undefined | ||
| | Record<string, boolean | undefined> | ||
| | ClassProp[] | ||
| // Dispatching can be augmented to do custom processing. | ||
| type DispatchInitializer<S> = (dispatch: Dispatch<S>) => Dispatch<S> | ||
| // This lets event-handling actions properly accept custom payloads. | ||
| type CustomPayloads<S, T> = { | ||
| [K in keyof T]?: | ||
| K extends "style" | ||
| ? StyleProp | ||
| : T[K] extends [action: Action<S, infer P>, payload: unknown] | ||
| ? readonly [action: Action<S, P>, payload: P] | ||
| : T[K] | ||
| } | ||
| // --------------------------------------------------------------------------- | ||
| // Dispatching will cause state transitions. | ||
| type Dispatch<S> = (dispatchable: Dispatchable<S>, payload?: unknown) => void | ||
| // A dispatched action handles an event in the context of the current state. | ||
| type Dispatch<S> = (dispatchable: Dispatchable<S>, payload?: any) => void | ||
| // A dispatchable entity, when processed, causes a state transition. | ||
| // A dispatchable entity is used to cause a state transition. | ||
| type Dispatchable<S, P = any> = | ||
@@ -118,9 +122,6 @@ | S | ||
| | Action<S, P> | ||
| | [action: Action<S, P>, payload: P] | ||
| | readonly [action: Action<S, P>, payload: P] | ||
| // An action transforms existing state and/or wraps another action. | ||
| type Action<S, P = any> = (state: S, payload: P) => Dispatchable<S> | ||
| // An effect is where side effects and any additional dispatching may occur. | ||
| type Effect<S, P = any> = [ | ||
| type Effect<S, P = any> = readonly [ | ||
| effecter: (dispatch: Dispatch<S>, payload: P) => void | Promise<void>, | ||
@@ -130,42 +131,14 @@ payload: P | ||
| // --------------------------------------------------------------------------- | ||
| // A virtual DOM node represents an actual DOM element. | ||
| type VDOM<S> = { | ||
| readonly type: VDOMNodeType | ||
| readonly props: PropList<S> | ||
| readonly children: MaybeVDOM<S>[] | ||
| node: null | undefined | Node | ||
| readonly tag: Tag<S> | ||
| readonly key: Key | ||
| memo?: PropList<S> | ||
| events?: Record<string, Action<S> | [action: Action<S>, payload: any]> | ||
| // `_VDOM` is a guard property which gives us a way to tell `VDOM` objects | ||
| // apart from `PropList` objects. Since we don't expect users to manually | ||
| // create their own VNodes, we can take advantage of this trick that's | ||
| // specific to TypeScript without forcing the user to do | ||
| // anything different. | ||
| _VDOM: true | ||
| // Event handlers are implemented using actions. | ||
| type EventActions<S> = { | ||
| [K in keyof EventsMap]: | ||
| | Action<S, EventsMap[K]> | ||
| | readonly [action: Action<S>, payload: unknown] | ||
| } | ||
| // These are based on actual DOM node types: | ||
| // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType | ||
| const enum VDOMNodeType { | ||
| SSR = 1, | ||
| Text = 3, | ||
| } | ||
| // In certain places a virtual DOM node can be made optional. | ||
| type MaybeVDOM<S> = boolean | null | undefined | VDOM<S> | ||
| type MaybeVNode<S> = boolean | null | undefined | VNode<S> | ||
| // A virtual DOM node's tag has metadata relevant to it. Virtual DOM nodes are | ||
| // tagged by their type to assist rendering. | ||
| type Tag<S> = string | View<S> | ||
| // A key can uniquely associate a virtual DOM node with a certain DOM element. | ||
| type Key = string | null | undefined | ||
| // Virtual DOM properties will often correspond to HTML attributes. | ||
| type PropList<S> = | ||
| type Props<S> = | ||
| Readonly< | ||
@@ -184,47 +157,62 @@ Partial< | ||
| class?: ClassProp | ||
| key?: Key | ||
| key?: VNode<S>["key"] | ||
| style?: StyleProp | ||
| // By disallowing `_VDOM` we ensure that values having the `VDOM` type | ||
| // are not mistaken for also having `PropList`. | ||
| _VDOM?: never | ||
| // By disallowing `_VNode` we ensure values having the `VNode` type are | ||
| // not mistaken for also having the `Props` type. | ||
| _VNode?: never | ||
| } | ||
| > | ||
| // The `class` property represents an HTML class attribute string. | ||
| type ClassProp = | ||
| | boolean | ||
| | string | ||
| | undefined | ||
| | Record<string, boolean | undefined> | ||
| | ClassProp[] | ||
| // The `style` property represents inline CSS. This relies on TypeScript's CSS | ||
| // property definitions. Custom properties aren't covered as well as any newer | ||
| // properties yet to be recognized by TypeScript. The only way to accommodate | ||
| // them is to relax the adherence to TypeScript's CSS property definitions. | ||
| // It's a poor trade-off given the likelihood of using such properties. | ||
| // However, you can use type casting if you want to use them. | ||
| type StyleProp = IndexableByKey & { | ||
| [K in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[K] | null | ||
| } | ||
| // The `style` property represents inline CSS. | ||
| // | ||
| // NOTE: This relies on what TypeScript itself recognizes as valid CSS | ||
| // properties. Custom properties are not covered as well as any newer | ||
| // properties that are not yet recognized by TypeScript. Apparently, | ||
| // the only way to accommodate them is to relax the adherence to | ||
| // TypeScript's CSS property definitions. The trade-off doesn't | ||
| // seem worth it given the chances of using such properties. | ||
| // However, you can use type casting if you want to them. | ||
| type StyleProp = IndexableByKey & | ||
| { | ||
| [K in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[K] | null | ||
| } | ||
| // A subscription reacts to external activity. | ||
| type Subscription<S, P = any> = readonly [ | ||
| subscriber: (dispatch: Dispatch<S>, payload: P) => Unsubscribe, | ||
| payload: P | ||
| ] | ||
| // Event handlers are implemented using actions. | ||
| type EventActions<S> = { | ||
| [K in keyof EventsMap]: | ||
| | Action<S, EventsMap[K]> | ||
| | [action: Action<S>, payload: any] | ||
| // An unsubscribe function cleans up a canceled subscription. | ||
| type Unsubscribe = () => void | ||
| // A virtual DOM node (a.k.a. VNode) represents an actual DOM element. | ||
| type VNode<S> = { | ||
| readonly props: Props<S> | ||
| readonly children: readonly MaybeVNode<S>[] | ||
| node: null | undefined | Node | ||
| // Hyperapp takes care of using native Web platform event handlers for us. | ||
| events?: | ||
| Record< | ||
| string, | ||
| Action<S> | readonly [action: Action<S>, payload: unknown] | ||
| > | ||
| // A key can uniquely associate a VNode with a certain DOM element. | ||
| readonly key: string | null | undefined | ||
| // A VNode's tag is either an element name or a memoized view function. | ||
| readonly tag: string | ((data: Indexable) => VNode<S>) | ||
| // If the VNode's tag is a function then this data will get passed to it. | ||
| memo?: Indexable | ||
| // VNode types are based on actual DOM node types: | ||
| // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType | ||
| readonly type: 1 | 3 | ||
| // `_VNode` is a phantom guard property which gives us a way to tell `VNode` | ||
| // objects apart from `Props` objects. Since we don't expect users to make | ||
| // their own VNodes manually, we can take advantage of this trick which | ||
| // is unique to TypeScript type definitions for JavaScript code. | ||
| _VNode: true | ||
| } | ||
| // Most event typings are provided by TypeScript itself. | ||
| type EventsMap = { | ||
| [K in keyof HTMLElementEventMap as `on${K}`]: HTMLElementEventMap[K] | ||
| } & | ||
| { [K in keyof WindowEventMap as `on${K}`]: WindowEventMap[K] } & { | ||
| onsearch: Event | ||
| } | ||
| } |
+1
-1
| { | ||
| "name": "hyperapp", | ||
| "version": "2.0.16", | ||
| "version": "2.0.17", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
23439
-0.49%550
-2.83%4
33.33%