Created
August 7, 2023 08:45
-
-
Save mizchi/be851507604c86b897eae432a62ece0c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { For, Suspense, batch, createEffect, createResource, createSignal, lazy, on, onMount } from 'solid-js' | |
const DelayedGreeting = lazy(async () => { | |
await new Promise(r => setTimeout(r, 1000)); | |
return { | |
default: ()=> <div>Lazy Component</div> | |
} | |
}); | |
async function fetchUser(id: string) { | |
await new Promise(r => setTimeout(r, 300)); | |
return `${id}-${Math.random().toString(36).slice(2)}`; | |
} | |
function WithResource() { | |
const userId = "1"; | |
const [user, {refetch}] = createResource(userId, fetchUser); | |
return ( | |
<Suspense fallback="..."> | |
<button onClick={refetch}>{user()}</button> | |
</Suspense> | |
) | |
} | |
function App() { | |
console.log('render'); | |
const [count, setCount] = createSignal(0); | |
const onClick = () => { | |
console.log("onclick"); | |
setCount(count() + 1); | |
}; | |
const doubled = () => count() * 2; | |
createEffect(on(count, () => { | |
console.log("count changed", count()); | |
}, {defer: true})); | |
const [cats, setCats] = createSignal([ | |
{name: "cat1", id: "1"}, | |
]); | |
onMount(() => { | |
console.log("onMount"); | |
batch(() => { | |
setCats([...cats(), { | |
name: "cat2", | |
id: "2" | |
}]); | |
setCats([...cats(), { | |
name: "cat3", | |
id: "3" | |
}]); | |
}); | |
}); | |
return ( | |
<> | |
<button onClick={onClick}> | |
count is {count()} | |
</button> | |
<div> | |
doubled is {doubled()} | |
</div> | |
<For each={cats()}> | |
{(cat, i) => | |
<li> | |
{i() + 1}: {cat.name} | |
</li> | |
} | |
</For> | |
<hr /> | |
lazy | |
<Suspense fallback={<div>loading...</div>}> | |
<DelayedGreeting /> | |
</Suspense> | |
<hr/> | |
resource | |
<WithResource /> | |
</> | |
) | |
} | |
export default App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const equalFn = (a, b) => a === b; | |
const $TRACK = Symbol("solid-track"); | |
const signalOptions = { | |
equals: equalFn | |
}; | |
let runEffects = runQueue; | |
const STALE = 1; | |
const PENDING = 2; | |
const UNOWNED = { | |
owned: null, | |
cleanups: null, | |
context: null, | |
owner: null | |
}; | |
var Owner = null; | |
let Transition = null; | |
let Listener = null; | |
let Updates = null; | |
let Effects = null; | |
let ExecCount = 0; | |
function createRoot(fn, detachedOwner) { | |
const listener = Listener, owner = Owner, unowned = fn.length === 0, root2 = unowned ? UNOWNED : { | |
owned: null, | |
cleanups: null, | |
context: null, | |
owner: detachedOwner === void 0 ? owner : detachedOwner | |
}, updateFn = unowned ? fn : () => fn(() => untrack(() => cleanNode(root2))); | |
Owner = root2; | |
Listener = null; | |
try { | |
return runUpdates(updateFn, true); | |
} finally { | |
Listener = listener; | |
Owner = owner; | |
} | |
} | |
function createSignal(value, options) { | |
options = options ? Object.assign({}, signalOptions, options) : signalOptions; | |
const s = { | |
value, | |
observers: null, | |
observerSlots: null, | |
comparator: options.equals || void 0 | |
}; | |
const setter = (value2) => { | |
if (typeof value2 === "function") { | |
value2 = value2(s.value); | |
} | |
return writeSignal(s, value2); | |
}; | |
return [readSignal.bind(s), setter]; | |
} | |
function createRenderEffect(fn, value, options) { | |
const c = createComputation(fn, value, false, STALE); | |
updateComputation(c); | |
} | |
function createEffect(fn, value, options) { | |
runEffects = runUserEffects; | |
const c = createComputation(fn, value, false, STALE); | |
if (!options || !options.render) | |
c.user = true; | |
Effects ? Effects.push(c) : updateComputation(c); | |
} | |
function createMemo(fn, value, options) { | |
options = options ? Object.assign({}, signalOptions, options) : signalOptions; | |
const c = createComputation(fn, value, true, 0); | |
c.observers = null; | |
c.observerSlots = null; | |
c.comparator = options.equals || void 0; | |
updateComputation(c); | |
return readSignal.bind(c); | |
} | |
function batch(fn) { | |
return runUpdates(fn, false); | |
} | |
function untrack(fn) { | |
if (Listener === null) | |
return fn(); | |
const listener = Listener; | |
Listener = null; | |
try { | |
return fn(); | |
} finally { | |
Listener = listener; | |
} | |
} | |
function on(deps, fn, options) { | |
const isArray = Array.isArray(deps); | |
let prevInput; | |
let defer = options && options.defer; | |
return (prevValue) => { | |
let input; | |
if (isArray) { | |
input = Array(deps.length); | |
for (let i = 0; i < deps.length; i++) | |
input[i] = deps[i](); | |
} else | |
input = deps(); | |
if (defer) { | |
defer = false; | |
return void 0; | |
} | |
const result = untrack(() => fn(input, prevInput, prevValue)); | |
prevInput = input; | |
return result; | |
}; | |
} | |
function onMount(fn) { | |
createEffect(() => untrack(fn)); | |
} | |
function onCleanup(fn) { | |
if (Owner === null) | |
; | |
else if (Owner.cleanups === null) | |
Owner.cleanups = [fn]; | |
else | |
Owner.cleanups.push(fn); | |
return fn; | |
} | |
function readSignal() { | |
if (this.sources && this.state) { | |
if (this.state === STALE) | |
updateComputation(this); | |
else { | |
const updates = Updates; | |
Updates = null; | |
runUpdates(() => lookUpstream(this), false); | |
Updates = updates; | |
} | |
} | |
if (Listener) { | |
const sSlot = this.observers ? this.observers.length : 0; | |
if (!Listener.sources) { | |
Listener.sources = [this]; | |
Listener.sourceSlots = [sSlot]; | |
} else { | |
Listener.sources.push(this); | |
Listener.sourceSlots.push(sSlot); | |
} | |
if (!this.observers) { | |
this.observers = [Listener]; | |
this.observerSlots = [Listener.sources.length - 1]; | |
} else { | |
this.observers.push(Listener); | |
this.observerSlots.push(Listener.sources.length - 1); | |
} | |
} | |
return this.value; | |
} | |
function writeSignal(node, value, isComp) { | |
let current = node.value; | |
if (!node.comparator || !node.comparator(current, value)) { | |
node.value = value; | |
if (node.observers && node.observers.length) { | |
runUpdates(() => { | |
for (let i = 0; i < node.observers.length; i += 1) { | |
const o = node.observers[i]; | |
const TransitionRunning = Transition && Transition.running; | |
if (TransitionRunning && Transition.disposed.has(o)) | |
; | |
if (TransitionRunning ? !o.tState : !o.state) { | |
if (o.pure) | |
Updates.push(o); | |
else | |
Effects.push(o); | |
if (o.observers) | |
markDownstream(o); | |
} | |
if (!TransitionRunning) | |
o.state = STALE; | |
} | |
if (Updates.length > 1e6) { | |
Updates = []; | |
if (false) | |
; | |
throw new Error(); | |
} | |
}, false); | |
} | |
} | |
return value; | |
} | |
function updateComputation(node) { | |
if (!node.fn) | |
return; | |
cleanNode(node); | |
const owner = Owner, listener = Listener, time = ExecCount; | |
Listener = Owner = node; | |
runComputation(node, node.value, time); | |
Listener = listener; | |
Owner = owner; | |
} | |
function runComputation(node, value, time) { | |
let nextValue; | |
try { | |
nextValue = node.fn(value); | |
} catch (err) { | |
if (node.pure) { | |
{ | |
node.state = STALE; | |
node.owned && node.owned.forEach(cleanNode); | |
node.owned = null; | |
} | |
} | |
node.updatedAt = time + 1; | |
return handleError(err); | |
} | |
if (!node.updatedAt || node.updatedAt <= time) { | |
if (node.updatedAt != null && "observers" in node) { | |
writeSignal(node, nextValue); | |
} else | |
node.value = nextValue; | |
node.updatedAt = time; | |
} | |
} | |
function createComputation(fn, init, pure, state = STALE, options) { | |
const c = { | |
fn, | |
state, | |
updatedAt: null, | |
owned: null, | |
sources: null, | |
sourceSlots: null, | |
cleanups: null, | |
value: init, | |
owner: Owner, | |
context: null, | |
pure | |
}; | |
if (Owner === null) | |
; | |
else if (Owner !== UNOWNED) { | |
{ | |
if (!Owner.owned) | |
Owner.owned = [c]; | |
else | |
Owner.owned.push(c); | |
} | |
} | |
return c; | |
} | |
function runTop(node) { | |
if (node.state === 0) | |
return; | |
if (node.state === PENDING) | |
return lookUpstream(node); | |
if (node.suspense && untrack(node.suspense.inFallback)) | |
return node.suspense.effects.push(node); | |
const ancestors = [node]; | |
while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { | |
if (node.state) | |
ancestors.push(node); | |
} | |
for (let i = ancestors.length - 1; i >= 0; i--) { | |
node = ancestors[i]; | |
if (node.state === STALE) { | |
updateComputation(node); | |
} else if (node.state === PENDING) { | |
const updates = Updates; | |
Updates = null; | |
runUpdates(() => lookUpstream(node, ancestors[0]), false); | |
Updates = updates; | |
} | |
} | |
} | |
function runUpdates(fn, init) { | |
if (Updates) | |
return fn(); | |
let wait = false; | |
if (!init) | |
Updates = []; | |
if (Effects) | |
wait = true; | |
else | |
Effects = []; | |
ExecCount++; | |
try { | |
const res = fn(); | |
completeUpdates(wait); | |
return res; | |
} catch (err) { | |
if (!wait) | |
Effects = null; | |
Updates = null; | |
handleError(err); | |
} | |
} | |
function completeUpdates(wait) { | |
if (Updates) { | |
runQueue(Updates); | |
Updates = null; | |
} | |
if (wait) | |
return; | |
const e = Effects; | |
Effects = null; | |
if (e.length) | |
runUpdates(() => runEffects(e), false); | |
} | |
function runQueue(queue) { | |
for (let i = 0; i < queue.length; i++) | |
runTop(queue[i]); | |
} | |
function runUserEffects(queue) { | |
let i, userLength = 0; | |
for (i = 0; i < queue.length; i++) { | |
const e = queue[i]; | |
if (!e.user) | |
runTop(e); | |
else | |
queue[userLength++] = e; | |
} | |
for (i = 0; i < userLength; i++) | |
runTop(queue[i]); | |
} | |
function lookUpstream(node, ignore) { | |
node.state = 0; | |
for (let i = 0; i < node.sources.length; i += 1) { | |
const source = node.sources[i]; | |
if (source.sources) { | |
const state = source.state; | |
if (state === STALE) { | |
if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) | |
runTop(source); | |
} else if (state === PENDING) | |
lookUpstream(source, ignore); | |
} | |
} | |
} | |
function markDownstream(node) { | |
for (let i = 0; i < node.observers.length; i += 1) { | |
const o = node.observers[i]; | |
if (!o.state) { | |
o.state = PENDING; | |
if (o.pure) | |
Updates.push(o); | |
else | |
Effects.push(o); | |
o.observers && markDownstream(o); | |
} | |
} | |
} | |
function cleanNode(node) { | |
let i; | |
if (node.sources) { | |
while (node.sources.length) { | |
const source = node.sources.pop(), index2 = node.sourceSlots.pop(), obs = source.observers; | |
if (obs && obs.length) { | |
const n = obs.pop(), s = source.observerSlots.pop(); | |
if (index2 < obs.length) { | |
n.sourceSlots[s] = index2; | |
obs[index2] = n; | |
source.observerSlots[index2] = s; | |
} | |
} | |
} | |
} | |
if (node.owned) { | |
for (i = node.owned.length - 1; i >= 0; i--) | |
cleanNode(node.owned[i]); | |
node.owned = null; | |
} | |
if (node.cleanups) { | |
for (i = node.cleanups.length - 1; i >= 0; i--) | |
node.cleanups[i](); | |
node.cleanups = null; | |
} | |
node.state = 0; | |
node.context = null; | |
} | |
function castError(err) { | |
if (err instanceof Error) | |
return err; | |
return new Error(typeof err === "string" ? err : "Unknown error", { | |
cause: err | |
}); | |
} | |
function handleError(err, owner = Owner) { | |
const error = castError(err); | |
throw error; | |
} | |
const FALLBACK = Symbol("fallback"); | |
function dispose(d) { | |
for (let i = 0; i < d.length; i++) | |
d[i](); | |
} | |
function mapArray(list, mapFn, options = {}) { | |
let items = [], mapped = [], disposers = [], len = 0, indexes = mapFn.length > 1 ? [] : null; | |
onCleanup(() => dispose(disposers)); | |
return () => { | |
let newItems = list() || [], i, j; | |
newItems[$TRACK]; | |
return untrack(() => { | |
let newLen = newItems.length, newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item; | |
if (newLen === 0) { | |
if (len !== 0) { | |
dispose(disposers); | |
disposers = []; | |
items = []; | |
mapped = []; | |
len = 0; | |
indexes && (indexes = []); | |
} | |
if (options.fallback) { | |
items = [FALLBACK]; | |
mapped[0] = createRoot((disposer) => { | |
disposers[0] = disposer; | |
return options.fallback(); | |
}); | |
len = 1; | |
} | |
} else if (len === 0) { | |
mapped = new Array(newLen); | |
for (j = 0; j < newLen; j++) { | |
items[j] = newItems[j]; | |
mapped[j] = createRoot(mapper); | |
} | |
len = newLen; | |
} else { | |
temp = new Array(newLen); | |
tempdisposers = new Array(newLen); | |
indexes && (tempIndexes = new Array(newLen)); | |
for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++) | |
; | |
for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) { | |
temp[newEnd] = mapped[end]; | |
tempdisposers[newEnd] = disposers[end]; | |
indexes && (tempIndexes[newEnd] = indexes[end]); | |
} | |
newIndices = /* @__PURE__ */ new Map(); | |
newIndicesNext = new Array(newEnd + 1); | |
for (j = newEnd; j >= start; j--) { | |
item = newItems[j]; | |
i = newIndices.get(item); | |
newIndicesNext[j] = i === void 0 ? -1 : i; | |
newIndices.set(item, j); | |
} | |
for (i = start; i <= end; i++) { | |
item = items[i]; | |
j = newIndices.get(item); | |
if (j !== void 0 && j !== -1) { | |
temp[j] = mapped[i]; | |
tempdisposers[j] = disposers[i]; | |
indexes && (tempIndexes[j] = indexes[i]); | |
j = newIndicesNext[j]; | |
newIndices.set(item, j); | |
} else | |
disposers[i](); | |
} | |
for (j = start; j < newLen; j++) { | |
if (j in temp) { | |
mapped[j] = temp[j]; | |
disposers[j] = tempdisposers[j]; | |
if (indexes) { | |
indexes[j] = tempIndexes[j]; | |
indexes[j](j); | |
} | |
} else | |
mapped[j] = createRoot(mapper); | |
} | |
mapped = mapped.slice(0, len = newLen); | |
items = newItems.slice(0); | |
} | |
return mapped; | |
}); | |
function mapper(disposer) { | |
disposers[j] = disposer; | |
if (indexes) { | |
const [s, set] = createSignal(j); | |
indexes[j] = set; | |
return mapFn(newItems[j], s); | |
} | |
return mapFn(newItems[j]); | |
} | |
}; | |
} | |
function createComponent(Comp, props) { | |
return untrack(() => Comp(props || {})); | |
} | |
function For(props) { | |
const fallback = "fallback" in props && { | |
fallback: () => props.fallback | |
}; | |
return createMemo(mapArray(() => props.each, props.children, fallback || void 0)); | |
} | |
function reconcileArrays(parentNode, a, b) { | |
let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null; | |
while (aStart < aEnd || bStart < bEnd) { | |
if (a[aStart] === b[bStart]) { | |
aStart++; | |
bStart++; | |
continue; | |
} | |
while (a[aEnd - 1] === b[bEnd - 1]) { | |
aEnd--; | |
bEnd--; | |
} | |
if (aEnd === aStart) { | |
const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; | |
while (bStart < bEnd) | |
parentNode.insertBefore(b[bStart++], node); | |
} else if (bEnd === bStart) { | |
while (aStart < aEnd) { | |
if (!map || !map.has(a[aStart])) | |
a[aStart].remove(); | |
aStart++; | |
} | |
} else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { | |
const node = a[--aEnd].nextSibling; | |
parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); | |
parentNode.insertBefore(b[--bEnd], node); | |
a[aEnd] = b[bEnd]; | |
} else { | |
if (!map) { | |
map = /* @__PURE__ */ new Map(); | |
let i = bStart; | |
while (i < bEnd) | |
map.set(b[i], i++); | |
} | |
const index2 = map.get(a[aStart]); | |
if (index2 != null) { | |
if (bStart < index2 && index2 < bEnd) { | |
let i = aStart, sequence = 1, t; | |
while (++i < aEnd && i < bEnd) { | |
if ((t = map.get(a[i])) == null || t !== index2 + sequence) | |
break; | |
sequence++; | |
} | |
if (sequence > index2 - bStart) { | |
const node = a[aStart]; | |
while (bStart < index2) | |
parentNode.insertBefore(b[bStart++], node); | |
} else | |
parentNode.replaceChild(b[bStart++], a[aStart++]); | |
} else | |
aStart++; | |
} else | |
a[aStart++].remove(); | |
} | |
} | |
} | |
const $$EVENTS = "_$DX_DELEGATE"; | |
function render(code, element, init, options = {}) { | |
let disposer; | |
createRoot((dispose2) => { | |
disposer = dispose2; | |
element === document ? code() : insert(element, code(), element.firstChild ? null : void 0, init); | |
}, options.owner); | |
return () => { | |
disposer(); | |
element.textContent = ""; | |
}; | |
} | |
function template(html, isCE, isSVG) { | |
let node; | |
const create = () => { | |
const t = document.createElement("template"); | |
t.innerHTML = html; | |
return isSVG ? t.content.firstChild.firstChild : t.content.firstChild; | |
}; | |
const fn = isCE ? () => untrack(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true); | |
fn.cloneNode = fn; | |
return fn; | |
} | |
function delegateEvents(eventNames, document2 = window.document) { | |
const e = document2[$$EVENTS] || (document2[$$EVENTS] = /* @__PURE__ */ new Set()); | |
for (let i = 0, l = eventNames.length; i < l; i++) { | |
const name = eventNames[i]; | |
if (!e.has(name)) { | |
e.add(name); | |
document2.addEventListener(name, eventHandler); | |
} | |
} | |
} | |
function insert(parent, accessor, marker, initial) { | |
if (marker !== void 0 && !initial) | |
initial = []; | |
if (typeof accessor !== "function") | |
return insertExpression(parent, accessor, initial, marker); | |
createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial); | |
} | |
function eventHandler(e) { | |
const key = `$$${e.type}`; | |
let node = e.composedPath && e.composedPath()[0] || e.target; | |
if (e.target !== node) { | |
Object.defineProperty(e, "target", { | |
configurable: true, | |
value: node | |
}); | |
} | |
Object.defineProperty(e, "currentTarget", { | |
configurable: true, | |
get() { | |
return node || document; | |
} | |
}); | |
while (node) { | |
const handler = node[key]; | |
if (handler && !node.disabled) { | |
const data = node[`${key}Data`]; | |
data !== void 0 ? handler.call(node, data, e) : handler.call(node, e); | |
if (e.cancelBubble) | |
return; | |
} | |
node = node._$host || node.parentNode || node.host; | |
} | |
} | |
function insertExpression(parent, value, current, marker, unwrapArray) { | |
while (typeof current === "function") | |
current = current(); | |
if (value === current) | |
return current; | |
const t = typeof value, multi = marker !== void 0; | |
parent = multi && current[0] && current[0].parentNode || parent; | |
if (t === "string" || t === "number") { | |
if (t === "number") | |
value = value.toString(); | |
if (multi) { | |
let node = current[0]; | |
if (node && node.nodeType === 3) { | |
node.data = value; | |
} else | |
node = document.createTextNode(value); | |
current = cleanChildren(parent, current, marker, node); | |
} else { | |
if (current !== "" && typeof current === "string") { | |
current = parent.firstChild.data = value; | |
} else | |
current = parent.textContent = value; | |
} | |
} else if (value == null || t === "boolean") { | |
current = cleanChildren(parent, current, marker); | |
} else if (t === "function") { | |
createRenderEffect(() => { | |
let v = value(); | |
while (typeof v === "function") | |
v = v(); | |
current = insertExpression(parent, v, current, marker); | |
}); | |
return () => current; | |
} else if (Array.isArray(value)) { | |
const array = []; | |
const currentArray = current && Array.isArray(current); | |
if (normalizeIncomingArray(array, value, current, unwrapArray)) { | |
createRenderEffect(() => current = insertExpression(parent, array, current, marker, true)); | |
return () => current; | |
} | |
if (array.length === 0) { | |
current = cleanChildren(parent, current, marker); | |
if (multi) | |
return current; | |
} else if (currentArray) { | |
if (current.length === 0) { | |
appendNodes(parent, array, marker); | |
} else | |
reconcileArrays(parent, current, array); | |
} else { | |
current && cleanChildren(parent); | |
appendNodes(parent, array); | |
} | |
current = array; | |
} else if (value.nodeType) { | |
if (Array.isArray(current)) { | |
if (multi) | |
return current = cleanChildren(parent, current, marker, value); | |
cleanChildren(parent, current, null, value); | |
} else if (current == null || current === "" || !parent.firstChild) { | |
parent.appendChild(value); | |
} else | |
parent.replaceChild(value, parent.firstChild); | |
current = value; | |
} else | |
console.warn(`Unrecognized value. Skipped inserting`, value); | |
return current; | |
} | |
function normalizeIncomingArray(normalized, array, current, unwrap) { | |
let dynamic = false; | |
for (let i = 0, len = array.length; i < len; i++) { | |
let item = array[i], prev = current && current[i], t; | |
if (item == null || item === true || item === false) | |
; | |
else if ((t = typeof item) === "object" && item.nodeType) { | |
normalized.push(item); | |
} else if (Array.isArray(item)) { | |
dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; | |
} else if (t === "function") { | |
if (unwrap) { | |
while (typeof item === "function") | |
item = item(); | |
dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; | |
} else { | |
normalized.push(item); | |
dynamic = true; | |
} | |
} else { | |
const value = String(item); | |
if (prev && prev.nodeType === 3 && prev.data === value) | |
normalized.push(prev); | |
else | |
normalized.push(document.createTextNode(value)); | |
} | |
} | |
return dynamic; | |
} | |
function appendNodes(parent, array, marker = null) { | |
for (let i = 0, len = array.length; i < len; i++) | |
parent.insertBefore(array[i], marker); | |
} | |
function cleanChildren(parent, current, marker, replacement) { | |
if (marker === void 0) | |
return parent.textContent = ""; | |
const node = replacement || document.createTextNode(""); | |
if (current.length) { | |
let inserted = false; | |
for (let i = current.length - 1; i >= 0; i--) { | |
const el = current[i]; | |
if (node !== el) { | |
const isParent = el.parentNode === parent; | |
if (!inserted && !i) | |
isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker); | |
else | |
isParent && el.remove(); | |
} else | |
inserted = true; | |
} | |
} else | |
parent.insertBefore(node, marker); | |
return [node]; | |
} | |
const index = ""; | |
const App$1 = ""; | |
const _tmpl$ = /* @__PURE__ */ template(`<button>count is `), _tmpl$2 = /* @__PURE__ */ template(`<div>doubled is `), _tmpl$3 = /* @__PURE__ */ template(`<li>: `); | |
function App() { | |
console.log("render"); | |
const [count, setCount] = createSignal(0); | |
const onClick = () => { | |
console.log("onclick"); | |
setCount(count() + 1); | |
}; | |
const doubled = () => count() * 2; | |
createEffect(on(count, () => { | |
console.log("count changed", count()); | |
}, { | |
defer: true | |
})); | |
const [cats, setCats] = createSignal([{ | |
name: "cat1", | |
id: "1" | |
}]); | |
onMount(() => { | |
console.log("onMount"); | |
batch(() => { | |
setCats([...cats(), { | |
name: "cat2", | |
id: "2" | |
}]); | |
setCats([...cats(), { | |
name: "cat3", | |
id: "3" | |
}]); | |
}); | |
}); | |
return [(() => { | |
const _el$ = _tmpl$(); | |
_el$.firstChild; | |
_el$.$$click = onClick; | |
insert(_el$, count, null); | |
return _el$; | |
})(), (() => { | |
const _el$3 = _tmpl$2(); | |
_el$3.firstChild; | |
insert(_el$3, doubled, null); | |
return _el$3; | |
})(), createComponent(For, { | |
get each() { | |
return cats(); | |
}, | |
children: (cat, i) => (() => { | |
const _el$5 = _tmpl$3(), _el$6 = _el$5.firstChild; | |
insert(_el$5, () => i() + 1, _el$6); | |
insert(_el$5, () => cat.name, null); | |
return _el$5; | |
})() | |
})]; | |
} | |
delegateEvents(["click"]); | |
const root = document.getElementById("root"); | |
render(() => createComponent(App, {}), root); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment