import type { JSX } from "../jsx" ; import type { Accessor , Setter } from "../reactive/signal" ; export const equalFn = < T > ( a , b ) => a === b ; export const $PROXY = Symbol ( "solid-proxy" ) ; export const $DEVCOMP = Symbol ( 'solid-dev-component' ) ; export const DEV = { } ; const ERROR = Symbol ( "error" ) ; const UNOWNED = { context : null , owner : null } ; export let Owner = null ; interface Owner { owner : Owner | null ; context : any | null ; } export function createRoot < T > ( fn , detachedOwner ? ) { detachedOwner && ( Owner = detachedOwner ) ; const owner = Owner , root = fn . length === 0 ? UNOWNED : { context : null , owner } ; Owner = root ; let result ; try { result = fn ( ( ) => { } ) ; } catch ( err ) { const fns = lookup ( Owner , ERROR ) ; if ( ! fns ) throw err ; fns . forEach ( ( f ) => f ( err ) ) ; } finally { Owner = owner ; } return result ! ; } export function createSignal < T > ( value , options ? ) { return [ ( ) => value as T , v => { return ( value = typeof v === "function" ? ( v as ( prev : T ) => T ) ( value ) : v ) ; } ] ; } export function createComputed < T > ( fn , value ? ) { Owner = { owner : Owner , context : null } ; try { fn ( value ) ; } catch ( err ) { const fns = lookup ( Owner , ERROR ) ; if ( ! fns ) throw err ; fns . forEach ( ( f ) => f ( err ) ) ; } finally { Owner = Owner . owner ; } } export const createRenderEffect = createComputed ; export function createEffect < T > ( fn , value ? ) { } export function createReaction ( fn ) { return ( fn ) => { fn ( ) ; } ; } export function createMemo < T > ( fn , value ? ) { Owner = { owner : Owner , context : null } ; let v ; try { v = fn ( value ) ; } catch ( err ) { const fns = lookup ( Owner , ERROR ) ; if ( ! fns ) throw err ; fns . forEach ( ( f ) => f ( err ) ) ; } finally { Owner = Owner . owner ; } return ( ) => v ; } export function createDeferred < T > ( source ) { return source ; } export function createSelector < T > ( source , fn ) { return ( k ) => fn ( k , source ( ) ) ; } export function batch < T > ( fn ) { return fn ( ) ; } export const untrack = batch ; export function on < T , U > ( deps , fn , options = { } ) { const isArray = Array . isArray ( deps ) ; const defer = options . defer ; return ( ) => { if ( defer ) return undefined ; let value ; if ( isArray ) { value = [ ] ; for ( let i = 0 ; i < deps . length ; i ++ ) value . push ( ( deps as Array < ( ) => T > ) [ i ] ( ) ) ; } else value = ( deps as ( ) => T ) ( ) ; return fn ! ( value ) ; } ; } export function onMount ( fn ) { } export function onCleanup ( fn ) { } export function onError ( fn ) { if ( Owner === null ) "_SOLID_DEV_" && console . warn ( "error handlers created outside a `createRoot` or `render` will never be run" ) ; else if ( Owner . context === null ) Owner . context = { [ ERROR ] : [ fn ] } ; else if ( ! Owner . context [ ERROR ] ) Owner . context [ ERROR ] = [ fn ] ; else Owner . context [ ERROR ] . push ( fn ) ; } export function getListener ( ) { return null ; } export interface Context < T > { id : symbol ; Provider : ( props : { value : T ; children : any ; } ) => any ; defaultValue ? : T ; } export function createContext < T > ( defaultValue ? ) { const id = Symbol ( "context" ) ; return { id , Provider : createProvider ( id ) , defaultValue } ; } export function useContext < T > ( context ) { return lookup ( Owner , context . id ) || context . defaultValue ; } export function getOwner ( ) { return Owner ; } export function children ( fn ) { return createMemo ( ( ) => resolveChildren ( fn ( ) ) ) ; } export function runWithOwner ( o , fn ) { const prev = Owner ; Owner = o ; try { return fn ( ) ; } finally { Owner = prev ; } } export function lookup ( owner , key ) { return ( owner && ( ( owner . context && owner . context [ key ] !== undefined ) ? owner . context [ key ] : owner . owner && lookup ( owner . owner , key ) ) ) ; } function resolveChildren ( children ) { if ( typeof children === "function" && ! children . length ) return resolveChildren ( children ( ) ) ; if ( Array . isArray ( children ) ) { const results = [ ] ; for ( let i = 0 ; i < children . length ; i ++ ) { const result = resolveChildren ( children [ i ] ) ; Array . isArray ( result ) ? results . push . apply ( results , result ) : results . push ( result ) ; } return results ; } return children ; } function createProvider ( id ) { return function provider ( props ) { return createMemo ( ( ) => { Owner ! . context = { [ id ] : props . value } ; return children ( ( ) => props . children ) ; } ) as unknown as JSX . Element ; } ; } export interface Task { id : number ; fn : ( ( didTimeout : boolean ) => void ) | null ; startTime : number ; expirationTime : number ; } export function requestCallback ( fn , options ? ) { return { id : 0 , fn : ( ) => { } , startTime : 0 , expirationTime : 0 } ; } export function cancelCallback ( task ) { } export function mapArray < T , U > ( list , mapFn , options = { } ) { const items = list ( ) ; let s = [ ] ; if ( items . length ) { for ( let i = 0 , len = items . length ; i < len ; i ++ ) s . push ( mapFn ( items [ i ] , ( ) => i ) ) ; } else if ( options . fallback ) s = [ options . fallback ( ) ] ; return ( ) => s ; } function getSymbol ( ) { const SymbolCopy = Symbol as any ; return SymbolCopy . observable || "@@observable" ; } export type ObservableObserver < T > = ( ( v : T ) => void ) | { next : ( v : T ) => void ; error ? : ( v : any ) => void ; complete ? : ( v : boolean ) => void ; } ; export function observable < T > ( input ) { const $$observable = getSymbol ( ) ; return { subscribe ( observer ) { if ( ! ( observer instanceof Object ) || observer == null ) { throw new TypeError ( "Expected the observer to be an object." ) ; } const handler = "next" in observer ? observer . next : observer ; let complete = false ; createComputed ( ( ) => { if ( complete ) return ; const v = input ( ) ; handler ( v ) ; } ) ; return { unsubscribe ( ) { complete = true ; } } ; } , [ $$observable ] ( ) { return this ; } } ; } export function from < T > ( producer ) { const [ s , set ] = createSignal < T | undefined > ( undefined , { equals : false } ) as [ Accessor < T > , Setter < T > ] ; if ( "subscribe" in producer ) { const unsub = producer . subscribe ( v => set ( ( ) => v ) ) ; onCleanup ( ( ) => ( "unsubscribe" in unsub ? unsub . unsubscribe ( ) : unsub ( ) ) ) ; } else { const clean = producer ( set ) ; onCleanup ( clean ) ; } return s ; } export function enableExternalSource ( factory ) { }