mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-29 01:35:48 +00:00
fix(app): guard reentrant Solid cleanup (#39261)
Co-authored-by: Jack <jack@anoma.ly>
This commit is contained in:
parent
7c898249a2
commit
be93cec9ba
2 changed files with 210 additions and 10 deletions
64
packages/app/test-browser/solid-router-cleanup.test.ts
Normal file
64
packages/app/test-browser/solid-router-cleanup.test.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { MetaProvider, Title } from "@solidjs/meta"
|
||||
import { MemoryRouter, Route, createMemoryHistory, useParams } from "@solidjs/router"
|
||||
import { createMemo } from "solid-js"
|
||||
import { createComponent, render } from "solid-js/web"
|
||||
|
||||
test("route cleanup cannot invalidate an owner list being disposed", async () => {
|
||||
const host = document.createElement("div")
|
||||
document.body.append(host)
|
||||
const history = createMemoryHistory()
|
||||
|
||||
const RepoPage = () => {
|
||||
const params = useParams<{ id?: string }>()
|
||||
const title = createMemo(() => params.id ?? "")
|
||||
const button = document.createElement("button")
|
||||
button.textContent = "Back"
|
||||
button.addEventListener("click", () => history.set({ value: "/", scroll: false, replace: false }))
|
||||
return [
|
||||
createComponent(Title, {
|
||||
get children() {
|
||||
return title()
|
||||
},
|
||||
}),
|
||||
button,
|
||||
]
|
||||
}
|
||||
|
||||
const HomePage = () => {
|
||||
const button = document.createElement("button")
|
||||
button.textContent = "Go"
|
||||
button.addEventListener("click", () => history.set({ value: "/project", scroll: false, replace: false }))
|
||||
return button
|
||||
}
|
||||
|
||||
const App = () =>
|
||||
createComponent(MetaProvider, {
|
||||
get children() {
|
||||
return createComponent(MemoryRouter, {
|
||||
history,
|
||||
get children() {
|
||||
return [
|
||||
createComponent(Route, { path: "/", component: HomePage }),
|
||||
createComponent(Route, { path: "/:id", component: RepoPage }),
|
||||
]
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const dispose = render(() => createComponent(App, {}), host)
|
||||
const go = host.querySelector("button")
|
||||
expect(go?.textContent).toBe("Go")
|
||||
go?.click()
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
|
||||
const back = host.querySelector("button")
|
||||
expect(back?.textContent).toBe("Back")
|
||||
back?.click()
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
|
||||
expect(host.querySelector("button")?.textContent).toBe("Go")
|
||||
dispose()
|
||||
host.remove()
|
||||
})
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
diff --git a/Users/brendonovich/github.com/anomalyco/opencode/node_modules/solid-js/.bun-tag-6fcb6b48d6947d2c b/.bun-tag-6fcb6b48d6947d2c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/Users/brendonovich/github.com/anomalyco/opencode/node_modules/solid-js/.bun-tag-b272f631c12927b0 b/.bun-tag-b272f631c12927b0
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/dist/dev.cjs b/dist/dev.cjs
|
||||
index 7104749486e4361e8c4ee7836a8046582cec7aa1..0501eb1ec5d13b81ecb13a5ac1a82db42502b976 100644
|
||||
index 7104749..dc3eac9 100644
|
||||
--- a/dist/dev.cjs
|
||||
+++ b/dist/dev.cjs
|
||||
@@ -764,6 +764,8 @@ function runComputation(node, value, time) {
|
||||
|
|
@ -17,8 +11,33 @@ index 7104749486e4361e8c4ee7836a8046582cec7aa1..0501eb1ec5d13b81ecb13a5ac1a82db4
|
|||
Transition.sources.add(node);
|
||||
node.tValue = nextValue;
|
||||
} else node.value = nextValue;
|
||||
@@ -987,18 +989,21 @@ function cleanNode(node) {
|
||||
}
|
||||
}
|
||||
if (node.tOwned) {
|
||||
- for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]);
|
||||
+ const tOwned = node.tOwned;
|
||||
delete node.tOwned;
|
||||
+ for (i = tOwned.length - 1; i >= 0; i--) cleanNode(tOwned[i]);
|
||||
}
|
||||
if (Transition && Transition.running && node.pure) {
|
||||
reset(node, true);
|
||||
} else if (node.owned) {
|
||||
- for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (i = owned.length - 1; i >= 0; i--) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
|
||||
}
|
||||
if (Transition && Transition.running) node.tState = 0;else node.state = 0;
|
||||
delete node.sourceMap;
|
||||
diff --git a/dist/dev.js b/dist/dev.js
|
||||
index ea5e4bc2fd4f0b3922a73d9134439529dc81339f..4b3ec07e624d20fdd23d6941a4fdde6d3a78cca3 100644
|
||||
index ea5e4bc..a2e2d59 100644
|
||||
--- a/dist/dev.js
|
||||
+++ b/dist/dev.js
|
||||
@@ -762,6 +762,8 @@ function runComputation(node, value, time) {
|
||||
|
|
@ -30,8 +49,75 @@ index ea5e4bc2fd4f0b3922a73d9134439529dc81339f..4b3ec07e624d20fdd23d6941a4fdde6d
|
|||
Transition.sources.add(node);
|
||||
node.tValue = nextValue;
|
||||
} else node.value = nextValue;
|
||||
@@ -985,18 +987,21 @@ function cleanNode(node) {
|
||||
}
|
||||
}
|
||||
if (node.tOwned) {
|
||||
- for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]);
|
||||
+ const tOwned = node.tOwned;
|
||||
delete node.tOwned;
|
||||
+ for (i = tOwned.length - 1; i >= 0; i--) cleanNode(tOwned[i]);
|
||||
}
|
||||
if (Transition && Transition.running && node.pure) {
|
||||
reset(node, true);
|
||||
} else if (node.owned) {
|
||||
- for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (i = owned.length - 1; i >= 0; i--) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
|
||||
}
|
||||
if (Transition && Transition.running) node.tState = 0;else node.state = 0;
|
||||
delete node.sourceMap;
|
||||
diff --git a/dist/server.cjs b/dist/server.cjs
|
||||
index e715309..188ba81 100644
|
||||
--- a/dist/server.cjs
|
||||
+++ b/dist/server.cjs
|
||||
@@ -127,12 +127,14 @@ function onCleanup(fn) {
|
||||
}
|
||||
function cleanNode(node) {
|
||||
if (node.owned) {
|
||||
- for (let i = 0; i < node.owned.length; i++) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (let i = 0; i < owned.length; i++) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (let i = 0; i < node.cleanups.length; i++) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (let i = 0; i < cleanups.length; i++) cleanups[i]();
|
||||
}
|
||||
}
|
||||
function catchError(fn, handler) {
|
||||
diff --git a/dist/server.js b/dist/server.js
|
||||
index d5f8803..320d9af 100644
|
||||
--- a/dist/server.js
|
||||
+++ b/dist/server.js
|
||||
@@ -125,12 +125,14 @@ function onCleanup(fn) {
|
||||
}
|
||||
function cleanNode(node) {
|
||||
if (node.owned) {
|
||||
- for (let i = 0; i < node.owned.length; i++) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (let i = 0; i < owned.length; i++) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (let i = 0; i < node.cleanups.length; i++) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (let i = 0; i < cleanups.length; i++) cleanups[i]();
|
||||
}
|
||||
}
|
||||
function catchError(fn, handler) {
|
||||
diff --git a/dist/solid.cjs b/dist/solid.cjs
|
||||
index 7c133a2b254678a84fd61d719fbeffad766e1331..2f68c99f2698210cc0bac62f074cc8cd3beb2881 100644
|
||||
index 7c133a2..5ef1501 100644
|
||||
--- a/dist/solid.cjs
|
||||
+++ b/dist/solid.cjs
|
||||
@@ -717,6 +717,8 @@ function runComputation(node, value, time) {
|
||||
|
|
@ -43,8 +129,33 @@ index 7c133a2b254678a84fd61d719fbeffad766e1331..2f68c99f2698210cc0bac62f074cc8cd
|
|||
Transition.sources.add(node);
|
||||
node.tValue = nextValue;
|
||||
} else node.value = nextValue;
|
||||
@@ -938,18 +940,21 @@ function cleanNode(node) {
|
||||
}
|
||||
}
|
||||
if (node.tOwned) {
|
||||
- for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]);
|
||||
+ const tOwned = node.tOwned;
|
||||
delete node.tOwned;
|
||||
+ for (i = tOwned.length - 1; i >= 0; i--) cleanNode(tOwned[i]);
|
||||
}
|
||||
if (Transition && Transition.running && node.pure) {
|
||||
reset(node, true);
|
||||
} else if (node.owned) {
|
||||
- for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (i = owned.length - 1; i >= 0; i--) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
|
||||
}
|
||||
if (Transition && Transition.running) node.tState = 0;else node.state = 0;
|
||||
}
|
||||
diff --git a/dist/solid.js b/dist/solid.js
|
||||
index 656fd26e7e5c794aa22df19c2377ff5c0591fc29..f08e9f5a7157c3506e5b6922fe2ef991335a80be 100644
|
||||
index 656fd26..6e0038c 100644
|
||||
--- a/dist/solid.js
|
||||
+++ b/dist/solid.js
|
||||
@@ -715,6 +715,8 @@ function runComputation(node, value, time) {
|
||||
|
|
@ -56,3 +167,28 @@ index 656fd26e7e5c794aa22df19c2377ff5c0591fc29..f08e9f5a7157c3506e5b6922fe2ef991
|
|||
Transition.sources.add(node);
|
||||
node.tValue = nextValue;
|
||||
} else node.value = nextValue;
|
||||
@@ -936,18 +938,21 @@ function cleanNode(node) {
|
||||
}
|
||||
}
|
||||
if (node.tOwned) {
|
||||
- for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]);
|
||||
+ const tOwned = node.tOwned;
|
||||
delete node.tOwned;
|
||||
+ for (i = tOwned.length - 1; i >= 0; i--) cleanNode(tOwned[i]);
|
||||
}
|
||||
if (Transition && Transition.running && node.pure) {
|
||||
reset(node, true);
|
||||
} else if (node.owned) {
|
||||
- for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]);
|
||||
+ const owned = node.owned;
|
||||
node.owned = null;
|
||||
+ for (i = owned.length - 1; i >= 0; i--) cleanNode(owned[i]);
|
||||
}
|
||||
if (node.cleanups) {
|
||||
- for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i]();
|
||||
+ const cleanups = node.cleanups;
|
||||
node.cleanups = null;
|
||||
+ for (i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
|
||||
}
|
||||
if (Transition && Transition.running) node.tState = 0;else node.state = 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue