@shane_il/pulse 0.2.0 → 0.3.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.
package/dist/pulse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pulse.js","sources":["../src/vnode.ts","../src/createElement.ts","../src/store.ts","../src/scheduler.ts","../src/connect.ts","../src/diff.ts","../src/patch.ts","../src/render.ts","../src/router.ts","../src/middleware.ts"],"sourcesContent":["import type { ComponentInstance } from './connect';\nimport type { SelectorBinding } from './store';\n\nexport const TEXT_NODE: unique symbol = Symbol('TEXT_NODE');\nexport const FRAGMENT: unique symbol = Symbol('FRAGMENT');\n\nexport type VNodeType = string | typeof TEXT_NODE | typeof FRAGMENT | ComponentFunction;\n\nexport interface VNode {\n type: VNodeType;\n props: Record<string, any>;\n children: VNode[];\n key: string | number | null;\n _dom?: Node | null;\n _instance?: ComponentInstance | null;\n}\n\nexport type ComponentFunction = (props: Record<string, any>) => VNode | null;\n\nexport interface Bindings {\n [propName: string]: SelectorBinding<any, any>;\n}\n\nexport interface Lifecycle {\n onMount?: (ctx: { dom: Node | null | undefined; props: Record<string, any> }) => void | (() => void);\n onUpdate?: (ctx: { dom: Node | null | undefined; props: Record<string, any> }) => void;\n onError?: (ctx: { error: unknown; props: Record<string, any> }) => VNode | null;\n onDestroy?: (ctx: { props: Record<string, any> }) => void;\n}\n\nexport function createTextVNode(text: string | number): VNode {\n return {\n type: TEXT_NODE,\n props: { nodeValue: String(text) },\n children: [],\n key: null,\n };\n}\n\nexport function normalizeChild(child: any): VNode | null {\n if (child == null || typeof child === 'boolean') return null;\n if (typeof child === 'string' || typeof child === 'number') {\n return createTextVNode(child);\n }\n return child as VNode;\n}\n\nexport function flattenChildren(rawChildren: any[]): VNode[] {\n const result: VNode[] = [];\n for (const child of rawChildren) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child));\n } else {\n const normalized = normalizeChild(child);\n if (normalized !== null) result.push(normalized);\n }\n }\n return result;\n}\n","import { FRAGMENT, flattenChildren } from './vnode';\nimport type { VNode, VNodeType } from './vnode';\n\nexport function h(type: VNodeType, props: Record<string, any> | null, ...rawChildren: any[]): VNode {\n props = props || {};\n const key = props.key ?? null;\n\n if (props.key !== undefined) {\n props = { ...props };\n delete props.key;\n }\n\n const children = flattenChildren(rawChildren);\n\n return { type, props, children, key };\n}\n\nexport { FRAGMENT as Fragment };\n","import type { Middleware, DispatchContext } from './middleware';\n\nexport interface StoreActions<S> {\n [actionName: string]: (state: S, payload?: any) => S;\n}\n\nexport interface StoreConfig<S> {\n state: S;\n actions: StoreActions<S>;\n name?: string;\n middleware?: Middleware<S>[];\n}\n\nexport interface SelectorBinding<S, R> {\n store: Store<S>;\n selector: (state: S) => R;\n}\n\nexport interface Store<S> {\n readonly name?: string;\n getState(): S;\n dispatch(actionName: string, payload?: any): void;\n subscribe(listener: (state: S) => void): () => void;\n select<R>(selectorFn: (state: S) => R): SelectorBinding<S, R>;\n}\n\nexport function createStore<S>(config: StoreConfig<S>): Store<S> {\n let state: S = config.state;\n const actions = config.actions;\n const listeners = new Set<(state: S) => void>();\n const mw = config.middleware;\n\n function getState(): S {\n return state;\n }\n\n function notify(): void {\n for (const listener of listeners) {\n listener(state);\n }\n }\n\n // Fast path: no middleware — same hot path as before\n function dispatchSimple(actionName: string, payload?: any): void {\n const action = actions[actionName];\n if (!action) {\n throw new Error(`[pulse] Unknown action: \"${actionName}\"`);\n }\n const nextState = action(state, payload);\n if (nextState === state) return;\n state = nextState;\n notify();\n }\n\n // Middleware path: build onion chain per dispatch\n function dispatchWithMiddleware(actionName: string, payload?: any): void {\n // __devtools_replace__ is a reserved action for time-travel\n if (actionName === '__devtools_replace__') {\n state = payload as S;\n notify();\n return;\n }\n\n const action = actions[actionName];\n if (!action) {\n throw new Error(`[pulse] Unknown action: \"${actionName}\"`);\n }\n\n const ctx: DispatchContext<S> = {\n store: storeObj,\n actionName,\n payload,\n prevState: state,\n nextState: undefined,\n };\n\n let idx = 0;\n function next(): void {\n if (idx < mw!.length) {\n const fn = mw![idx++];\n fn(ctx, next);\n } else {\n // Core action at the center of the onion\n const nextState = action(ctx.prevState, ctx.payload);\n ctx.nextState = nextState;\n if (nextState !== state) {\n state = nextState;\n notify();\n }\n }\n }\n\n next();\n }\n\n const dispatch = mw && mw.length > 0 ? dispatchWithMiddleware : dispatchSimple;\n\n function subscribe(listener: (state: S) => void): () => void {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n }\n\n function select<R>(selectorFn: (state: S) => R): SelectorBinding<S, R> {\n return { store: storeObj, selector: selectorFn };\n }\n\n const storeObj: Store<S> = {\n getState,\n dispatch,\n subscribe,\n select,\n };\n\n if (config.name) {\n (storeObj as any).name = config.name;\n }\n\n return storeObj;\n}\n","let pending = false;\nconst queue = new Set<() => void>();\n\nexport function scheduleUpdate(callback: () => void): void {\n queue.add(callback);\n if (!pending) {\n pending = true;\n queueMicrotask(flush);\n }\n}\n\nfunction flush(): void {\n const batch = [...queue];\n queue.clear();\n pending = false;\n for (const callback of batch) {\n callback();\n }\n}\n\nexport function flushSync(): void {\n const batch = [...queue];\n queue.clear();\n pending = false;\n for (const callback of batch) {\n callback();\n }\n}\n","import { scheduleUpdate } from './scheduler';\nimport type { VNode, Bindings, Lifecycle, ComponentFunction } from './vnode';\n\nexport const CONNECTED: unique symbol = Symbol('PULSE_CONNECTED');\n\n// Pluggable devtools hooks — stored on globalThis so separate bundles\n// (pulse core vs devtools) share the same hook storage.\ninterface ComponentHooks {\n onMount: ((instance: any) => void) | null;\n onUnmount: ((instance: any) => void) | null;\n}\n\nconst G = globalThis as any;\nif (!G.__PULSE_HOOKS__) {\n G.__PULSE_HOOKS__ = { onMount: null, onUnmount: null };\n}\nconst hooks: ComponentHooks = G.__PULSE_HOOKS__;\n\nexport function __setComponentHooks(\n onMount: ((instance: ComponentInstance) => void) | null,\n onUnmount: ((instance: ComponentInstance) => void) | null,\n): void {\n hooks.onMount = onMount;\n hooks.onUnmount = onUnmount;\n}\n\nexport function connect(\n bindings: Bindings | null | undefined,\n lifecycle?: Lifecycle,\n) {\n return function wrapComponent(Component: ComponentFunction) {\n const b = bindings || {};\n\n function ConnectedComponent(props: Record<string, any>): VNode | null {\n const selectedProps: Record<string, any> = {};\n for (const propName in b) {\n const { store, selector } = b[propName];\n selectedProps[propName] = selector(store.getState());\n }\n return Component({ ...selectedProps, ...props });\n }\n\n (ConnectedComponent as any)[CONNECTED] = true;\n (ConnectedComponent as any)._bindings = b;\n (ConnectedComponent as any)._innerComponent = Component;\n if (lifecycle) (ConnectedComponent as any)._lifecycle = lifecycle;\n ConnectedComponent.displayName =\n `Connected(${(Component as any).displayName || Component.name || 'Anonymous'})`;\n\n return ConnectedComponent;\n };\n}\n\nexport class ComponentInstance {\n connectedFn: ComponentFunction;\n props: Record<string, any>;\n prevSelected: Record<string, any>;\n unsubscribers: (() => void)[];\n lastVTree: VNode | null;\n parentDom: Node | null;\n _renderCallback: (() => void) | null;\n _mountCleanup: (() => void) | null;\n\n constructor(connectedFn: ComponentFunction, props: Record<string, any>) {\n this.connectedFn = connectedFn;\n this.props = props;\n this.prevSelected = {};\n this.unsubscribers = [];\n this.lastVTree = null;\n this.parentDom = null;\n this._renderCallback = null;\n this._mountCleanup = null;\n }\n\n mount(parentDom: Node, renderCallback: () => void): void {\n this.parentDom = parentDom;\n this._renderCallback = renderCallback;\n\n const bindings: Bindings = (this.connectedFn as any)._bindings;\n\n for (const propName in bindings) {\n const { store, selector } = bindings[propName];\n this.prevSelected[propName] = selector(store.getState());\n }\n\n for (const propName in bindings) {\n const { store } = bindings[propName];\n const unsub = store.subscribe(() => {\n this._onStoreChange();\n });\n this.unsubscribers.push(unsub);\n }\n\n // Lifecycle: call onMount after subscriptions are live\n const lifecycle: Lifecycle | undefined = (this.connectedFn as any)._lifecycle;\n if (lifecycle?.onMount) {\n const cleanup = lifecycle.onMount({\n dom: this.lastVTree?._dom,\n props: this.props,\n });\n if (typeof cleanup === 'function') {\n this._mountCleanup = cleanup;\n }\n }\n\n // Devtools hook\n if (hooks.onMount) hooks.onMount(this);\n }\n\n _onStoreChange(): void {\n const bindings: Bindings = (this.connectedFn as any)._bindings;\n let changed = false;\n\n for (const propName in bindings) {\n const { store, selector } = bindings[propName];\n const newValue = selector(store.getState());\n if (!shallowEqual(newValue, this.prevSelected[propName])) {\n changed = true;\n break;\n }\n }\n\n if (changed) {\n scheduleUpdate(this._renderCallback!);\n }\n }\n\n updateSelected(): void {\n const bindings: Bindings = (this.connectedFn as any)._bindings;\n for (const propName in bindings) {\n const { store, selector } = bindings[propName];\n this.prevSelected[propName] = selector(store.getState());\n }\n }\n\n unmount(): void {\n // Devtools hook\n if (hooks.onUnmount) hooks.onUnmount(this);\n\n // Lifecycle: cleanup from onMount, then onDestroy\n if (this._mountCleanup) {\n this._mountCleanup();\n this._mountCleanup = null;\n }\n const lifecycle: Lifecycle | undefined = (this.connectedFn as any)._lifecycle;\n if (lifecycle?.onDestroy) {\n lifecycle.onDestroy({ props: this.props });\n }\n\n for (const unsub of this.unsubscribers) {\n unsub();\n }\n this.unsubscribers = [];\n this._renderCallback = null;\n }\n}\n\nexport function shallowEqual(a: any, b: any): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n if (a === null || b === null) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {\n return false;\n }\n }\n return true;\n}\n","import { TEXT_NODE } from './vnode';\nimport type { VNode } from './vnode';\n\nexport const PATCH = {\n CREATE: 'CREATE',\n REMOVE: 'REMOVE',\n REPLACE: 'REPLACE',\n UPDATE: 'UPDATE',\n TEXT: 'TEXT',\n MOVE: 'MOVE',\n CHILDREN: 'CHILDREN',\n} as const;\n\nexport type PatchType = typeof PATCH[keyof typeof PATCH];\n\nexport interface PropPatches {\n set: Record<string, any>;\n remove: string[];\n}\n\nexport type Patch =\n | { type: typeof PATCH.CREATE; newVNode: VNode; anchor?: VNode | null }\n | { type: typeof PATCH.REMOVE; target: VNode }\n | { type: typeof PATCH.REPLACE; oldVNode: VNode; newVNode: VNode }\n | { type: typeof PATCH.UPDATE; target: VNode; propPatches: PropPatches }\n | { type: typeof PATCH.TEXT; oldVNode: VNode; newVNode: VNode }\n | { type: typeof PATCH.MOVE; vnode: VNode; anchor: VNode | null; childPatches: Patch[] }\n | { type: typeof PATCH.CHILDREN; parent: VNode; childPatches: Patch[] };\n\nexport function diff(oldVNode: VNode | null, newVNode: VNode | null): Patch[] {\n if (newVNode == null && oldVNode == null) return [];\n if (newVNode == null) return [{ type: PATCH.REMOVE, target: oldVNode! }];\n if (oldVNode == null) return [{ type: PATCH.CREATE, newVNode }];\n\n if (oldVNode.type !== newVNode.type) {\n return [{ type: PATCH.REPLACE, oldVNode, newVNode }];\n }\n\n // Transfer _dom reference: the new vnode represents the same DOM node\n newVNode._dom = oldVNode._dom;\n\n if (oldVNode.type === TEXT_NODE) {\n if (oldVNode.props.nodeValue !== newVNode.props.nodeValue) {\n return [{ type: PATCH.TEXT, oldVNode, newVNode }];\n }\n return [];\n }\n\n const patches: Patch[] = [];\n\n const propPatches = diffProps(oldVNode.props, newVNode.props);\n if (propPatches) {\n patches.push({ type: PATCH.UPDATE, target: oldVNode, propPatches });\n }\n\n const childPatches = diffChildren(oldVNode.children, newVNode.children);\n if (childPatches.length) {\n patches.push({ type: PATCH.CHILDREN, parent: oldVNode, childPatches });\n }\n\n return patches;\n}\n\nfunction diffProps(\n oldProps: Record<string, any>,\n newProps: Record<string, any>,\n): PropPatches | null {\n const set: Record<string, any> = {};\n const remove: string[] = [];\n let hasChanges = false;\n\n for (const key in newProps) {\n if (key === 'children') continue;\n if (oldProps[key] !== newProps[key]) {\n set[key] = newProps[key];\n hasChanges = true;\n }\n }\n\n for (const key in oldProps) {\n if (key === 'children') continue;\n if (!(key in newProps)) {\n remove.push(key);\n hasChanges = true;\n }\n }\n\n return hasChanges ? { set, remove } : null;\n}\n\nfunction sameVNode(a: VNode | null, b: VNode | null): boolean {\n if (a == null || b == null) return false;\n return a.type === b.type && a.key === b.key;\n}\n\nfunction warnChildKeys(children: (VNode | null)[], label: string): void {\n const seen = new Set<string | number>();\n let keyedCount = 0;\n let unkeyedCount = 0;\n\n for (const child of children) {\n if (child == null) continue;\n if (child.key != null) {\n keyedCount++;\n if (seen.has(child.key)) {\n console.warn(\n `[pulse] Duplicate key \"${String(child.key)}\" in ${label} children. ` +\n `Keys must be unique among siblings.`,\n );\n }\n seen.add(child.key);\n } else {\n unkeyedCount++;\n }\n }\n\n if (keyedCount > 0 && unkeyedCount > 0) {\n console.warn(\n `[pulse] Mixed keyed and unkeyed children in ${label} list ` +\n `(${keyedCount} keyed, ${unkeyedCount} unkeyed). ` +\n `Either all children should have keys or none should.`,\n );\n }\n}\n\nfunction diffChildren(oldChildren: (VNode | null)[], newChildren: VNode[]): Patch[] {\n if (process.env.NODE_ENV !== 'production') {\n warnChildKeys(oldChildren, 'old');\n warnChildKeys(newChildren, 'new');\n }\n\n const patches: Patch[] = [];\n\n let oldStartIdx = 0;\n let oldEndIdx = oldChildren.length - 1;\n let newStartIdx = 0;\n let newEndIdx = newChildren.length - 1;\n\n let oldStartVNode = oldChildren[oldStartIdx];\n let oldEndVNode = oldChildren[oldEndIdx];\n let newStartVNode = newChildren[newStartIdx];\n let newEndVNode = newChildren[newEndIdx];\n\n // Phase 1: two-pointer scan\n while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\n if (oldStartVNode == null) {\n oldStartVNode = oldChildren[++oldStartIdx];\n continue;\n }\n if (oldEndVNode == null) {\n oldEndVNode = oldChildren[--oldEndIdx];\n continue;\n }\n\n if (sameVNode(oldStartVNode, newStartVNode)) {\n patches.push(...diff(oldStartVNode, newStartVNode));\n oldStartVNode = oldChildren[++oldStartIdx];\n newStartVNode = newChildren[++newStartIdx];\n } else if (sameVNode(oldEndVNode, newEndVNode)) {\n patches.push(...diff(oldEndVNode, newEndVNode));\n oldEndVNode = oldChildren[--oldEndIdx];\n newEndVNode = newChildren[--newEndIdx];\n } else if (sameVNode(oldStartVNode, newEndVNode)) {\n patches.push({\n type: PATCH.MOVE,\n vnode: oldStartVNode!,\n anchor: oldChildren[oldEndIdx + 1] || null,\n childPatches: diff(oldStartVNode, newEndVNode),\n });\n oldStartVNode = oldChildren[++oldStartIdx];\n newEndVNode = newChildren[--newEndIdx];\n } else if (sameVNode(oldEndVNode, newStartVNode)) {\n patches.push({\n type: PATCH.MOVE,\n vnode: oldEndVNode!,\n anchor: oldStartVNode,\n childPatches: diff(oldEndVNode, newStartVNode),\n });\n oldEndVNode = oldChildren[--oldEndIdx];\n newStartVNode = newChildren[++newStartIdx];\n } else {\n // Fall through to key-map phase\n break;\n }\n }\n\n // Phase 2: key-map fallback for remaining nodes\n if (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\n const keyMap = new Map<string | number, number>();\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n const key = oldChildren[i]?.key;\n if (key != null) keyMap.set(key, i);\n }\n\n while (newStartIdx <= newEndIdx) {\n newStartVNode = newChildren[newStartIdx];\n const oldIdx = newStartVNode.key != null\n ? keyMap.get(newStartVNode.key)\n : undefined;\n\n if (oldIdx !== undefined) {\n const matchedOld = oldChildren[oldIdx]!;\n patches.push({\n type: PATCH.MOVE,\n vnode: matchedOld,\n anchor: oldChildren[oldStartIdx] || null,\n childPatches: diff(matchedOld, newStartVNode),\n });\n oldChildren[oldIdx] = null;\n keyMap.delete(newStartVNode.key!);\n } else {\n patches.push({\n type: PATCH.CREATE,\n newVNode: newStartVNode,\n anchor: oldChildren[oldStartIdx] || null,\n });\n }\n newStartIdx++;\n }\n\n // Remove unconsumed old children\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n if (oldChildren[i] != null) {\n patches.push({ type: PATCH.REMOVE, target: oldChildren[i]! });\n }\n }\n }\n\n // Phase 3: remaining creates or removes\n if (oldStartIdx > oldEndIdx) {\n const anchor = newChildren[newEndIdx + 1] || null;\n for (let i = newStartIdx; i <= newEndIdx; i++) {\n patches.push({ type: PATCH.CREATE, newVNode: newChildren[i], anchor });\n }\n } else if (newStartIdx > newEndIdx) {\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n if (oldChildren[i] != null) {\n patches.push({ type: PATCH.REMOVE, target: oldChildren[i]! });\n }\n }\n }\n\n return patches;\n}\n","import { TEXT_NODE, FRAGMENT } from './vnode';\nimport { PATCH } from './diff';\nimport type { VNode } from './vnode';\nimport type { Patch } from './diff';\n\nexport function createDOMNode(vnode: VNode): Node {\n if (vnode.type === TEXT_NODE) {\n const textNode = document.createTextNode(vnode.props.nodeValue);\n vnode._dom = textNode;\n return textNode;\n }\n\n if (vnode.type === FRAGMENT) {\n const frag = document.createDocumentFragment();\n for (const child of vnode.children) {\n frag.appendChild(createDOMNode(child));\n }\n // For fragments, store ref to first child for positioning\n vnode._dom = frag;\n return frag;\n }\n\n const el = document.createElement(vnode.type as string);\n applyProps(el, {}, vnode.props);\n\n for (const child of vnode.children) {\n el.appendChild(createDOMNode(child));\n }\n\n vnode._dom = el;\n return el;\n}\n\nexport function applyProps(\n el: HTMLElement,\n oldProps: Record<string, any>,\n newProps: Record<string, any>,\n): void {\n for (const key in oldProps) {\n if (key === 'children' || key === 'key') continue;\n if (!(key in newProps)) {\n removeProp(el, key, oldProps[key]);\n }\n }\n for (const key in newProps) {\n if (key === 'children' || key === 'key') continue;\n if (oldProps[key] !== newProps[key]) {\n setProp(el, key, newProps[key], oldProps[key]);\n }\n }\n}\n\nfunction setProp(el: HTMLElement, key: string, value: any, oldValue: any): void {\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase();\n if (oldValue) el.removeEventListener(eventName, oldValue);\n if (value) el.addEventListener(eventName, value);\n } else if (key === 'className') {\n el.className = value || '';\n } else if (key === 'style' && typeof value === 'object') {\n if (typeof oldValue === 'object' && oldValue) {\n for (const prop in oldValue) {\n if (!(prop in value)) (el.style as any)[prop] = '';\n }\n }\n Object.assign(el.style, value);\n } else if (key === 'ref') {\n if (typeof value === 'function') value(el);\n } else if (value === true) {\n el.setAttribute(key, '');\n } else if (value === false || value == null) {\n el.removeAttribute(key);\n } else {\n el.setAttribute(key, value);\n }\n}\n\nfunction removeProp(el: HTMLElement, key: string, oldValue: any): void {\n if (key.startsWith('on')) {\n el.removeEventListener(key.slice(2).toLowerCase(), oldValue);\n } else if (key === 'className') {\n el.className = '';\n } else {\n el.removeAttribute(key);\n }\n}\n\nexport function applyPatches(parentDom: Node, patches: Patch[]): void {\n for (const patch of patches) {\n switch (patch.type) {\n case PATCH.CREATE: {\n const dom = createDOMNode(patch.newVNode);\n if (patch.anchor?._dom) {\n parentDom.insertBefore(dom, patch.anchor._dom);\n } else {\n parentDom.appendChild(dom);\n }\n break;\n }\n\n case PATCH.REMOVE: {\n const dom = patch.target._dom;\n if (dom?.parentNode) {\n dom.parentNode.removeChild(dom);\n }\n break;\n }\n\n case PATCH.REPLACE: {\n const newDom = createDOMNode(patch.newVNode);\n const oldDom = patch.oldVNode._dom;\n if (oldDom?.parentNode) {\n oldDom.parentNode.replaceChild(newDom, oldDom);\n }\n break;\n }\n\n case PATCH.UPDATE: {\n const dom = patch.target._dom as HTMLElement;\n const { set, remove } = patch.propPatches;\n for (const key of remove) {\n removeProp(dom, key, patch.target.props[key]);\n }\n for (const key in set) {\n setProp(dom, key, set[key], patch.target.props[key]);\n }\n break;\n }\n\n case PATCH.TEXT: {\n const dom = patch.oldVNode._dom;\n if (dom) dom.nodeValue = patch.newVNode.props.nodeValue;\n break;\n }\n\n case PATCH.MOVE: {\n const dom = patch.vnode._dom;\n if (dom) {\n if (patch.anchor?._dom) {\n parentDom.insertBefore(dom, patch.anchor._dom);\n } else {\n parentDom.appendChild(dom);\n }\n }\n if (patch.childPatches?.length && dom) {\n applyPatches(dom, patch.childPatches);\n }\n break;\n }\n\n case PATCH.CHILDREN: {\n const dom = patch.parent._dom;\n if (dom && patch.childPatches.length) {\n applyPatches(dom, patch.childPatches);\n }\n break;\n }\n }\n }\n}\n","import { diff, PATCH } from './diff';\nimport { createDOMNode, applyPatches } from './patch';\nimport { CONNECTED, ComponentInstance } from './connect';\nimport { TEXT_NODE, FRAGMENT, createTextVNode } from './vnode';\nimport type { VNode, Lifecycle } from './vnode';\nimport type { Patch } from './diff';\n\ninterface RootEntry {\n vTree: VNode;\n}\n\nconst roots = new WeakMap<Node, RootEntry>();\n\nexport function render(vnode: VNode, container: Node): void {\n const prev = roots.get(container);\n\n if (!prev) {\n // First mount\n const expanded = expand(vnode, container);\n if (!expanded) return;\n\n const dom = createDOMNode(expanded);\n container.appendChild(dom);\n\n const instances: ComponentInstance[] = [];\n collectInstances(expanded, instances);\n for (const inst of instances) {\n inst.mount(container, () => reRenderInstance(inst, container));\n }\n\n roots.set(container, { vTree: expanded });\n } else {\n // Update\n const expanded = expand(vnode, container);\n\n const oldInstances: ComponentInstance[] = [];\n collectInstances(prev.vTree, oldInstances);\n\n const patches = diff(prev.vTree, expanded);\n applyPatches(container, patches);\n\n const newInstances: ComponentInstance[] = [];\n if (expanded) collectInstances(expanded, newInstances);\n\n // Unmount removed instances\n const newSet = new Set(newInstances);\n for (const inst of oldInstances) {\n if (!newSet.has(inst)) {\n inst.unmount();\n }\n }\n\n // Mount new instances\n const oldSet = new Set(oldInstances);\n for (const inst of newInstances) {\n if (!oldSet.has(inst)) {\n inst.mount(container, () => reRenderInstance(inst, container));\n }\n }\n\n roots.set(container, { vTree: expanded! });\n }\n}\n\nfunction expand(vnode: VNode | null, parentDom: Node): VNode | null {\n if (vnode == null) return null;\n\n if (typeof vnode.type === 'function') {\n if ((vnode.type as any)[CONNECTED]) {\n // Connected component — with error boundary support\n const lifecycle: Lifecycle | undefined = (vnode.type as any)._lifecycle;\n\n try {\n const instance = new ComponentInstance(vnode.type, vnode.props);\n const childVNode = vnode.type(vnode.props);\n const expanded = expand(childVNode, parentDom);\n\n // Use placeholder for null returns so instance stays in tree (subscribes)\n const result = expanded ?? createTextVNode('');\n\n if (result._instance) {\n // Nested connected component: wrap outer in a boundary element\n // so each instance has its own VNode (no _instance collision).\n const boundary: VNode = {\n type: 'div',\n props: { style: { display: 'contents' } },\n children: [result],\n key: vnode.key,\n };\n boundary._instance = instance;\n instance.lastVTree = boundary;\n return boundary;\n }\n\n result._instance = instance;\n instance.lastVTree = result;\n\n return result;\n } catch (error) {\n if (lifecycle?.onError) {\n const fallbackVNode = lifecycle.onError({ error, props: vnode.props });\n return expand(fallbackVNode, parentDom);\n }\n throw error;\n }\n }\n\n // Plain function component\n const childVNode = vnode.type({ ...vnode.props, children: vnode.children });\n return expand(childVNode, parentDom);\n }\n\n // Element, text, or fragment: recursively expand children\n if (vnode.children?.length) {\n vnode.children = vnode.children\n .map(child => expand(child, parentDom))\n .filter((c): c is VNode => c != null);\n }\n\n return vnode;\n}\n\nfunction reRenderInstance(instance: ComponentInstance, parentDom: Node): void {\n // Guard: skip re-render if instance was unmounted (e.g. parent already rebuilt this subtree)\n if (!instance._renderCallback) return;\n\n const connectedFn = instance.connectedFn;\n const lifecycle: Lifecycle | undefined = (connectedFn as any)._lifecycle;\n\n try {\n const newVNode = connectedFn(instance.props);\n const rawExpanded = expand(newVNode, parentDom);\n\n // Use placeholder for null returns so instance stays in tree\n let innerContent = rawExpanded ?? createTextVNode('');\n\n // Wrap if nested connected component (same logic as expand)\n let newTree: VNode;\n if (innerContent._instance && innerContent._instance !== instance) {\n newTree = {\n type: 'div',\n props: { style: { display: 'contents' } },\n children: [innerContent],\n key: null,\n } as VNode;\n newTree._instance = instance;\n } else {\n innerContent._instance = instance;\n newTree = innerContent;\n }\n\n if (instance.lastVTree) {\n // Refresh stale inner instance references before diffing\n refreshInnerInstances(instance.lastVTree, instance);\n\n const patches = diff(instance.lastVTree, newTree);\n\n // Find the actual parent DOM node to patch against\n const domParent = instance.lastVTree._dom?.parentNode || parentDom;\n applyPatches(domParent, patches);\n\n // Transfer the _dom reference from old to new\n if (!newTree._dom) {\n newTree._dom = instance.lastVTree._dom;\n }\n }\n\n // Collect inner instances for lifecycle management\n const oldInner: ComponentInstance[] = [];\n collectInnerInstances(instance.lastVTree, oldInner, instance);\n const newInner: ComponentInstance[] = [];\n collectInnerInstances(newTree, newInner, instance);\n\n // Unmount removed inner instances\n const newInstSet = new Set(newInner);\n for (const inst of oldInner) {\n if (!newInstSet.has(inst)) inst.unmount();\n }\n\n instance.lastVTree = newTree;\n\n // Mount new inner instances\n const oldInstSet = new Set(oldInner);\n for (const inst of newInner) {\n if (!oldInstSet.has(inst)) {\n inst.mount(parentDom, () => reRenderInstance(inst, parentDom));\n }\n }\n\n // Lifecycle: onUpdate fires after every re-render (not on initial mount)\n if (lifecycle?.onUpdate) {\n lifecycle.onUpdate({\n dom: newTree?._dom,\n props: instance.props,\n });\n }\n\n instance.updateSelected();\n } catch (error) {\n if (lifecycle?.onError) {\n const fallbackVNode = lifecycle.onError({ error, props: instance.props });\n const fallbackExpanded = expand(fallbackVNode, parentDom);\n\n // Replace current DOM with fallback\n if (instance.lastVTree && fallbackExpanded) {\n refreshInnerInstances(instance.lastVTree, instance);\n\n const patches = diff(instance.lastVTree, fallbackExpanded);\n const domParent = instance.lastVTree._dom?.parentNode || parentDom;\n applyPatches(domParent, patches);\n\n if (!fallbackExpanded._dom) {\n fallbackExpanded._dom = instance.lastVTree._dom;\n }\n }\n\n // Unmount old inner instances on error fallback\n const oldInner: ComponentInstance[] = [];\n collectInnerInstances(instance.lastVTree, oldInner, instance);\n for (const inst of oldInner) inst.unmount();\n\n instance.lastVTree = fallbackExpanded;\n instance.updateSelected();\n } else {\n throw error;\n }\n }\n}\n\n/**\n * Before diffing a parent's lastVTree, refresh any inner connected components'\n * subtrees to reflect their current state (they may have re-rendered independently).\n */\nfunction refreshInnerInstances(vnode: VNode | null, skip: ComponentInstance): void {\n if (!vnode || !vnode.children) return;\n for (let i = 0; i < vnode.children.length; i++) {\n const child = vnode.children[i];\n if (child._instance && child._instance !== skip && child._instance.lastVTree) {\n // Replace stale reference with instance's current lastVTree\n if (child._instance.lastVTree !== child) {\n vnode.children[i] = child._instance.lastVTree;\n }\n }\n refreshInnerInstances(vnode.children[i], skip);\n }\n}\n\nfunction unmountSubtree(vnode: VNode | null, skip?: ComponentInstance): void {\n if (!vnode) return;\n if (vnode._instance && vnode._instance !== skip) vnode._instance.unmount();\n if (vnode.children) {\n for (const child of vnode.children) {\n unmountSubtree(child, skip);\n }\n }\n}\n\nfunction collectInstances(vnode: VNode | null, result: ComponentInstance[]): void {\n if (!vnode) return;\n if (vnode._instance) result.push(vnode._instance);\n if (vnode.children) {\n for (const child of vnode.children) {\n collectInstances(child, result);\n }\n }\n}\n\nfunction collectInnerInstances(\n vnode: VNode | null,\n result: ComponentInstance[],\n skip: ComponentInstance,\n): void {\n if (!vnode) return;\n if (vnode._instance && vnode._instance !== skip) result.push(vnode._instance);\n if (vnode.children) {\n for (const child of vnode.children) {\n collectInnerInstances(child, result, skip);\n }\n }\n}\n","import { createStore } from './store';\nimport { connect } from './connect';\nimport { h } from './createElement';\nimport type { Store } from './store';\nimport type { VNode, ComponentFunction } from './vnode';\n\n// ── Types ──────────────────────────────────────────────────\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n matched: string | null;\n}\n\nexport interface RouteConfig {\n path: string;\n}\n\nexport interface RouterOptions {\n routes: RouteConfig[];\n initialPath?: string;\n}\n\nexport interface Router {\n store: Store<RouteState>;\n navigate: (path: string) => void;\n redirect: (path: string) => void;\n back: () => void;\n forward: () => void;\n destroy: () => void;\n Route: ComponentFunction;\n Link: ComponentFunction;\n Redirect: ComponentFunction;\n}\n\n// ── Path Utilities ─────────────────────────────────────────\n\nfunction normalizePath(path: string): string {\n // Strip trailing slash (but keep root \"/\")\n if (path.length > 1 && path.endsWith('/')) {\n return path.slice(0, -1);\n }\n return path || '/';\n}\n\nfunction parseQuery(search: string): Record<string, string> {\n const result: Record<string, string> = {};\n if (!search) return result;\n const cleaned = search.startsWith('?') ? search.slice(1) : search;\n if (!cleaned) return result;\n const params = new URLSearchParams(cleaned);\n params.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n\n// ── Route Matching ─────────────────────────────────────────\n\ninterface MatchResult {\n pattern: string;\n params: Record<string, string>;\n}\n\nfunction matchSingle(\n path: string,\n pattern: string,\n): { params: Record<string, string> } | null {\n const normalizedPath = normalizePath(path);\n const normalizedPattern = normalizePath(pattern);\n\n // Catch-all wildcard\n if (normalizedPattern === '*') {\n return { params: { '*': normalizedPath } };\n }\n\n const pathSegments = normalizedPath === '/'\n ? ['']\n : normalizedPath.split('/').slice(1);\n const patternSegments = normalizedPattern === '/'\n ? ['']\n : normalizedPattern.split('/').slice(1);\n\n // Check for trailing wildcard (prefix matching)\n const hasTrailingWildcard =\n patternSegments.length > 0 &&\n patternSegments[patternSegments.length - 1] === '*';\n\n if (hasTrailingWildcard) {\n const prefixSegments = patternSegments.slice(0, -1);\n\n // Path must have at least as many segments as the prefix\n if (pathSegments.length < prefixSegments.length) return null;\n\n const params: Record<string, string> = {};\n for (let i = 0; i < prefixSegments.length; i++) {\n const ps = prefixSegments[i];\n if (ps.startsWith(':')) {\n params[ps.slice(1)] = pathSegments[i];\n } else if (ps !== pathSegments[i]) {\n return null;\n }\n }\n\n // Capture the rest as \"*\" param\n const rest = pathSegments.slice(prefixSegments.length).join('/');\n params['*'] = rest;\n return { params };\n }\n\n // Exact segment count required for non-wildcard patterns\n if (pathSegments.length !== patternSegments.length) return null;\n\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const ps = patternSegments[i];\n if (ps.startsWith(':')) {\n params[ps.slice(1)] = pathSegments[i];\n } else if (ps !== pathSegments[i]) {\n return null;\n }\n }\n\n return { params };\n}\n\nfunction matchRoute(\n path: string,\n routes: RouteConfig[],\n): MatchResult | null {\n for (const route of routes) {\n const result = matchSingle(path, route.path);\n if (result) {\n return { pattern: route.path, params: result.params };\n }\n }\n return null;\n}\n\n// ── Router Factory ─────────────────────────────────────────\n\nexport function createRouter(options: RouterOptions): Router {\n const { routes, initialPath } = options;\n\n // Read initial URL\n const initPathRaw = initialPath ?? window.location.pathname;\n const initSearch = initialPath ? '' : window.location.search;\n const initPath = normalizePath(initPathRaw);\n const initQuery = parseQuery(initSearch);\n const initMatch = matchRoute(initPath, routes);\n\n // Create the route store\n const store = createStore<RouteState>({\n state: {\n path: initPath,\n params: initMatch?.params ?? {},\n query: initQuery,\n matched: initMatch?.pattern ?? null,\n },\n actions: {\n _sync: (_: RouteState, payload: RouteState) => payload,\n },\n });\n\n // ── Navigation ──\n\n function buildState(rawPath: string): RouteState {\n const qIdx = rawPath.indexOf('?');\n const pathname = normalizePath(qIdx >= 0 ? rawPath.slice(0, qIdx) : rawPath);\n const queryStr = qIdx >= 0 ? rawPath.slice(qIdx + 1) : '';\n const query = parseQuery(queryStr);\n const match = matchRoute(pathname, routes);\n return {\n path: pathname,\n params: match?.params ?? {},\n query,\n matched: match?.pattern ?? null,\n };\n }\n\n function navigate(path: string): void {\n const state = buildState(path);\n window.history.pushState(null, '', path);\n store.dispatch('_sync', state);\n }\n\n function redirect(path: string): void {\n const state = buildState(path);\n window.history.replaceState(null, '', path);\n store.dispatch('_sync', state);\n }\n\n function back(): void {\n window.history.back();\n }\n\n function forward(): void {\n window.history.forward();\n }\n\n // ── Popstate ──\n\n function onPopState(): void {\n const state = buildState(\n window.location.pathname + window.location.search,\n );\n store.dispatch('_sync', state);\n }\n\n window.addEventListener('popstate', onPopState);\n\n function destroy(): void {\n window.removeEventListener('popstate', onPopState);\n }\n\n // ── Route Component (connected) ──\n\n const Route = connect({\n _path: store.select((s: RouteState) => s.path),\n })(function RouteInner(props: Record<string, any>): VNode | null {\n const { _path, path: pattern, component, children, ...rest } = props;\n const match = matchSingle(_path, pattern);\n if (!match) return null;\n if (component) {\n return h(component, { ...rest, params: match.params });\n }\n return children?.[0] ?? null;\n });\n\n // ── Link Component (plain) ──\n\n function Link(props: Record<string, any>): VNode {\n const { to, children, ...rest } = props;\n return h(\n 'a',\n {\n ...rest,\n href: to,\n onClick: (e: MouseEvent) => {\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return;\n e.preventDefault();\n navigate(to);\n },\n },\n ...(children || []),\n );\n }\n\n // ── Redirect Component (plain) ──\n\n function RedirectComponent(props: Record<string, any>): VNode | null {\n redirect(props.to);\n return null;\n }\n\n return {\n store,\n navigate,\n redirect,\n back,\n forward,\n destroy,\n Route,\n Link,\n Redirect: RedirectComponent,\n };\n}\n","import type { Store } from './store';\n\nexport interface DispatchContext<S = any> {\n store: Store<S>;\n actionName: string;\n payload: any;\n prevState: S;\n nextState: S | undefined;\n}\n\nexport type Middleware<S = any> = (ctx: DispatchContext<S>, next: () => void) => void;\n\nexport interface ActionEntry {\n actionName: string;\n payload: any;\n prevState: any;\n nextState: any;\n timestamp: number;\n}\n\n/**\n * Logger middleware — logs action dispatches with prev/next state.\n */\nexport function logger(): Middleware {\n return (ctx, next) => {\n const label = `[pulse] ${ctx.actionName}`;\n console.group(label);\n console.log('prev state', ctx.prevState);\n console.log('payload', ctx.payload);\n next();\n console.log('next state', ctx.nextState);\n console.groupEnd();\n };\n}\n\n/**\n * Action history middleware — pushes entries to a caller-owned array.\n */\nexport function actionHistory(\n history: ActionEntry[],\n opts?: { maxEntries?: number },\n): Middleware {\n const max = opts?.maxEntries ?? Infinity;\n return (ctx, next) => {\n next();\n history.push({\n actionName: ctx.actionName,\n payload: ctx.payload,\n prevState: ctx.prevState,\n nextState: ctx.nextState ?? ctx.prevState,\n timestamp: Date.now(),\n });\n if (history.length > max) {\n history.splice(0, history.length - max);\n }\n };\n}\n"],"names":["TEXT_NODE","FRAGMENT","createTextVNode","text","normalizeChild","child","flattenChildren","rawChildren","result","normalized","h","type","props","key","children","createStore","config","state","actions","listeners","mw","getState","notify","listener","dispatchSimple","actionName","payload","action","nextState","dispatchWithMiddleware","ctx","storeObj","idx","next","fn","dispatch","subscribe","select","selectorFn","pending","queue","scheduleUpdate","callback","flush","batch","flushSync","CONNECTED","G","hooks","connect","bindings","lifecycle","Component","b","ConnectedComponent","selectedProps","propName","store","selector","ComponentInstance","connectedFn","__publicField","parentDom","renderCallback","_a","unsub","cleanup","changed","newValue","shallowEqual","a","keysA","keysB","PATCH","diff","oldVNode","newVNode","patches","propPatches","diffProps","childPatches","diffChildren","oldProps","newProps","set","remove","hasChanges","sameVNode","warnChildKeys","label","seen","keyedCount","unkeyedCount","oldChildren","newChildren","oldStartIdx","oldEndIdx","newStartIdx","newEndIdx","oldStartVNode","oldEndVNode","newStartVNode","newEndVNode","keyMap","i","oldIdx","matchedOld","anchor","createDOMNode","vnode","textNode","frag","el","applyProps","removeProp","setProp","value","oldValue","eventName","prop","applyPatches","_b","_c","patch","dom","newDom","oldDom","roots","render","container","prev","expanded","expand","oldInstances","collectInstances","newInstances","newSet","inst","oldSet","reRenderInstance","instances","instance","childVNode","boundary","error","fallbackVNode","c","innerContent","newTree","refreshInnerInstances","domParent","oldInner","collectInnerInstances","newInner","newInstSet","oldInstSet","fallbackExpanded","skip","normalizePath","path","parseQuery","search","cleaned","matchSingle","pattern","normalizedPath","normalizedPattern","pathSegments","patternSegments","prefixSegments","params","ps","rest","matchRoute","routes","route","createRouter","options","initialPath","initPathRaw","initSearch","initPath","initQuery","initMatch","_","buildState","rawPath","qIdx","pathname","queryStr","query","match","navigate","redirect","back","forward","onPopState","destroy","Route","s","_path","component","Link","to","e","RedirectComponent","logger","actionHistory","history","opts","max"],"mappings":"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"}
1
+ {"version":3,"file":"pulse.js","sources":["../src/vnode.ts","../src/createElement.ts","../src/store.ts","../src/scheduler.ts","../src/connect.ts","../src/diff.ts","../src/patch.ts","../src/render.ts","../src/router.ts","../src/middleware.ts"],"sourcesContent":["import type { ComponentInstance } from './connect';\nimport type { SelectorBinding } from './store';\n\nexport const TEXT_NODE: unique symbol = Symbol('TEXT_NODE');\nexport const FRAGMENT: unique symbol = Symbol('FRAGMENT');\n\nexport type VNodeType =\n | string\n | typeof TEXT_NODE\n | typeof FRAGMENT\n | ComponentFunction;\n\nexport interface VNode {\n type: VNodeType;\n props: Record<string, any>;\n children: VNode[];\n key: string | number | null;\n _dom?: Node | null;\n _instance?: ComponentInstance | null;\n}\n\nexport type ComponentFunction = (props: Record<string, any>) => VNode | null;\n\nexport interface Bindings {\n [propName: string]: SelectorBinding<any, any>;\n}\n\nexport interface Lifecycle {\n onMount?: (ctx: {\n dom: Node | null | undefined;\n props: Record<string, any>;\n }) => void | (() => void);\n onUpdate?: (ctx: {\n dom: Node | null | undefined;\n props: Record<string, any>;\n }) => void;\n onError?: (ctx: {\n error: unknown;\n props: Record<string, any>;\n }) => VNode | null;\n onDestroy?: (ctx: { props: Record<string, any> }) => void;\n}\n\nexport function createTextVNode(text: string | number): VNode {\n return {\n type: TEXT_NODE,\n props: { nodeValue: String(text) },\n children: [],\n key: null,\n };\n}\n\nexport function normalizeChild(child: any): VNode | null {\n if (child == null || typeof child === 'boolean') return null;\n if (typeof child === 'string' || typeof child === 'number') {\n return createTextVNode(child);\n }\n return child as VNode;\n}\n\nexport function flattenChildren(rawChildren: any[]): VNode[] {\n const result: VNode[] = [];\n for (const child of rawChildren) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child));\n } else {\n const normalized = normalizeChild(child);\n if (normalized !== null) result.push(normalized);\n }\n }\n return result;\n}\n","import { FRAGMENT, flattenChildren } from './vnode';\nimport type { VNode, VNodeType } from './vnode';\n\nexport function h(\n type: VNodeType,\n props: Record<string, any> | null,\n ...rawChildren: any[]\n): VNode {\n props = props || {};\n const key = props.key ?? null;\n\n if (props.key !== undefined) {\n props = { ...props };\n delete props.key;\n }\n\n const children = flattenChildren(rawChildren);\n\n return { type, props, children, key };\n}\n\nexport { FRAGMENT as Fragment };\n","import type { Middleware, DispatchContext } from './middleware';\n\nexport interface StoreActions<S> {\n [actionName: string]: (state: S, payload?: any) => S;\n}\n\nexport interface StoreConfig<S> {\n state: S;\n actions: StoreActions<S>;\n name?: string;\n middleware?: Middleware<S>[];\n}\n\nexport interface SelectorBinding<S, R> {\n store: Store<S>;\n selector: (state: S) => R;\n}\n\nexport interface Store<S> {\n readonly name?: string;\n getState(): S;\n dispatch(actionName: string, payload?: any): void;\n subscribe(listener: (state: S) => void): () => void;\n select<R>(selectorFn: (state: S) => R): SelectorBinding<S, R>;\n}\n\nexport function createStore<S>(config: StoreConfig<S>): Store<S> {\n let state: S = config.state;\n const actions = config.actions;\n const listeners = new Set<(state: S) => void>();\n const mw = config.middleware;\n\n function getState(): S {\n return state;\n }\n\n function notify(): void {\n for (const listener of listeners) {\n listener(state);\n }\n }\n\n // Fast path: no middleware — same hot path as before\n function dispatchSimple(actionName: string, payload?: any): void {\n const action = actions[actionName];\n if (!action) {\n throw new Error(`[pulse] Unknown action: \"${actionName}\"`);\n }\n const nextState = action(state, payload);\n if (nextState === state) return;\n state = nextState;\n notify();\n }\n\n // Middleware path: build onion chain per dispatch\n function dispatchWithMiddleware(actionName: string, payload?: any): void {\n // __devtools_replace__ is a reserved action for time-travel\n if (actionName === '__devtools_replace__') {\n state = payload as S;\n notify();\n return;\n }\n\n const action = actions[actionName];\n if (!action) {\n throw new Error(`[pulse] Unknown action: \"${actionName}\"`);\n }\n\n const ctx: DispatchContext<S> = {\n store: storeObj,\n actionName,\n payload,\n prevState: state,\n nextState: undefined,\n };\n\n let idx = 0;\n function next(): void {\n if (idx < mw!.length) {\n const fn = mw![idx++];\n fn(ctx, next);\n } else {\n // Core action at the center of the onion\n const nextState = action(ctx.prevState, ctx.payload);\n ctx.nextState = nextState;\n if (nextState !== state) {\n state = nextState;\n notify();\n }\n }\n }\n\n next();\n }\n\n const dispatch =\n mw && mw.length > 0 ? dispatchWithMiddleware : dispatchSimple;\n\n function subscribe(listener: (state: S) => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function select<R>(selectorFn: (state: S) => R): SelectorBinding<S, R> {\n return { store: storeObj, selector: selectorFn };\n }\n\n const storeObj: Store<S> = {\n getState,\n dispatch,\n subscribe,\n select,\n };\n\n if (config.name) {\n (storeObj as any).name = config.name;\n }\n\n return storeObj;\n}\n","let pending = false;\nconst queue = new Set<() => void>();\n\nexport function scheduleUpdate(callback: () => void): void {\n queue.add(callback);\n if (!pending) {\n pending = true;\n queueMicrotask(flush);\n }\n}\n\nfunction flush(): void {\n const batch = [...queue];\n queue.clear();\n pending = false;\n for (const callback of batch) {\n callback();\n }\n}\n\nexport function flushSync(): void {\n const batch = [...queue];\n queue.clear();\n pending = false;\n for (const callback of batch) {\n callback();\n }\n}\n","import { scheduleUpdate } from './scheduler';\r\nimport type { VNode, Bindings, Lifecycle, ComponentFunction } from './vnode';\r\n\r\nexport const CONNECTED: unique symbol = Symbol('PULSE_CONNECTED');\r\n\r\n// Pluggable devtools hooks — stored on globalThis so separate bundles\r\n// (pulse core vs devtools) share the same hook storage.\r\ninterface ComponentHooks {\r\n onMount: ((instance: any) => void) | null;\r\n onUnmount: ((instance: any) => void) | null;\r\n}\r\n\r\nconst G = globalThis as any;\r\nif (!G.__PULSE_HOOKS__) {\r\n G.__PULSE_HOOKS__ = { onMount: null, onUnmount: null };\r\n}\r\nconst hooks: ComponentHooks = G.__PULSE_HOOKS__;\r\n\r\nexport function __setComponentHooks(\r\n onMount: ((instance: ComponentInstance) => void) | null,\r\n onUnmount: ((instance: ComponentInstance) => void) | null,\r\n): void {\r\n hooks.onMount = onMount;\r\n hooks.onUnmount = onUnmount;\r\n}\r\n\r\nexport function connect(\r\n bindings: Bindings | null | undefined,\r\n lifecycle?: Lifecycle,\r\n) {\r\n return function wrapComponent(Component: ComponentFunction) {\r\n const b = bindings || {};\r\n\r\n function ConnectedComponent(props: Record<string, any>): VNode | null {\r\n const selectedProps: Record<string, any> = {};\r\n for (const propName in b) {\r\n const { store, selector } = b[propName];\r\n selectedProps[propName] = selector(store.getState());\r\n }\r\n return Component({ ...selectedProps, ...props });\r\n }\r\n\r\n (ConnectedComponent as any)[CONNECTED] = true;\r\n (ConnectedComponent as any)._bindings = b;\r\n (ConnectedComponent as any)._innerComponent = Component;\r\n if (lifecycle) (ConnectedComponent as any)._lifecycle = lifecycle;\r\n ConnectedComponent.displayName = `Connected(${(Component as any).displayName || Component.name || 'Anonymous'})`;\r\n\r\n return ConnectedComponent;\r\n };\r\n}\r\n\r\nexport class ComponentInstance {\r\n connectedFn: ComponentFunction;\r\n props: Record<string, any>;\r\n prevSelected: Record<string, any>;\r\n unsubscribers: (() => void)[];\r\n lastVTree: VNode | null;\r\n parentDom: Node | null;\r\n _renderCallback: (() => void) | null;\r\n _mountCleanup: (() => void) | null;\r\n\r\n constructor(connectedFn: ComponentFunction, props: Record<string, any>) {\r\n this.connectedFn = connectedFn;\r\n this.props = props;\r\n this.prevSelected = {};\r\n this.unsubscribers = [];\r\n this.lastVTree = null;\r\n this.parentDom = null;\r\n this._renderCallback = null;\r\n this._mountCleanup = null;\r\n }\r\n\r\n mount(parentDom: Node, renderCallback: () => void): void {\r\n this.parentDom = parentDom;\r\n this._renderCallback = renderCallback;\r\n\r\n const bindings: Bindings = (this.connectedFn as any)._bindings;\r\n\r\n for (const propName in bindings) {\r\n const { store, selector } = bindings[propName];\r\n this.prevSelected[propName] = selector(store.getState());\r\n }\r\n\r\n for (const propName in bindings) {\r\n const { store } = bindings[propName];\r\n const unsub = store.subscribe(() => {\r\n this._onStoreChange();\r\n });\r\n this.unsubscribers.push(unsub);\r\n }\r\n\r\n // Lifecycle: call onMount after subscriptions are live\r\n const lifecycle: Lifecycle | undefined = (this.connectedFn as any)\r\n ._lifecycle;\r\n if (lifecycle?.onMount) {\r\n const cleanup = lifecycle.onMount({\r\n dom: this.lastVTree?._dom,\r\n props: this.props,\r\n });\r\n if (typeof cleanup === 'function') {\r\n this._mountCleanup = cleanup;\r\n }\r\n }\r\n\r\n // Devtools hook\r\n if (hooks.onMount) hooks.onMount(this);\r\n }\r\n\r\n _onStoreChange(): void {\r\n const bindings: Bindings = (this.connectedFn as any)._bindings;\r\n let changed = false;\r\n\r\n for (const propName in bindings) {\r\n const { store, selector } = bindings[propName];\r\n const newValue = selector(store.getState());\r\n if (!shallowEqual(newValue, this.prevSelected[propName])) {\r\n changed = true;\r\n break;\r\n }\r\n }\r\n\r\n if (changed) {\r\n scheduleUpdate(this._renderCallback!);\r\n }\r\n }\r\n\r\n updateSelected(): void {\r\n const bindings: Bindings = (this.connectedFn as any)._bindings;\r\n for (const propName in bindings) {\r\n const { store, selector } = bindings[propName];\r\n this.prevSelected[propName] = selector(store.getState());\r\n }\r\n }\r\n\r\n unmount(): void {\r\n // Devtools hook\r\n if (hooks.onUnmount) hooks.onUnmount(this);\r\n\r\n // Lifecycle: cleanup from onMount, then onDestroy\r\n if (this._mountCleanup) {\r\n this._mountCleanup();\r\n this._mountCleanup = null;\r\n }\r\n const lifecycle: Lifecycle | undefined = (this.connectedFn as any)\r\n ._lifecycle;\r\n if (lifecycle?.onDestroy) {\r\n lifecycle.onDestroy({ props: this.props });\r\n }\r\n\r\n for (const unsub of this.unsubscribers) {\r\n unsub();\r\n }\r\n this.unsubscribers = [];\r\n this._renderCallback = null;\r\n }\r\n}\r\n\r\nexport function shallowEqual(a: any, b: any): boolean {\r\n if (Object.is(a, b)) return true;\r\n if (typeof a !== 'object' || typeof b !== 'object') return false;\r\n if (a === null || b === null) return false;\r\n\r\n const keysA = Object.keys(a);\r\n const keysB = Object.keys(b);\r\n if (keysA.length !== keysB.length) return false;\r\n\r\n for (const key of keysA) {\r\n if (\r\n !Object.prototype.hasOwnProperty.call(b, key) ||\r\n !Object.is(a[key], b[key])\r\n ) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n","import { TEXT_NODE } from './vnode';\nimport type { VNode } from './vnode';\n\nexport const PATCH = {\n CREATE: 'CREATE',\n REMOVE: 'REMOVE',\n REPLACE: 'REPLACE',\n UPDATE: 'UPDATE',\n TEXT: 'TEXT',\n MOVE: 'MOVE',\n CHILDREN: 'CHILDREN',\n} as const;\n\nexport type PatchType = (typeof PATCH)[keyof typeof PATCH];\n\nexport interface PropPatches {\n set: Record<string, any>;\n remove: string[];\n}\n\nexport type Patch =\n | { type: typeof PATCH.CREATE; newVNode: VNode; anchor?: VNode | null }\n | { type: typeof PATCH.REMOVE; target: VNode }\n | { type: typeof PATCH.REPLACE; oldVNode: VNode; newVNode: VNode }\n | { type: typeof PATCH.UPDATE; target: VNode; propPatches: PropPatches }\n | { type: typeof PATCH.TEXT; oldVNode: VNode; newVNode: VNode }\n | {\n type: typeof PATCH.MOVE;\n vnode: VNode;\n anchor: VNode | null;\n childPatches: Patch[];\n }\n | { type: typeof PATCH.CHILDREN; parent: VNode; childPatches: Patch[] };\n\nexport function diff(oldVNode: VNode | null, newVNode: VNode | null): Patch[] {\n if (newVNode == null && oldVNode == null) return [];\n if (newVNode == null) return [{ type: PATCH.REMOVE, target: oldVNode! }];\n if (oldVNode == null) return [{ type: PATCH.CREATE, newVNode }];\n\n if (oldVNode.type !== newVNode.type) {\n return [{ type: PATCH.REPLACE, oldVNode, newVNode }];\n }\n\n // Transfer _dom reference: the new vnode represents the same DOM node\n newVNode._dom = oldVNode._dom;\n\n if (oldVNode.type === TEXT_NODE) {\n if (oldVNode.props.nodeValue !== newVNode.props.nodeValue) {\n return [{ type: PATCH.TEXT, oldVNode, newVNode }];\n }\n return [];\n }\n\n const patches: Patch[] = [];\n\n const propPatches = diffProps(oldVNode.props, newVNode.props);\n if (propPatches) {\n patches.push({ type: PATCH.UPDATE, target: oldVNode, propPatches });\n }\n\n const childPatches = diffChildren(oldVNode.children, newVNode.children);\n if (childPatches.length) {\n patches.push({ type: PATCH.CHILDREN, parent: oldVNode, childPatches });\n }\n\n return patches;\n}\n\nfunction diffProps(\n oldProps: Record<string, any>,\n newProps: Record<string, any>,\n): PropPatches | null {\n const set: Record<string, any> = {};\n const remove: string[] = [];\n let hasChanges = false;\n\n for (const key in newProps) {\n if (key === 'children') continue;\n if (oldProps[key] !== newProps[key]) {\n set[key] = newProps[key];\n hasChanges = true;\n }\n }\n\n for (const key in oldProps) {\n if (key === 'children') continue;\n if (!(key in newProps)) {\n remove.push(key);\n hasChanges = true;\n }\n }\n\n return hasChanges ? { set, remove } : null;\n}\n\nfunction sameVNode(a: VNode | null, b: VNode | null): boolean {\n if (a == null || b == null) return false;\n return a.type === b.type && a.key === b.key;\n}\n\nfunction warnChildKeys(children: (VNode | null)[], label: string): void {\n const seen = new Set<string | number>();\n let keyedCount = 0;\n let unkeyedCount = 0;\n\n for (const child of children) {\n if (child == null) continue;\n if (child.key != null) {\n keyedCount++;\n if (seen.has(child.key)) {\n console.warn(\n `[pulse] Duplicate key \"${String(child.key)}\" in ${label} children. ` +\n `Keys must be unique among siblings.`,\n );\n }\n seen.add(child.key);\n } else {\n unkeyedCount++;\n }\n }\n\n if (keyedCount > 0 && unkeyedCount > 0) {\n console.warn(\n `[pulse] Mixed keyed and unkeyed children in ${label} list ` +\n `(${keyedCount} keyed, ${unkeyedCount} unkeyed). ` +\n `Either all children should have keys or none should.`,\n );\n }\n}\n\nfunction diffChildren(\n oldChildren: (VNode | null)[],\n newChildren: VNode[],\n): Patch[] {\n if (process.env.NODE_ENV !== 'production') {\n warnChildKeys(oldChildren, 'old');\n warnChildKeys(newChildren, 'new');\n }\n\n const patches: Patch[] = [];\n\n let oldStartIdx = 0;\n let oldEndIdx = oldChildren.length - 1;\n let newStartIdx = 0;\n let newEndIdx = newChildren.length - 1;\n\n let oldStartVNode = oldChildren[oldStartIdx];\n let oldEndVNode = oldChildren[oldEndIdx];\n let newStartVNode = newChildren[newStartIdx];\n let newEndVNode = newChildren[newEndIdx];\n\n // Phase 1: two-pointer scan\n while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\n if (oldStartVNode == null) {\n oldStartVNode = oldChildren[++oldStartIdx];\n continue;\n }\n if (oldEndVNode == null) {\n oldEndVNode = oldChildren[--oldEndIdx];\n continue;\n }\n\n if (sameVNode(oldStartVNode, newStartVNode)) {\n patches.push(...diff(oldStartVNode, newStartVNode));\n oldStartVNode = oldChildren[++oldStartIdx];\n newStartVNode = newChildren[++newStartIdx];\n } else if (sameVNode(oldEndVNode, newEndVNode)) {\n patches.push(...diff(oldEndVNode, newEndVNode));\n oldEndVNode = oldChildren[--oldEndIdx];\n newEndVNode = newChildren[--newEndIdx];\n } else if (sameVNode(oldStartVNode, newEndVNode)) {\n patches.push({\n type: PATCH.MOVE,\n vnode: oldStartVNode!,\n anchor: oldChildren[oldEndIdx + 1] || null,\n childPatches: diff(oldStartVNode, newEndVNode),\n });\n oldStartVNode = oldChildren[++oldStartIdx];\n newEndVNode = newChildren[--newEndIdx];\n } else if (sameVNode(oldEndVNode, newStartVNode)) {\n patches.push({\n type: PATCH.MOVE,\n vnode: oldEndVNode!,\n anchor: oldStartVNode,\n childPatches: diff(oldEndVNode, newStartVNode),\n });\n oldEndVNode = oldChildren[--oldEndIdx];\n newStartVNode = newChildren[++newStartIdx];\n } else {\n // Fall through to key-map phase\n break;\n }\n }\n\n // Phase 2: key-map fallback for remaining nodes\n if (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\n const keyMap = new Map<string | number, number>();\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n const key = oldChildren[i]?.key;\n if (key != null) keyMap.set(key, i);\n }\n\n while (newStartIdx <= newEndIdx) {\n newStartVNode = newChildren[newStartIdx];\n const oldIdx =\n newStartVNode.key != null ? keyMap.get(newStartVNode.key) : undefined;\n\n if (oldIdx !== undefined) {\n const matchedOld = oldChildren[oldIdx]!;\n patches.push({\n type: PATCH.MOVE,\n vnode: matchedOld,\n anchor: oldChildren[oldStartIdx] || null,\n childPatches: diff(matchedOld, newStartVNode),\n });\n oldChildren[oldIdx] = null;\n keyMap.delete(newStartVNode.key!);\n } else {\n patches.push({\n type: PATCH.CREATE,\n newVNode: newStartVNode,\n anchor: oldChildren[oldStartIdx] || null,\n });\n }\n newStartIdx++;\n }\n\n // Remove unconsumed old children\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n if (oldChildren[i] != null) {\n patches.push({ type: PATCH.REMOVE, target: oldChildren[i]! });\n }\n }\n }\n\n // Phase 3: remaining creates or removes\n if (oldStartIdx > oldEndIdx) {\n const anchor = newChildren[newEndIdx + 1] || null;\n for (let i = newStartIdx; i <= newEndIdx; i++) {\n patches.push({ type: PATCH.CREATE, newVNode: newChildren[i], anchor });\n }\n } else if (newStartIdx > newEndIdx) {\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\n if (oldChildren[i] != null) {\n patches.push({ type: PATCH.REMOVE, target: oldChildren[i]! });\n }\n }\n }\n\n return patches;\n}\n","import { TEXT_NODE, FRAGMENT } from './vnode';\nimport { PATCH } from './diff';\nimport type { VNode } from './vnode';\nimport type { Patch } from './diff';\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nexport function createDOMNode(vnode: VNode, namespace?: string): Node {\n if (vnode.type === TEXT_NODE) {\n const textNode = document.createTextNode(vnode.props.nodeValue);\n vnode._dom = textNode;\n return textNode;\n }\n\n if (vnode.type === FRAGMENT) {\n const frag = document.createDocumentFragment();\n for (const child of vnode.children) {\n frag.appendChild(createDOMNode(child, namespace));\n }\n // For fragments, store ref to first child for positioning\n vnode._dom = frag;\n return frag;\n }\n\n // SVG namespace: 'svg' enters, 'foreignObject' exits back to HTML\n if (vnode.type === 'svg') {\n namespace = SVG_NS;\n } else if (vnode.type === 'foreignObject') {\n namespace = undefined;\n }\n\n const el = namespace\n ? document.createElementNS(namespace, vnode.type as string)\n : document.createElement(vnode.type as string);\n applyProps(el, {}, vnode.props);\n\n for (const child of vnode.children) {\n el.appendChild(createDOMNode(child, namespace));\n }\n\n vnode._dom = el;\n return el;\n}\n\nexport function applyProps(\n el: Element,\n oldProps: Record<string, any>,\n newProps: Record<string, any>,\n): void {\n for (const key in oldProps) {\n if (key === 'children' || key === 'key') continue;\n if (!(key in newProps)) {\n removeProp(el, key, oldProps[key]);\n }\n }\n for (const key in newProps) {\n if (key === 'children' || key === 'key') continue;\n if (oldProps[key] !== newProps[key]) {\n setProp(el, key, newProps[key], oldProps[key]);\n }\n }\n}\n\nfunction setProp(\n el: Element,\n key: string,\n value: any,\n oldValue: any,\n): void {\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase();\n if (oldValue) el.removeEventListener(eventName, oldValue);\n if (value) el.addEventListener(eventName, value);\n } else if (key === 'className' || key === 'class') {\n // SVG className is an SVGAnimatedString — use setAttribute instead\n if (el instanceof SVGElement) {\n el.setAttribute('class', value || '');\n } else {\n (el as HTMLElement).className = value || '';\n }\n } else if (key === 'style' && typeof value === 'object') {\n if (typeof oldValue === 'object' && oldValue) {\n for (const prop in oldValue) {\n if (!(prop in value)) ((el as HTMLElement).style as any)[prop] = '';\n }\n }\n Object.assign((el as HTMLElement).style, value);\n } else if (key === 'dangerouslySetInnerHTML') {\n if (value && typeof value.__html === 'string') {\n el.innerHTML = value.__html;\n }\n } else if (key === 'ref') {\n if (typeof value === 'function') value(el);\n } else if (key in el && !(el instanceof SVGElement)) {\n // DOM property — set directly for properties like value, checked, selected\n try {\n (el as any)[key] = value ?? '';\n } catch {\n el.setAttribute(key, value);\n }\n } else if (value === true) {\n el.setAttribute(key, '');\n } else if (value === false || value == null) {\n el.removeAttribute(key);\n } else {\n el.setAttribute(key, value);\n }\n}\n\nfunction removeProp(el: Element, key: string, oldValue: any): void {\n if (key.startsWith('on')) {\n el.removeEventListener(key.slice(2).toLowerCase(), oldValue);\n } else if (key === 'dangerouslySetInnerHTML') {\n el.innerHTML = '';\n } else if (key === 'className' || key === 'class') {\n if (el instanceof SVGElement) {\n el.removeAttribute('class');\n } else {\n (el as HTMLElement).className = '';\n }\n } else if (key in el && !(el instanceof SVGElement)) {\n try {\n (el as any)[key] = '';\n } catch {\n el.removeAttribute(key);\n }\n } else {\n el.removeAttribute(key);\n }\n}\n\nfunction inferNamespace(node: Node): string | undefined {\n return node instanceof SVGElement ? SVG_NS : undefined;\n}\n\nexport function applyPatches(parentDom: Node, patches: Patch[]): void {\n for (const patch of patches) {\n switch (patch.type) {\n case PATCH.CREATE: {\n const dom = createDOMNode(patch.newVNode, inferNamespace(parentDom));\n if (patch.anchor?._dom) {\n parentDom.insertBefore(dom, patch.anchor._dom);\n } else {\n parentDom.appendChild(dom);\n }\n break;\n }\n\n case PATCH.REMOVE: {\n const dom = patch.target._dom;\n if (dom?.parentNode) {\n dom.parentNode.removeChild(dom);\n }\n break;\n }\n\n case PATCH.REPLACE: {\n const oldDom = patch.oldVNode._dom;\n const parent = oldDom?.parentNode;\n const newDom = createDOMNode(\n patch.newVNode,\n parent ? inferNamespace(parent) : undefined,\n );\n if (parent) {\n parent.replaceChild(newDom, oldDom!);\n }\n break;\n }\n\n case PATCH.UPDATE: {\n const dom = patch.target._dom as Element;\n const { set, remove } = patch.propPatches;\n for (const key of remove) {\n removeProp(dom, key, patch.target.props[key]);\n }\n for (const key in set) {\n setProp(dom, key, set[key], patch.target.props[key]);\n }\n break;\n }\n\n case PATCH.TEXT: {\n const dom = patch.oldVNode._dom;\n if (dom) dom.nodeValue = patch.newVNode.props.nodeValue;\n break;\n }\n\n case PATCH.MOVE: {\n const dom = patch.vnode._dom;\n if (dom) {\n if (patch.anchor?._dom) {\n parentDom.insertBefore(dom, patch.anchor._dom);\n } else {\n parentDom.appendChild(dom);\n }\n }\n if (patch.childPatches?.length && dom) {\n applyPatches(dom, patch.childPatches);\n }\n break;\n }\n\n case PATCH.CHILDREN: {\n const dom = patch.parent._dom;\n if (dom && patch.childPatches.length) {\n applyPatches(dom, patch.childPatches);\n }\n break;\n }\n }\n }\n}\n","import { diff } from './diff';\r\nimport { createDOMNode, applyPatches } from './patch';\r\nimport { CONNECTED, ComponentInstance } from './connect';\r\nimport { createTextVNode } from './vnode';\r\nimport type { VNode, Lifecycle } from './vnode';\r\n\r\ninterface RootEntry {\r\n vTree: VNode;\r\n}\r\n\r\nconst roots = new WeakMap<Node, RootEntry>();\r\n\r\nexport function render(vnode: VNode, container: Node): void {\r\n const prev = roots.get(container);\r\n\r\n if (!prev) {\r\n // First mount\r\n const expanded = expand(vnode, container);\r\n if (!expanded) return;\r\n\r\n const dom = createDOMNode(expanded);\r\n container.appendChild(dom);\r\n\r\n const instances: ComponentInstance[] = [];\r\n collectInstances(expanded, instances);\r\n for (const inst of instances) {\r\n inst.mount(container, () => reRenderInstance(inst, container));\r\n }\r\n\r\n roots.set(container, { vTree: expanded });\r\n } else {\r\n // Update\r\n const expanded = expand(vnode, container);\r\n\r\n const oldInstances: ComponentInstance[] = [];\r\n collectInstances(prev.vTree, oldInstances);\r\n\r\n const patches = diff(prev.vTree, expanded);\r\n applyPatches(container, patches);\r\n\r\n const newInstances: ComponentInstance[] = [];\r\n if (expanded) collectInstances(expanded, newInstances);\r\n\r\n // Unmount removed instances\r\n const newSet = new Set(newInstances);\r\n for (const inst of oldInstances) {\r\n if (!newSet.has(inst)) {\r\n inst.unmount();\r\n }\r\n }\r\n\r\n // Mount new instances\r\n const oldSet = new Set(oldInstances);\r\n for (const inst of newInstances) {\r\n if (!oldSet.has(inst)) {\r\n inst.mount(container, () => reRenderInstance(inst, container));\r\n }\r\n }\r\n\r\n roots.set(container, { vTree: expanded! });\r\n }\r\n}\r\n\r\nfunction expand(vnode: VNode | null, parentDom: Node): VNode | null {\r\n if (vnode == null) return null;\r\n\r\n if (typeof vnode.type === 'function') {\r\n if ((vnode.type as any)[CONNECTED]) {\r\n // Connected component — with error boundary support\r\n const lifecycle: Lifecycle | undefined = (vnode.type as any)._lifecycle;\r\n\r\n try {\r\n const instance = new ComponentInstance(vnode.type, vnode.props);\r\n const childVNode = vnode.type(vnode.props);\r\n const expanded = expand(childVNode, parentDom);\r\n\r\n // Use placeholder for null returns so instance stays in tree (subscribes)\r\n const result = expanded ?? createTextVNode('');\r\n\r\n if (result._instance) {\r\n // Nested connected component: wrap outer in a boundary element\r\n // so each instance has its own VNode (no _instance collision).\r\n const boundary: VNode = {\r\n type: 'div',\r\n props: { style: { display: 'contents' } },\r\n children: [result],\r\n key: vnode.key,\r\n };\r\n boundary._instance = instance;\r\n instance.lastVTree = boundary;\r\n return boundary;\r\n }\r\n\r\n result._instance = instance;\r\n instance.lastVTree = result;\r\n\r\n return result;\r\n } catch (error) {\r\n if (lifecycle?.onError) {\r\n const fallbackVNode = lifecycle.onError({\r\n error,\r\n props: vnode.props,\r\n });\r\n return expand(fallbackVNode, parentDom);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n // Plain function component\r\n const childVNode = vnode.type({ ...vnode.props, children: vnode.children });\r\n return expand(childVNode, parentDom);\r\n }\r\n\r\n // Element, text, or fragment: recursively expand children\r\n if (vnode.children?.length) {\r\n vnode.children = vnode.children\r\n .map((child) => expand(child, parentDom))\r\n .filter((c): c is VNode => c != null);\r\n }\r\n\r\n return vnode;\r\n}\r\n\r\nfunction reRenderInstance(instance: ComponentInstance, parentDom: Node): void {\r\n // Guard: skip re-render if instance was unmounted (e.g. parent already rebuilt this subtree)\r\n if (!instance._renderCallback) return;\r\n\r\n const connectedFn = instance.connectedFn;\r\n const lifecycle: Lifecycle | undefined = (connectedFn as any)._lifecycle;\r\n\r\n try {\r\n const newVNode = connectedFn(instance.props);\r\n const rawExpanded = expand(newVNode, parentDom);\r\n\r\n // Use placeholder for null returns so instance stays in tree\r\n const innerContent = rawExpanded ?? createTextVNode('');\r\n\r\n // Wrap if nested connected component (same logic as expand)\r\n let newTree: VNode;\r\n if (innerContent._instance && innerContent._instance !== instance) {\r\n newTree = {\r\n type: 'div',\r\n props: { style: { display: 'contents' } },\r\n children: [innerContent],\r\n key: null,\r\n } as VNode;\r\n newTree._instance = instance;\r\n } else {\r\n innerContent._instance = instance;\r\n newTree = innerContent;\r\n }\r\n\r\n if (instance.lastVTree) {\r\n // Refresh stale inner instance references before diffing\r\n refreshInnerInstances(instance.lastVTree, instance);\r\n\r\n const patches = diff(instance.lastVTree, newTree);\r\n\r\n // Find the actual parent DOM node to patch against\r\n const domParent = instance.lastVTree._dom?.parentNode || parentDom;\r\n applyPatches(domParent, patches);\r\n\r\n // Transfer the _dom reference from old to new\r\n if (!newTree._dom) {\r\n newTree._dom = instance.lastVTree._dom;\r\n }\r\n }\r\n\r\n // Collect inner instances for lifecycle management\r\n const oldInner: ComponentInstance[] = [];\r\n collectInnerInstances(instance.lastVTree, oldInner, instance);\r\n const newInner: ComponentInstance[] = [];\r\n collectInnerInstances(newTree, newInner, instance);\r\n\r\n // Unmount removed inner instances\r\n const newInstSet = new Set(newInner);\r\n for (const inst of oldInner) {\r\n if (!newInstSet.has(inst)) inst.unmount();\r\n }\r\n\r\n instance.lastVTree = newTree;\r\n\r\n // Mount new inner instances\r\n const oldInstSet = new Set(oldInner);\r\n for (const inst of newInner) {\r\n if (!oldInstSet.has(inst)) {\r\n inst.mount(parentDom, () => reRenderInstance(inst, parentDom));\r\n }\r\n }\r\n\r\n // Lifecycle: onUpdate fires after every re-render (not on initial mount)\r\n if (lifecycle?.onUpdate) {\r\n lifecycle.onUpdate({\r\n dom: newTree?._dom,\r\n props: instance.props,\r\n });\r\n }\r\n\r\n instance.updateSelected();\r\n } catch (error) {\r\n if (lifecycle?.onError) {\r\n const fallbackVNode = lifecycle.onError({ error, props: instance.props });\r\n const fallbackExpanded = expand(fallbackVNode, parentDom);\r\n\r\n // Replace current DOM with fallback\r\n if (instance.lastVTree && fallbackExpanded) {\r\n refreshInnerInstances(instance.lastVTree, instance);\r\n\r\n const patches = diff(instance.lastVTree, fallbackExpanded);\r\n const domParent = instance.lastVTree._dom?.parentNode || parentDom;\r\n applyPatches(domParent, patches);\r\n\r\n if (!fallbackExpanded._dom) {\r\n fallbackExpanded._dom = instance.lastVTree._dom;\r\n }\r\n }\r\n\r\n // Unmount old inner instances on error fallback\r\n const oldInner: ComponentInstance[] = [];\r\n collectInnerInstances(instance.lastVTree, oldInner, instance);\r\n for (const inst of oldInner) inst.unmount();\r\n\r\n instance.lastVTree = fallbackExpanded;\r\n instance.updateSelected();\r\n } else {\r\n throw error;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Before diffing a parent's lastVTree, refresh any inner connected components'\r\n * subtrees to reflect their current state (they may have re-rendered independently).\r\n */\r\nfunction refreshInnerInstances(\r\n vnode: VNode | null,\r\n skip: ComponentInstance,\r\n): void {\r\n if (!vnode || !vnode.children) return;\r\n for (let i = 0; i < vnode.children.length; i++) {\r\n const child = vnode.children[i];\r\n if (\r\n child._instance &&\r\n child._instance !== skip &&\r\n child._instance.lastVTree\r\n ) {\r\n // Replace stale reference with instance's current lastVTree\r\n if (child._instance.lastVTree !== child) {\r\n vnode.children[i] = child._instance.lastVTree;\r\n }\r\n }\r\n refreshInnerInstances(vnode.children[i], skip);\r\n }\r\n}\r\n\r\nfunction collectInstances(\r\n vnode: VNode | null,\r\n result: ComponentInstance[],\r\n): void {\r\n if (!vnode) return;\r\n if (vnode._instance) result.push(vnode._instance);\r\n if (vnode.children) {\r\n for (const child of vnode.children) {\r\n collectInstances(child, result);\r\n }\r\n }\r\n}\r\n\r\nfunction collectInnerInstances(\r\n vnode: VNode | null,\r\n result: ComponentInstance[],\r\n skip: ComponentInstance,\r\n): void {\r\n if (!vnode) return;\r\n if (vnode._instance && vnode._instance !== skip) result.push(vnode._instance);\r\n if (vnode.children) {\r\n for (const child of vnode.children) {\r\n collectInnerInstances(child, result, skip);\r\n }\r\n }\r\n}\r\n","import { createStore } from './store';\nimport { connect } from './connect';\nimport { h } from './createElement';\nimport type { Store } from './store';\nimport type { VNode, ComponentFunction } from './vnode';\n\n// ── Types ──────────────────────────────────────────────────\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n matched: string | null;\n}\n\nexport interface RouteConfig {\n path: string;\n}\n\nexport interface RouterOptions {\n routes: RouteConfig[];\n initialPath?: string;\n}\n\nexport interface Router {\n store: Store<RouteState>;\n navigate: (path: string) => void;\n redirect: (path: string) => void;\n back: () => void;\n forward: () => void;\n destroy: () => void;\n Route: ComponentFunction;\n Link: ComponentFunction;\n Redirect: ComponentFunction;\n}\n\n// ── Path Utilities ─────────────────────────────────────────\n\nfunction normalizePath(path: string): string {\n // Strip trailing slash (but keep root \"/\")\n if (path.length > 1 && path.endsWith('/')) {\n return path.slice(0, -1);\n }\n return path || '/';\n}\n\nfunction parseQuery(search: string): Record<string, string> {\n const result: Record<string, string> = {};\n if (!search) return result;\n const cleaned = search.startsWith('?') ? search.slice(1) : search;\n if (!cleaned) return result;\n const params = new URLSearchParams(cleaned);\n params.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n\n// ── Route Matching ─────────────────────────────────────────\n\ninterface MatchResult {\n pattern: string;\n params: Record<string, string>;\n}\n\nfunction matchSingle(\n path: string,\n pattern: string,\n): { params: Record<string, string> } | null {\n const normalizedPath = normalizePath(path);\n const normalizedPattern = normalizePath(pattern);\n\n // Catch-all wildcard\n if (normalizedPattern === '*') {\n return { params: { '*': normalizedPath } };\n }\n\n const pathSegments =\n normalizedPath === '/' ? [''] : normalizedPath.split('/').slice(1);\n const patternSegments =\n normalizedPattern === '/' ? [''] : normalizedPattern.split('/').slice(1);\n\n // Check for trailing wildcard (prefix matching)\n const hasTrailingWildcard =\n patternSegments.length > 0 &&\n patternSegments[patternSegments.length - 1] === '*';\n\n if (hasTrailingWildcard) {\n const prefixSegments = patternSegments.slice(0, -1);\n\n // Path must have at least as many segments as the prefix\n if (pathSegments.length < prefixSegments.length) return null;\n\n const params: Record<string, string> = {};\n for (let i = 0; i < prefixSegments.length; i++) {\n const ps = prefixSegments[i];\n if (ps.startsWith(':')) {\n params[ps.slice(1)] = pathSegments[i];\n } else if (ps !== pathSegments[i]) {\n return null;\n }\n }\n\n // Capture the rest as \"*\" param\n const rest = pathSegments.slice(prefixSegments.length).join('/');\n params['*'] = rest;\n return { params };\n }\n\n // Exact segment count required for non-wildcard patterns\n if (pathSegments.length !== patternSegments.length) return null;\n\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const ps = patternSegments[i];\n if (ps.startsWith(':')) {\n params[ps.slice(1)] = pathSegments[i];\n } else if (ps !== pathSegments[i]) {\n return null;\n }\n }\n\n return { params };\n}\n\nfunction matchRoute(path: string, routes: RouteConfig[]): MatchResult | null {\n for (const route of routes) {\n const result = matchSingle(path, route.path);\n if (result) {\n return { pattern: route.path, params: result.params };\n }\n }\n return null;\n}\n\n// ── Router Factory ─────────────────────────────────────────\n\nexport function createRouter(options: RouterOptions): Router {\n const { routes, initialPath } = options;\n\n // Read initial URL\n const initPathRaw = initialPath ?? window.location.pathname;\n const initSearch = initialPath ? '' : window.location.search;\n const initPath = normalizePath(initPathRaw);\n const initQuery = parseQuery(initSearch);\n const initMatch = matchRoute(initPath, routes);\n\n // Create the route store\n const store = createStore<RouteState>({\n state: {\n path: initPath,\n params: initMatch?.params ?? {},\n query: initQuery,\n matched: initMatch?.pattern ?? null,\n },\n actions: {\n _sync: (_: RouteState, payload: RouteState) => payload,\n },\n });\n\n // ── Navigation ──\n\n function buildState(rawPath: string): RouteState {\n const qIdx = rawPath.indexOf('?');\n const pathname = normalizePath(\n qIdx >= 0 ? rawPath.slice(0, qIdx) : rawPath,\n );\n const queryStr = qIdx >= 0 ? rawPath.slice(qIdx + 1) : '';\n const query = parseQuery(queryStr);\n const match = matchRoute(pathname, routes);\n return {\n path: pathname,\n params: match?.params ?? {},\n query,\n matched: match?.pattern ?? null,\n };\n }\n\n function navigate(path: string): void {\n const state = buildState(path);\n window.history.pushState(null, '', path);\n store.dispatch('_sync', state);\n }\n\n function redirect(path: string): void {\n const state = buildState(path);\n window.history.replaceState(null, '', path);\n store.dispatch('_sync', state);\n }\n\n function back(): void {\n window.history.back();\n }\n\n function forward(): void {\n window.history.forward();\n }\n\n // ── Popstate ──\n\n function onPopState(): void {\n const state = buildState(window.location.pathname + window.location.search);\n store.dispatch('_sync', state);\n }\n\n window.addEventListener('popstate', onPopState);\n\n function destroy(): void {\n window.removeEventListener('popstate', onPopState);\n }\n\n // ── Route Component (connected) ──\n\n const Route = connect({\n _path: store.select((s: RouteState) => s.path),\n })(function RouteInner(props: Record<string, any>): VNode | null {\n const { _path, path: pattern, component, children, ...rest } = props;\n const match = matchSingle(_path, pattern);\n if (!match) return null;\n if (component) {\n return h(component, { ...rest, params: match.params });\n }\n return children?.[0] ?? null;\n });\n\n // ── Link Component (plain) ──\n\n function Link(props: Record<string, any>): VNode {\n const { to, children, ...rest } = props;\n return h(\n 'a',\n {\n ...rest,\n href: to,\n onClick: (e: MouseEvent) => {\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return;\n e.preventDefault();\n navigate(to);\n },\n },\n ...(children || []),\n );\n }\n\n // ── Redirect Component (plain) ──\n\n function RedirectComponent(props: Record<string, any>): VNode | null {\n redirect(props.to);\n return null;\n }\n\n return {\n store,\n navigate,\n redirect,\n back,\n forward,\n destroy,\n Route,\n Link,\n Redirect: RedirectComponent,\n };\n}\n","import type { Store } from './store';\n\nexport interface DispatchContext<S = any> {\n store: Store<S>;\n actionName: string;\n payload: any;\n prevState: S;\n nextState: S | undefined;\n}\n\nexport type Middleware<S = any> = (\n ctx: DispatchContext<S>,\n next: () => void,\n) => void;\n\nexport interface ActionEntry {\n actionName: string;\n payload: any;\n prevState: any;\n nextState: any;\n timestamp: number;\n}\n\n/**\n * Logger middleware — logs action dispatches with prev/next state.\n */\nexport function logger(): Middleware {\n return (ctx, next) => {\n const label = `[pulse] ${ctx.actionName}`;\n console.group(label);\n console.log('prev state', ctx.prevState);\n console.log('payload', ctx.payload);\n next();\n console.log('next state', ctx.nextState);\n console.groupEnd();\n };\n}\n\n/**\n * Async action helper — wraps an async operation with loading/success/error dispatches.\n */\nexport interface AsyncActionConfig<R, A extends any[] = any[]> {\n start?: string;\n run: (...args: A) => Promise<R>;\n ok: string;\n fail?: string;\n}\n\nexport function createAsyncAction<S, R, A extends any[] = any[]>(\n store: Store<S>,\n config: AsyncActionConfig<R, A>,\n): (...args: A) => Promise<R> {\n return async (...args: A): Promise<R> => {\n if (config.start) store.dispatch(config.start);\n try {\n const result = await config.run(...args);\n store.dispatch(config.ok, result);\n return result;\n } catch (e: any) {\n if (config.fail) {\n store.dispatch(config.fail, e?.message ?? String(e));\n } else {\n throw e;\n }\n return undefined as any;\n }\n };\n}\n\n/**\n * Action history middleware — pushes entries to a caller-owned array.\n */\nexport function actionHistory(\n history: ActionEntry[],\n opts?: { maxEntries?: number },\n): Middleware {\n const max = opts?.maxEntries ?? Infinity;\n return (ctx, next) => {\n next();\n history.push({\n actionName: ctx.actionName,\n payload: ctx.payload,\n prevState: ctx.prevState,\n nextState: ctx.nextState ?? ctx.prevState,\n timestamp: Date.now(),\n });\n if (history.length > max) {\n history.splice(0, history.length - max);\n }\n };\n}\n"],"names":["TEXT_NODE","FRAGMENT","createTextVNode","text","normalizeChild","child","flattenChildren","rawChildren","result","normalized","h","type","props","key","children","createStore","config","state","actions","listeners","mw","getState","notify","listener","dispatchSimple","actionName","payload","action","nextState","dispatchWithMiddleware","ctx","storeObj","idx","next","fn","dispatch","subscribe","select","selectorFn","pending","queue","scheduleUpdate","callback","flush","batch","flushSync","CONNECTED","G","hooks","connect","bindings","lifecycle","Component","b","ConnectedComponent","selectedProps","propName","store","selector","ComponentInstance","connectedFn","__publicField","parentDom","renderCallback","_a","unsub","cleanup","changed","newValue","shallowEqual","a","keysA","keysB","PATCH","diff","oldVNode","newVNode","patches","propPatches","diffProps","childPatches","diffChildren","oldProps","newProps","set","remove","hasChanges","sameVNode","warnChildKeys","label","seen","keyedCount","unkeyedCount","oldChildren","newChildren","oldStartIdx","oldEndIdx","newStartIdx","newEndIdx","oldStartVNode","oldEndVNode","newStartVNode","newEndVNode","keyMap","i","oldIdx","matchedOld","anchor","SVG_NS","createDOMNode","vnode","namespace","textNode","frag","el","applyProps","removeProp","setProp","value","oldValue","eventName","prop","inferNamespace","node","applyPatches","_b","_c","patch","dom","oldDom","parent","newDom","roots","render","container","prev","expanded","expand","oldInstances","collectInstances","newInstances","newSet","inst","oldSet","reRenderInstance","instances","instance","childVNode","boundary","error","fallbackVNode","c","innerContent","newTree","refreshInnerInstances","domParent","oldInner","collectInnerInstances","newInner","newInstSet","oldInstSet","fallbackExpanded","skip","normalizePath","path","parseQuery","search","cleaned","matchSingle","pattern","normalizedPath","normalizedPattern","pathSegments","patternSegments","prefixSegments","params","ps","rest","matchRoute","routes","route","createRouter","options","initialPath","initPathRaw","initSearch","initPath","initQuery","initMatch","_","buildState","rawPath","qIdx","pathname","queryStr","query","match","navigate","redirect","back","forward","onPopState","destroy","Route","s","_path","component","Link","to","e","RedirectComponent","logger","createAsyncAction","args","actionHistory","history","opts","max"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shane_il/pulse",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A render-driven UI framework with virtual DOM and immutable stores",
5
5
  "author": "Shane-IL",
6
6
  "repository": {
@@ -35,6 +35,8 @@
35
35
  "typecheck": "tsc --noEmit",
36
36
  "test": "vitest run",
37
37
  "test:watch": "vitest",
38
+ "lint": "eslint .",
39
+ "format": "prettier --write .",
38
40
  "prepublishOnly": "npm test && npm run build"
39
41
  },
40
42
  "keywords": [
@@ -50,8 +52,12 @@
50
52
  ],
51
53
  "license": "MIT",
52
54
  "devDependencies": {
55
+ "@eslint/js": "^10.0.1",
56
+ "eslint": "^10.1.0",
53
57
  "jsdom": "^25.0.0",
58
+ "prettier": "^3.8.1",
54
59
  "typescript": "^5.9.3",
60
+ "typescript-eslint": "^8.57.1",
55
61
  "vite": "^6.0.0",
56
62
  "vitest": "^3.0.0"
57
63
  }