add router-hook
This commit is contained in:
46
sigpro2.js
46
sigpro2.js
@@ -11,6 +11,7 @@ let isFlushing = false
|
|||||||
const effectQueue = new Set()
|
const effectQueue = new Set()
|
||||||
const MOUNTED_NODES = new WeakMap()
|
const MOUNTED_NODES = new WeakMap()
|
||||||
|
|
||||||
|
// effect cleanup
|
||||||
const dispose = eff => {
|
const dispose = eff => {
|
||||||
if (!eff || eff._disposed) return
|
if (!eff || eff._disposed) return
|
||||||
eff._disposed = true
|
eff._disposed = true
|
||||||
@@ -32,6 +33,7 @@ const dispose = eff => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helpers
|
||||||
const onMount = fn => {
|
const onMount = fn => {
|
||||||
if (activeOwner) (activeOwner._mounts ||= []).push(fn)
|
if (activeOwner) (activeOwner._mounts ||= []).push(fn)
|
||||||
}
|
}
|
||||||
@@ -40,6 +42,22 @@ const onUnmount = fn => {
|
|||||||
if (activeOwner) (activeOwner._cleanups ||= new Set()).add(fn)
|
if (activeOwner) (activeOwner._cleanups ||= new Set()).add(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const set = (signal, path, value) => {
|
||||||
|
if (value === undefined) return signal(isFunc(path) ? path(signal()) : path)
|
||||||
|
const keys = path.split('.'), root = { ...signal() }
|
||||||
|
let acc = root, k
|
||||||
|
for (k of keys.slice(0, -1)) acc = acc[k] = { ...(acc[k] || {}) }
|
||||||
|
acc[keys.at(-1)] = value
|
||||||
|
signal(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
const untrack = fn => {
|
||||||
|
const p = activeEffect
|
||||||
|
activeEffect = null
|
||||||
|
try { return fn() } finally { activeEffect = p }
|
||||||
|
}
|
||||||
|
|
||||||
|
// effect creation
|
||||||
const createEffect = (fn, isComputed = false) => {
|
const createEffect = (fn, isComputed = false) => {
|
||||||
const effect = () => {
|
const effect = () => {
|
||||||
if (effect._disposed) return
|
if (effect._disposed) return
|
||||||
@@ -99,12 +117,7 @@ const trackUpdate = (subs, trigger = false) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const untrack = fn => {
|
// signal creation
|
||||||
const p = activeEffect
|
|
||||||
activeEffect = null
|
|
||||||
try { return fn() } finally { activeEffect = p }
|
|
||||||
}
|
|
||||||
|
|
||||||
const $ = (val, key = null) => {
|
const $ = (val, key = null) => {
|
||||||
const subs = new Set()
|
const subs = new Set()
|
||||||
if (isFunc(val)) {
|
if (isFunc(val)) {
|
||||||
@@ -157,6 +170,7 @@ const $ = (val, key = null) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Watch
|
||||||
const Watch = (sources, cb) => {
|
const Watch = (sources, cb) => {
|
||||||
if (cb === undefined) {
|
if (cb === undefined) {
|
||||||
const effect = createEffect(sources)
|
const effect = createEffect(sources)
|
||||||
@@ -195,6 +209,7 @@ const validateAttr = (key, val) => {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Tag
|
||||||
const Tag = (tag, props = {}, children = []) => {
|
const Tag = (tag, props = {}, children = []) => {
|
||||||
if (props instanceof Node || isArr(props) || !isObj(props)) {
|
if (props instanceof Node || isArr(props) || !isObj(props)) {
|
||||||
children = props
|
children = props
|
||||||
@@ -307,6 +322,7 @@ const Tag = (tag, props = {}, children = []) => {
|
|||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Render
|
||||||
const Render = renderFn => {
|
const Render = renderFn => {
|
||||||
const cleanups = new Set()
|
const cleanups = new Set()
|
||||||
const mounts = []
|
const mounts = []
|
||||||
@@ -349,6 +365,7 @@ const Render = renderFn => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create If
|
||||||
const If = (cond, ifYes, ifNot = null, trans = null) => {
|
const If = (cond, ifYes, ifNot = null, trans = null) => {
|
||||||
const anchor = doc.createTextNode("")
|
const anchor = doc.createTextNode("")
|
||||||
const root = Tag("div", { style: "display:contents" }, [anchor])
|
const root = Tag("div", { style: "display:contents" }, [anchor])
|
||||||
@@ -390,6 +407,7 @@ const If = (cond, ifYes, ifNot = null, trans = null) => {
|
|||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create For
|
||||||
const For = (src, itemFn, keyFn) => {
|
const For = (src, itemFn, keyFn) => {
|
||||||
const anchor = doc.createTextNode("")
|
const anchor = doc.createTextNode("")
|
||||||
const root = Tag("div", { style: "display:contents" }, [anchor])
|
const root = Tag("div", { style: "display:contents" }, [anchor])
|
||||||
@@ -420,13 +438,14 @@ const For = (src, itemFn, keyFn) => {
|
|||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create Router
|
||||||
const Router = routes => {
|
const Router = routes => {
|
||||||
const getHash = () => window.location.hash.slice(1) || "/"
|
const getHash = () => window.location.hash.slice(1) || "/"
|
||||||
const path = $(getHash())
|
const path = $(getHash())
|
||||||
const handler = () => path(getHash())
|
const handler = () => path(getHash())
|
||||||
window.addEventListener("hashchange", handler)
|
window.addEventListener("hashchange", handler)
|
||||||
onUnmount(() => window.removeEventListener("hashchange", handler))
|
onUnmount(() => window.removeEventListener("hashchange", handler))
|
||||||
const outlet = Tag("div", { class: "router-outlet" })
|
const hook = Tag("div", { class: "router-hook" })
|
||||||
let currentView = null
|
let currentView = null
|
||||||
Watch([path], () => {
|
Watch([path], () => {
|
||||||
const cur = path()
|
const cur = path()
|
||||||
@@ -443,10 +462,10 @@ const Router = routes => {
|
|||||||
})
|
})
|
||||||
Router.params(params)
|
Router.params(params)
|
||||||
currentView = Render(() => isFunc(route.component) ? route.component(params) : route.component)
|
currentView = Render(() => isFunc(route.component) ? route.component(params) : route.component)
|
||||||
outlet.replaceChildren(currentView.container)
|
hook.replaceChildren(currentView.container)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return outlet
|
return hook
|
||||||
}
|
}
|
||||||
Router.params = $({})
|
Router.params = $({})
|
||||||
Router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/")
|
Router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/")
|
||||||
@@ -463,15 +482,6 @@ const Mount = (comp, target) => {
|
|||||||
return inst
|
return inst
|
||||||
}
|
}
|
||||||
|
|
||||||
const set = (signal, path, value) => {
|
|
||||||
if (value === undefined) return signal(isFunc(path) ? path(signal()) : path)
|
|
||||||
const keys = path.split('.'), root = { ...signal() }
|
|
||||||
let acc = root, k
|
|
||||||
for (k of keys.slice(0, -1)) acc = acc[k] = { ...(acc[k] || {}) }
|
|
||||||
acc[keys.at(-1)] = value
|
|
||||||
signal(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SigPro = Object.freeze({ $, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount, set })
|
const SigPro = Object.freeze({ $, Watch, Tag, Render, If, For, Router, Mount, onMount, onUnmount, set })
|
||||||
|
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
|
|||||||
Reference in New Issue
Block a user