Coder Social home page Coder Social logo

epicweb-dev / epicshop Goto Github PK

View Code? Open in Web Editor NEW
187.0 6.0 31.0 10.59 MB

The workshop app for all workshops on EpicWeb.dev

Home Page: https://www.epicweb.dev

License: Other

JavaScript 3.89% TypeScript 92.95% CSS 3.06% MDX 0.05% Shell 0.05%

epicshop's Introduction

epicshop's People

Contributors

ayush-v avatar isaacplmann avatar jameshenry avatar jetmech avatar kentcdodds avatar kettanaito avatar michaeldeboey avatar onemen avatar realjokele avatar ruisaraiva19 avatar shahzeb1 avatar simonswiss avatar threepointone avatar vojtaholik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

epicshop's Issues

Support no React Hydration

I've adjusted the Web App Fundamentals workshop a bit to have an exercise on scripting, which means the exercises before it don't have any scripts in the client. This means that the current implementation of the iframe sync component won't work for those exercises which means the address bar won't stay up to date as you navigate around. We need to figure out a solution for these. I'm thinking we could just have the KCDShopIFrameSync component render an inline <script> that uses the onbeforeunload event to let the parent know when the route is going to change.

Add a link to open the README.mdx file in the editor

I often find myself wishing I had an easy way to open the instructions I'm reading to fix a typo. Especially early on in the workshops, people will also quickly identify typos and things that need improvement and wish to make PRs and improvements. The problem with that is they're often working off their main branch and making PRs using the main branch can be problematic (I can't edit their PRs for them).

So we've got two needs here:

  1. An easy way for me to launch the README.mdx in the editor
  2. An easy way for workshoppers to open the README.mdx in the GitHub online editor

I'm not sure of the best way to do this. Maybe a bit at the bottom of the README that says: "Edit instructions: <locally-icon> <online-icon>"

Or maybe it's just a link and by default it opens online, but if you're holding down "alt" it switches to the local icon and opens it locally. I think I like that best.

Ignore .test.ts files in simple apps

For simple use cases like the React Advanced Patterns workshop, we need to avoid the test files being used in the diff and the list of changed files.

image

image

Write docs

There are a few things about this project that I'm already starting to forget. Having docs for the components you can use in the markdown would be very helpful. Also documentation on required project structure would be good too.

Playground is not usable

Problems

  • Sometimes clicking on Set to Playground copy the playground files to its place but the message Set to Playground keep flashing, sometime F5 works, other times restart the browser works.
    If even restarting kcdshop did not work to solve this issue, i had to delete Brave User Data folder to solve this issue
    C:\Users\_____\AppData\Local\BraveSoftware\Brave-Browser\User Data, solve this issue

  • On first run before playground created inline links from README (InlineFile) show the word children. (i will include a for this in PR #30)

  • After playground started few times for different steps, this message appears more than one time: The port for this app is unavailable. It could be that you're running it elsewhere http:// localhost: 4000`, but i did not start any of the app, and port 4000 was not running on my Windows 11.

  • I also run into this issue one time:

[dev:server] [Error: EEXIST: file already exists, mkdir 'C:\Users\______\AppData\Local\Temp\kcdshop\diff\example\exercises.01.nested-routing.01.solution.outlet-1\app'] {
[dev:server]   errno: -4075,
[dev:server]   code: 'EEXIST',
[dev:server]   syscall: 'mkdir',
[dev:server]   path: 'C:\\Users\\______\\AppData\\Local\\Temp\\kcdshop\\diff\\example\\exercises.01.nested-routing.01.solution.outlet-1\\app'
[dev:server] }
  • Set to Playground is very slow, and it get slower on each time. I've copied web-app-fundamentals exercises into kcdshop/packages/example/exercises
    and start kcdshop (npm run dev), the time to start the playgroung keep going up and up. I see the same result with the simple examples from kcdshop.

this is the output

[dev:server] ๐Ÿจ  Let's get learning!
[dev:server] Local:            http://localhost:5639
[dev:server] On Your Network:  http://10.100.102.21:5639
[dev:server] Press Ctrl+C to stop
[dev:remix ] Watching Remix app in development mode...
[dev:remix ] mdx-bundler is possibly an ESM only package and should be bundled with "serverDependenciesToBundle" in remix.config.js.
[dev:remix ] ๐Ÿ’ฟ Built in 2.9s
[dev:server] POST /launch-editor?_data=routes%2Flaunch-editor 404 - - 48.654 ms
[dev:server] GET /build/routes/launch-editor-IGW2V433.js 404 - - 5741.518 ms
[dev:server] GET /01/01/problem 200 - - 793.992 ms
[dev:server] GET /01/01/problem - - - - ms
[dev:server] (node:14512) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] (Use `node --trace-warnings ...` to show where the warning was created)
[dev:server] (node:14512) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] (node:14512) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 uncaughtException listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] GET /01/01/problem - - - - ms
[dev:server] (node:14512) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 unhandledRejection listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] GET /01/01/problem 200 - - 3726.794 ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/01/problem 200 - - 796.300 ms
[dev:server] GET /01/01/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 778.682 ms
[dev:server] (node:14512) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 before:purge listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
[dev:server] GET /01/01/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 726.276 ms
[dev:server] GET /01/02/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber 200 - - 1633.168 ms
[dev:server] GET /01/02/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type - - - - ms
[dev:server] GET /01/02/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 1592.525 ms
[dev:server] GET /01/02/problem - - - - ms
[dev:server] GET /01/02/problem - - - - ms
[dev:server] GET /01/02/problem 200 - - 7097.769 ms
[dev:server] GET /01/02/problem - - - - ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/02/problem 200 - - 4134.433 ms
[dev:server] GET /01/03/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber 200 - - 1715.877 ms
[dev:server] GET /01/03/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type - - - - ms
[dev:server] GET /01/02/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 684.289 ms
[dev:server] GET /01/03/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 1675.548 ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/03/problem 200 - - 5577.593 ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] GET /01/03/problem - - - - ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground 200 - - 30571.230 ms
[dev:server] GET /01/03/problem?_data=root 200 - - 48.305 ms
[dev:server] GET /01/03/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F_layout - - - - ms
[dev:server] GET /01/03/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type - - - - ms
[dev:server] GET /01/03/problem 200 - - 8487.903 ms
[dev:server] GET /01/04/problem - - - - ms
[dev:server] GET /01/04/problem - - - - ms
[dev:server] GET /01/04/problem - - - - ms
[dev:server] GET /01/04/problem 200 - - 3441.557 ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/04/problem - - - - ms
[dev:server] GET /01/04/problem - - - - ms
[dev:server] GET /01/04/problem 200 - - 5626.322 ms
[dev:server] GET /01/04/solution?_data=root 200 - - 46.744 ms
[dev:server] GET /01/04/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type - - - - ms
[dev:server] GET /01/04/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber 200 - - 5107.516 ms
[dev:server] GET /01/04/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F_layout 200 - - 5159.773 ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/04/solution - - - - ms
[dev:server] GET /01/04/solution - - - - ms
[dev:server] GET /01/04/solution - - - - ms
[dev:server] GET /01/04/solution - - - - ms
[dev:server] GET /01/04/solution - - - - ms
[dev:server] GET /01/04/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 9345.299 ms
[dev:server] GET /01/04/solution 200 - - 6943.838 ms
[dev:server] GET /01/05/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber 200 - - 1416.017 ms
[dev:server] GET /01/05/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 1382.561 ms
[dev:server] GET /01/05/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type - - - - ms
[dev:server] GET /01/05/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 717.966 ms
[dev:server] GET /01/05/problem - - - - ms
[dev:server] GET /01/05/problem - - - - ms
[dev:server] GET /01/05/problem 200 - - 9408.127 ms
[dev:server] GET /01/05/problem - - - - ms
[dev:server] POST /set-playground?_data=routes%2Fset-playground - - - - ms
[dev:server] GET /01/05/problem 200 - - 6469.363 ms

Miscellaneous

  • consider prepare playground for exercise 01 step 01 as part of the workshop setup.
  • consider change Files button to Open Files or Open Files in Playground.
  • consider adding ๐Ÿ’ช ๐Ÿ ๐Ÿ›to OPEN in APP buttons in diff tab
  • when ?preview= is not on playground tab and the playground is not set to the problem, there is no direct view on where the playground is.
  • file menu was not visible before on solution page, now it appears is it by design?
  • missing playground icon on selected list in playground tab
  • extra scrollbar on open side bar - here
  • files show in diff tab even if the only change is empty line at the end of the file
    .gitignore 1 .gitignore 2
  • playground deos not work when there is no package.json in the exercise all example/exercises/03.react-components steps
  • package-lock.json is not up-to-date running npm install show changes.
  • Is this something you need to fix? mdx-bundler is possibly an ESM only package and should be bundled with "serverDependenciesToBundle" in remix.config.js
  • maybe this MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit related to some of the issues I had?

Handle copying node_modules to playground better

I'm pretty sure it would be best if we have a special branch of the code that just deletes the old node_modules directory completely and copies the new one over.

I'm not even sure that this would work, but issues like epicweb-dev/full-stack-foundations#2 are really frustrating. It pretty much requires that we make sure everything gets hoisted which can be tricky sometimes.

app start without styles

I've seen it several times, app start without styles, only if i switch to problem or diff and go back to the app it looks ok

without_styles
with_styles

Fix URL bar

It barely/rarely works. Very buggy. Would be great to get this thing working properly.

Thoughts after the web-app-fundamentals premiere

General

More information about the workshop app is needed, you can add a another read-me
page with more information about the workshop app, including screenshot,
explanation about navigation, tab panels, work flow etc...

Expand the explanation regarding the exercises, the folders structure, the
division of each exercise into lessons. Explain that each lesson contain a
problem folder which is the working directory for the student to work in and a
teacher's solution folder solution folder.

Perhaps you should add a note at the bottom of each lesson about closing the
files from previous lessons before starting to work on the current lesson (it
can be confusing especially when working on the same files in consecutive
lessons)

Diff

At the beginning of each lesson the DIFF tab show the different of each file
touched in the lesson between the problem and the solution. however as the
student work progress in the lesson the diff tab losing its starting data, and
only show the remaining changes.

I think you can add 2nd diff tab with fixed diff for that lesson, one tab can
read as lesson diff and the other current diff. you can generate the fixed
diff from a GitHub action and the save the diff file/s in the solution folder.

Another thing that i find confusing is the possibility to view backward diff
between the solution to the problem. You can get such diff when you are on
solution view http://localhost:5639/08/01/solution?preview=diff or when
student select APP1 and APP2 in reverse order. I think that this can be
confusing and serve no real purpose. I suggest to always show the diff in
forward order.

Build

The change in 807f349fb3a193ba06e3847a0aedb5592eb743a5 add build step to every
app in the setup stage. After this change the total time of a clean setup in
about 8 minutes

step time (m:s)
installing dependency 1:17
prisma & .env 0:35
playwright 0:35
build apps 5:30
total time 7:57

Is it possible to generate this files (build, public/build) using GitHub action
and include the files in the repository?

I did not noticed any improvement in the start app in each lesson.

Bugs

  • Apps start many time before the styles loaded. styles load after refresh.
    fbd3fad
    did not help

  • You mention during the workshop that the refresh button on the iFrame app
    should clear address bar. for example from /settings/profile to /. but
    this is not the normal behavior of a browser, the address bar does not reset
    after refresh. solution to this can be to

    • add home button
    • add button with the label 'RESET', that will restart/reset the app.

UI improvement

  • option to open all touched files in a lesson.

  • you already mension about adding indication which app is running, it can be
    added on the navigation side bar and on the tabs PROBLEM SOLUTION of each
    lesson.

  • option to close all apps, previous apps.

  • option to automatically start both problem and solution apps of a lesson.

  • option to automatically close previous apps when starting new lesson.

files watcher slow down set-playground

@kentcdodds

Currently there are multiple file watcher for the entire packages/example.

During the process of coping exercise files to playground, file watcher triggers multiple activities that slow down set-playground significantly.

In my testing, removing playground folder from the watcher improve set-playground time by 30-40% for the small example apps included in kcdshop. It can be more meaningful for larger apps included in the workshop.

Maybe kcdshop doesn't need to watch for changes in playground files at all?

set-playground already call getApps with forceFresh to update the cache, the only other place that need update when files change in the playground are diff tab in getForceFreshForDiff. for that case when getForceFreshForDiff called with playground as one of the apps, we can check the modified time of the playground directly and update the cache if we need to.

maybe you don't need to watch example files at all during workshop and only update cache for diff?.

Make it easy to deploy

We can't really deploy the process manager and launch editor stuff (I don't want people to be able to start/stop apps and tests on a deployed VM), but having access to the instructions and diff would be quite useful I think.

I think the workshop repos could deploy themselves. We'd just need a "production deployment" mode or something that disables the process manager. Perhaps it removes the tabs entirely and only renders the diff view.

/diff route

I use the diff view a lot as I'm working on the workshop. It's intentionally not the focus of the app because workshop attendees shouldn't have to use it very often. However, while I'm developing the workshop, it's kind of annoying that it's hidden behind a few clicks.

I'd like to have a /diff route that makes it really easy to compare the different apps. I would want it to have forward/backward arrows that work like this:

  • app1=A.problem app2=A.solution
  • Click Next
  • app1=A.solution app2=B.problem
  • Click Next
  • app1=B.problem app2=B.solution
  • Click Next
  • app1=B.solution app2=C.problem
  • Click Prev
  • app1=B.problem app2=B.solution

Sometimes (not always), there are changes between the solution of one and the problem of the next and it's important for me to see those, so I don't want it just switching between full exercise steps. It should go app-by-app.

cliped corner on the buttons is not the same

cliped_buttons

.clip-path-button {
	clip-path: polygon(0 0, 100% 0, 100% 75%, 90.5% 100%, 0 100%);
}

Hi @kentcdodds,
Its a little bit of cosmetics, but do you we need to unified the cut corner?

To make problem buttons clip in the corner in change this section navigation layout (lines 177-188)

	<Link
		to={`/${exerciseNum}/${step}`}
		className={clsx(
-			'whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium hover:underline',
-			{
-				// TODO: figure out how to make it clip in the corner
-				'bg-black text-white': isActive,
-			},
+			'clip-path-button whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium hover:underline',
+			{ 'bg-black text-white': isActive },
		)}
	>
		{step}. {title}
	</Link>

MaxListenersExceededWarning: Possible EventEmitter memory leak detected

$exerciseNumber_.$stepNumber.$type.tsx loader repeatedly call isPortAvailable

I've just added a log to isPortAvailable.

this is the output:

[dev:server] ๐Ÿจ  Let's get learning!
[dev:server] Local:            http://localhost:5639
[dev:server] On Your Network:  http://10.100.102.21:5639
[dev:server] Press Ctrl+C to stop
[dev:remix ] Watching Remix app in development mode...
[dev:decs  ]
[dev:decs  ] 18:33:34 - Starting compilation in watch mode...
[dev:decs  ]
[dev:decs  ]
[dev:decs  ] 18:33:34 - Found 0 errors. Watching for file changes.
[dev:remix ] mdx-bundler is possibly an ESM only package and should be bundled with "serverDependenciesToBundle" in remix.config.js.
[dev:remix ] ๐Ÿ’ฟ Built in 2.2s
[dev:server] server.listen - port: 4000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 6001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 7001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] GET /01/01/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 1011.006 ms
[dev:server] server.listen - port: 4000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 6001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 7001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] GET /01/01/solution?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 89.584 ms
[dev:server] GET /01/02/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber 200 - - 148.646 ms
[dev:server] server.listen - port: 4000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 6002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 7002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] GET /01/02/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 100.828 ms
[dev:server] server.listen - port: 4000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 6002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 7002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] (node:12368) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] (Use `node --trace-warnings ...` to show where the warning was created)
[dev:server] (node:12368) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] GET /01/02/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 74.748 ms
[dev:server] (node:12368) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 uncaughtException listeners added to [process]. Use emitter.setMaxListeners() to increase limit
[dev:server] server.listen - port: 4000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 6001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] server.listen - port: 7001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[dev:server] GET /01/01/problem?_data=routes%2F_app%2B%2F_exercises%2B%2F%24exerciseNumber_.%24stepNumber.%24type 200 - - 75.447 ms

globby with `\` return empty list

when I was testing setPlayground i've noticed that the lists srcFiles, destFiles and filesToDelete are always empty.

I was able to get a result only when I replaced all \ with / for the path that was passed to globby.

how ever i've noticed that if the current app in the playground was running the filesToDelete contains all the files in:
/build, /public and /node_modules/.cache/remix folders.
is it the desire result?

playground app start in new port each time

With the latest kcdshop 1.36.0
When calling SET TO PLAYGROUND while playground app is running the app starts in a new port each time.
see the following log from my terminal.

playground start in new port each time
> start
> kcdshop start

๐Ÿจ  Let's get learning!
Local:            http://localhost:5639
On Your Network:  http://10.100.102.21:5639
Press Ctrl+C to stop
[playground:4000]
[playground:4000] > dev
[playground:4000] > cross-env NODE_ENV=development run-p dev:*
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:server
[playground:4000] > tsx watch --clear-screen=false --ignore "app/**" --ignore "build/**" --ignore "node_modules/**" ./index.js
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:remix
[playground:4000] > cross-env PORT="" remix dev
[playground:4000]
[playground:4000]
[playground:4000] ๐Ÿš€  We have liftoff!
[playground:4000]
[playground:4000] Local:            http://localhost:4000
[playground:4000] On Your Network:  http://10.100.102.21:4000
[playground:4000] Press Ctrl+C to stop
[playground:4000]
[playground:4000] Loading environment variables from .env
[playground:4000]
[playground:4000] ๐Ÿ’ฟ Built in 3.6s
[playground:4000]
[playground:4000] HEAD / 200 - - 1780.743 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 2562.259 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 4638.000 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 1567.058 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 5364.723 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 4072.458 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 5895.709 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 3321.068 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 2567.434 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 5156.572 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 3103.653 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 4648.982 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 2340.124 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 3893.589 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 5717.470 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 3644.772 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 4428.679 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 332.660 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 302.935 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 271.728 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 237.418 ms
[playground:4000]
[playground:4000] HEAD / 200 - - 138.150 ms
[playground:4000]
[playground:4000] GET / 200 - - 61.523 ms
[playground:4000]
[playground:4000] GET / 200 - - 52.042 ms
[playground:4000]
[playground:4000] GET / 200 - - 88.912 ms
[playground:4000]
[playground:4000] exited (null)
[playground:4000]
[playground:4000] > dev
[playground:4000] > cross-env NODE_ENV=development run-p dev:*
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:server
[playground:4000] > tsx watch --clear-screen=false --ignore "app/**" --ignore "build/**" --ignore "node_modules/**" ./index.js
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:remix
[playground:4000] > cross-env PORT="" remix dev
[playground:4000]
[playground:4000]
[playground:4000] โš ๏ธ  Port 4000 is not available, using 4001 instead.
[playground:4000]
[playground:4000] ๐Ÿš€  We have liftoff!
[playground:4000]
[playground:4000] Local:            http://localhost:4001
[playground:4000] On Your Network:  http://10.100.102.21:4001
[playground:4000] Press Ctrl+C to stop
[playground:4000]
[playground:4000] Loading environment variables from .env
[playground:4000]
[playground:4000] ๐Ÿ’ฟ Built in 3.5s
[playground:4000]
[playground:4000] exited (null)
[playground:4000]
[playground:4000] > dev
[playground:4000] > cross-env NODE_ENV=development run-p dev:*
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:server
[playground:4000] > cross-env MOCKS=true tsx watch --clear-screen=false --ignore "app/**" --ignore "build/**" --ignore "node_modules/**" ./index.js
[playground:4000]
[playground:4000]
[playground:4000]
[playground:4000] > dev:remix
[playground:4000] > cross-env PORT="" remix dev
[playground:4000]
[playground:4000]
[playground:4000] ๐Ÿ”ถ Mock server installed
[playground:4000]
[playground:4000] Loading environment variables from .env
[playground:4000]
[playground:4000] โš ๏ธ  Port 4000 is not available, using 4002 instead.
[playground:4000]
[playground:4000] ๐Ÿš€  We have liftoff!
[playground:4000]
[playground:4000] Local:            http://localhost:4002
[playground:4000] On Your Network:  http://10.100.102.21:4002
[playground:4000] Press Ctrl+C to stop
[playground:4000]
[playground:4000] ๐Ÿ’ฟ Built in 3.7s
[playground:4000]

output from running netstat -aon in Windows 11 terminal, there are many:
TCP some_ip_address:4000 some_ip_address:64999 TIME_WAIT 0
(i've removed the real ips)

Active Connections on Windows
Active Connections

Proto  Local Address          Foreign Address        State           PID
TCP    ip_address:135            ip_address:0              LISTENING       1396
TCP    ip_address:445            ip_address:0              LISTENING       4
TCP    ip_address:1042           ip_address:0              LISTENING       17360
TCP    ip_address:1043           ip_address:0              LISTENING       17360
TCP    ip_address:2179           ip_address:0              LISTENING       2740
TCP    ip_address:3001           ip_address:0              LISTENING       6556
TCP    ip_address:3002           ip_address:0              LISTENING       7780
TCP    ip_address:3003           ip_address:0              LISTENING       5528
TCP    ip_address:4001           ip_address:0              LISTENING       18784
TCP    ip_address:4002           ip_address:0              LISTENING       4812
TCP    ip_address:5040           ip_address:0              LISTENING       7576
TCP    ip_address:5357           ip_address:0              LISTENING       4
TCP    ip_address:5639           ip_address:0              LISTENING       18676
TCP    ip_address:5985           ip_address:0              LISTENING       4
TCP    ip_address:7680           ip_address:0              LISTENING       4192
TCP    ip_address:9012           ip_address:0              LISTENING       13476
TCP    ip_address:9013           ip_address:0              LISTENING       13476
TCP    ip_address:9014           ip_address:0              LISTENING       9592
TCP    ip_address:47001          ip_address:0              LISTENING       4
TCP    ip_address:49664          ip_address:0              LISTENING       1140
TCP    ip_address:49665          ip_address:0              LISTENING       8
TCP    ip_address:49666          ip_address:0              LISTENING       1740
TCP    ip_address:49667          ip_address:0              LISTENING       3064
TCP    ip_address:49674          ip_address:0              LISTENING       4084
TCP    ip_address:49687          ip_address:0              LISTENING       1116
TCP    some_ip_address:139      ip_address:0              LISTENING       4
TCP    some_ip_address:4000     some_ip_address:64999    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65000    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65001    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65002    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65003    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65004    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65005    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65006    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65007    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65008    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65009    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65010    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65011    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65012    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65013    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65014    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65015    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65016    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65017    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65018    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65019    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65020    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65021    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65022    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65023    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65024    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65025    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65026    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65027    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65028    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65029    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65030    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65031    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65032    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65033    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65034    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65035    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65036    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65038    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65039    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65040    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65041    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65042    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65043    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65044    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65045    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65046    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65047    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65048    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65049    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65050    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65051    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65052    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65053    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65054    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65055    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65056    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65057    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65058    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65059    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65060    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65061    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65062    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65063    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65064    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65065    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65066    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65067    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65068    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65069    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65070    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65071    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65072    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65073    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65074    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65075    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65076    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65077    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65078    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65079    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65080    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65081    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65082    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65083    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65084    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65085    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65086    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65087    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65089    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65090    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65091    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65092    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65093    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65094    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65095    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65096    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65097    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65098    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65099    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65100    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65101    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65102    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65103    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65104    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65105    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65106    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65107    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65108    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65109    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65110    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65111    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65112    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65113    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65114    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65115    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65116    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65117    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65118    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65119    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65120    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65121    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65122    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65123    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65124    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65125    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65126    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65127    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65128    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65129    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65131    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65132    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65133    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65134    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65135    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65136    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65137    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65138    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65139    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65140    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65141    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65142    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65143    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65144    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65145    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65146    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65147    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65148    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65149    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65150    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65151    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65152    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65154    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65155    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65156    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65157    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65158    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65159    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65160    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65161    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65162    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65163    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65164    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65165    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65166    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65167    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65168    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65169    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65170    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65171    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65172    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65173    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65174    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65175    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65176    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65177    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65178    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65179    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65180    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65181    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65182    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65183    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65184    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65185    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65186    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65187    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65188    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65189    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65190    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65191    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65192    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65193    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65194    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65195    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65196    TIME_WAIT       0
TCP    some_ip_address:4000     some_ip_address:65197    TIME_WAIT       0
TCP    some_ip_address:59816    ip_address:8883    ESTABLISHED     2532
TCP    some_ip_address:59822    ip_address:443      ESTABLISHED     4396
TCP    some_ip_address:59922    ip_address:443      ESTABLISHED     11724
TCP    some_ip_address:61303    ip_address:80      LAST_ACK        7784
TCP    some_ip_address:62289    ip_address:443       ESTABLISHED     15072
TCP    some_ip_address:62300    ip_address:443      ESTABLISHED     15072
TCP    some_ip_address:62586    ip_address:443      TIME_WAIT       0
TCP    some_ip_address:63707    ip_address:443    ESTABLISHED     15072
TCP    some_ip_address:64355    ip_address:80       TIME_WAIT       0
TCP    some_ip_address:64362    ip_address:443      TIME_WAIT       0
TCP    some_ip_address:64374    ip_address:443      TIME_WAIT       0
TCP    some_ip_address:64377    ip_address:443      TIME_WAIT       0
TCP    some_ip_address:64385    ip_address:80       TIME_WAIT       0
TCP    some_ip_address:64386    ip_address:80       TIME_WAIT       0
TCP    some_ip_address:64393    ip_address:80       TIME_WAIT       0
TCP    some_ip_address:64452    ip_address:443        TIME_WAIT       0
TCP    some_ip_address:64467    ip_address:80          TIME_WAIT       0
TCP    some_ip_address:64488    ip_address:443      ESTABLISHED     15072
TCP    some_ip_address:65037    some_ip_address:4000     TIME_WAIT       0
TCP    some_ip_address:65088    some_ip_address:4000     TIME_WAIT       0
TCP    some_ip_address:65130    some_ip_address:4000     TIME_WAIT       0
TCP    some_ip_address:65153    some_ip_address:4000     TIME_WAIT       0
TCP    some_ip_address:65221    ip_address:443      ESTABLISHED     14456
TCP    some_ip_address:65244    ip_address:443      ESTABLISHED     11800
TCP    some_ip_address:65245    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65246    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65247    ip_address:443       ESTABLISHED     7784
TCP    some_ip_address:65252    ip_address:443     ESTABLISHED     7784
TCP    some_ip_address:65254    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65255    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65256    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65257    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65258    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65259    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65260    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65261    ip_address:443     ESTABLISHED     7784
TCP    some_ip_address:65262    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65263    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65264    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65265    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65266    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65267    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65268    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65269    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65270    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65271    ip_address:443      ESTABLISHED     7784
TCP    some_ip_address:65272    ip_address:443     ESTABLISHED     7784
TCP    some_ip_address:65273    some_ip_address:4000     SYN_SENT        6556
TCP    ip_address:1042         ip_address:59918        ESTABLISHED     17360
TCP    ip_address:1043         ip_address:59913        ESTABLISHED     17360
TCP    ip_address:13030        ip_address:0              LISTENING       4612
TCP    ip_address:13030        ip_address:49683        ESTABLISHED     4612
TCP    ip_address:22112        ip_address:0              LISTENING       4612
TCP    ip_address:28385        ip_address:0              LISTENING       4
TCP    ip_address:28390        ip_address:0              LISTENING       4
TCP    ip_address:49683        ip_address:13030        ESTABLISHED     4612
TCP    ip_address:59913        ip_address:1043         ESTABLISHED     13476
TCP    ip_address:59918        ip_address:1042         ESTABLISHED     11748
TCP    ip_address:59965        ip_address:59966        ESTABLISHED     15072
TCP    ip_address:59966        ip_address:59965        ESTABLISHED     15072
TCP    ip_address:59967        ip_address:59968        ESTABLISHED     10544
TCP    ip_address:59968        ip_address:59967        ESTABLISHED     10544
TCP    ip_address:139        ip_address:0              LISTENING       4
TCP    ip_address:139       ip_address:0              LISTENING       4
TCP    [::]:135               [::]:0                 LISTENING       1396
TCP    [::]:445               [::]:0                 LISTENING       4
TCP    [::]:1042              [::]:0                 LISTENING       17360
TCP    [::]:1043              [::]:0                 LISTENING       17360
TCP    [::]:2179              [::]:0                 LISTENING       2740
TCP    [::]:3001              [::]:0                 LISTENING       6556
TCP    [::]:3002              [::]:0                 LISTENING       7780
TCP    [::]:3003              [::]:0                 LISTENING       5528
TCP    [::]:4001              [::]:0                 LISTENING       18784
TCP    [::]:4002              [::]:0                 LISTENING       4812
TCP    [::]:5357              [::]:0                 LISTENING       4
TCP    [::]:5639              [::]:0                 LISTENING       18676
TCP    [::]:5985              [::]:0                 LISTENING       4
TCP    [::]:7680              [::]:0                 LISTENING       4192
TCP    [::]:9012              [::]:0                 LISTENING       13476
TCP    [::]:9013              [::]:0                 LISTENING       13476
TCP    [::]:9014              [::]:0                 LISTENING       9592
TCP    [::]:47001             [::]:0                 LISTENING       4
TCP    [::]:49664             [::]:0                 LISTENING       1140
TCP    [::]:49665             [::]:0                 LISTENING       8
TCP    [::]:49666             [::]:0                 LISTENING       1740
TCP    [::]:49667             [::]:0                 LISTENING       3064
TCP    [::]:49674             [::]:0                 LISTENING       4084
TCP    [::]:49687             [::]:0                 LISTENING       1116
TCP    [::1]:3001             [::1]:62654            ESTABLISHED     6556
TCP    [::1]:5639             [::1]:62587            ESTABLISHED     18676
TCP    [::1]:62587            [::1]:5639             ESTABLISHED     14396
TCP    [::1]:62654            [::1]:3001             ESTABLISHED     14396
UDP    ip_address:53             *:*                                    3212
UDP    ip_address:123            *:*                                    13652
UDP    ip_address:500            *:*                                    4404
UDP    ip_address:3702           *:*                                    2572
UDP    ip_address:3702           *:*                                    6044
UDP    ip_address:3702           *:*                                    6044
UDP    ip_address:3702           *:*                                    2572
UDP    ip_address:4500           *:*                                    4404
UDP    ip_address:5050           *:*                                    7576
UDP    ip_address:5353           *:*                                    2468
UDP    ip_address:5355           *:*                                    2468
UDP    ip_address:49157          *:*                                    2468
UDP    ip_address:50374          *:*                                    6044
UDP    ip_address:51120          *:*                                    2468
UDP    ip_address:52452          ip_address:53                        2532
UDP    ip_address:54475          *:*                                    3212
UDP    ip_address:54476          *:*                                    3212
UDP    ip_address:55132          *:*                                    2572
UDP    ip_address:62706          *:*                                    2468
UDP    ip_address:62894          *:*                                    2468
UDP    ip_address:64400          ip_address:53535                    2532
UDP    some_ip_address:137      *:*                                    4
UDP    some_ip_address:138      *:*                                    4
UDP    some_ip_address:1900     *:*                                    3412
UDP    some_ip_address:56739    *:*                                    3412
UDP    ip_address:1900         *:*                                    3412
UDP    ip_address:51123        *:*                                    3412
UDP    ip_address:52280        ip_address:52280                        4168
UDP    ip_address:57509        *:*                                    2532
UDP    ip_address:67         *:*                                    3212
UDP    ip_address:68         *:*                                    3212
UDP    ip_address:137        *:*                                    4
UDP    ip_address:138        *:*                                    4
UDP    ip_address:1900       *:*                                    3412
UDP    ip_address:51124      *:*                                    3412
UDP    ip_address:137       *:*                                    4
UDP    ip_address:138       *:*                                    4
UDP    ip_address:1900      *:*                                    3412
UDP    ip_address:56740     *:*                                    3412
UDP    [::]:123               *:*                                    13652
UDP    [::]:500               *:*                                    4404
UDP    [::]:3702              *:*                                    2572
UDP    [::]:3702              *:*                                    2572
UDP    [::]:3702              *:*                                    6044
UDP    [::]:3702              *:*                                    6044
UDP    [::]:4500              *:*                                    4404
UDP    [::]:5353              *:*                                    2468
UDP    [::]:5355              *:*                                    2468
UDP    [::]:49157             *:*                                    2468
UDP    [::]:50375             *:*                                    6044
UDP    [::]:51120             *:*                                    2468
UDP    [::]:54477             *:*                                    3212
UDP    [::]:55133             *:*                                    2572
UDP    [::]:62706             *:*                                    2468
UDP    [::]:62894             *:*                                    2468
UDP    [::1]:1900             *:*                                    3412
UDP    [::1]:56737            *:*                                    3412
UDP    [fe80::644f:4fc7:60cb:56bf%17]:1900  *:*                                    3412
UDP    [fe80::644f:4fc7:60cb:56bf%17]:56735  *:*                                    3412
UDP    [fe80::aa32:b179:a649:22fd%20]:1900  *:*                                    3412
UDP    [fe80::aa32:b179:a649:22fd%20]:56738  *:*                                    3412
UDP    [fe80::f70f:5436:7f28:95f8%13]:1900  *:*                                    3412
UDP    [fe80::f70f:5436:7f28:95f8%13]:56736  *:*                                    3412

The resource was preloaded using link preload but not used within a few seconds

I see this warning all the time for all the resources loaded from:

remix.run resource http://localhost:5639/build/_assets/tailwind-E25BMFDR.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.

https://github.com/epicweb-dev/kcdshop/blob/8f1503545f9c2d72f552c2cfaeb179d13fc0ef5e/packages/workshop-app/app/root.tsx#L24-L34

Do we need to add as="style"?

or maybe even change for all links

-		{ rel: 'stylesheet', href: '/neogrotesk-font.css' }
+		{ rel: 'preload', href: '/neogrotesk-font.css', as: 'style' } 

this is relevant mdn

Remix docs does not mention the as value in the examples for stylesheet, it only include as value in images examples.

Make "Set to Playground" faster

Sometimes it takes very long. Some ideas:

  1. Stop the server, do the set to playground, start the server. This would reduce issues with #93
  2. Delete the entire playground and copy the entire exercise. If I remember right we override existing files then delete the extra ones right now...

Change format a bit

One of the things I love about the workshop is that the launch-in-editor functionality makes it easy for people to get to the right file for the exercise.

One thing I don't like at all though is that they have to close the old file and open the new one, even if it's basically the same file.

An idea I had is what if we have a "playground" directory where we simply copy the contents of the problem app that we're working on so they always have the same files open, but we just keep the contents up-to-date with the exercise problem they're working on. It's possible the server wouldn't have to be stopped either (and if it crashed we could auto-restart it maybe?).

I think I'd like to explore doing this because I think it would make following the exercises even easier.

Restart the app automatically if it crashes

When clicking "Set to playground" sometimes the dev server crashes because who knows why ๐Ÿคทโ€โ™‚๏ธ

It would be cool if we auto-restart it when we detect it crashed.

We'd just want to make sure we don't get into a never-ending cycle of restarting the app. So maybe try once and if it fails, then give up?

CodeFile buttons

Is that what you want it to look like when all the buttons are visible?

buttons-new

TouchedFiles popup show error for a split second

I am working on 'Open all Files'

open-all-files

I have noticed that when the launch editor return an error it only appear in the popup for a split second
TouchedFiles

When clicking on a button in TouchedFiles' popup, LaunchEditor` (launch-editor.tsx) form renders 3 times, with these fetcher values:

  • state.submitting, data: undefined
  • state.loading,
   data: {
	  // i throw an error for testing
	  error: "testing error from launchEditor, with very very very long error message"
	  status: "error"
  }
  • state.idle, data: undefined
  1. I don't know what triggers the 3rd fetcher, but it clear the error
  2. do you want to change how the error looks in the popup? width. color, duration?
  3. since each InlineFile have its own form when one form is submitting in TouchedFiles all other forms in the popup rendering 3 times each, not only the one that was clicked

Fix home button on /finished

The home button looks funny:

image

image

Especially when you hover:

image image

I don't care what it looks like, but it should look nicer.

sidebar emoji is out of sync

I've noticed that sometimes app/routes/_app+/_exercises+/_layout.tsx runs before /set-playground action end.
In this cases playground emoji is out of sync.

I've tried to add shouldRevalidate in app/routes/_app+/_exercises+/_layout.tsx but it didn't helped, it appear that it is also triggered before the action ends

I did not find any reference in Remix to a way to asynchronous trigger loader after action from other route completed

Originally posted by @onemen in #36 (comment)

clear outdated file from .cache/compile-mdx

@kentcdodds

while working on #76 ,i have noticed that currently compileMdx function (compile-mdx.server.ts) create new file when an mdx file change but it never remove old files.

this is not a "big" issue, however my kcdshop/packages/example/node_modules/.cache/compile-mdx folder already have more then 500 files.

do you think it worth it to add code to remove outdated file to compileMdx, or we just need to remember to clear .cache every now and then.

I can work on it if you want

loader function calls getApps three time

improve MDX Components

ExercisePartRoute component get bloated with all the MDX component that are defined inline.

what do you think about move

<Mdx
	code={data.exerciseStepApp?.instructionsCode}
	components={{
		CodeFile,
		CodeFileNotification,
		DiffLink,
		InlineFile,
		LinkToApp,
		pre: PreWithButtons,
	}}
/>

with all the components list to a new file or to utils/mdx.tsx, then you can import ExerciseMdx and wrap it with useMemo if needed.

another improvement is to add remark plugin to validate inputs to Mdx components to prevents

- to <InlineFile file="app/routes/users_+/$username.tsx" /> so we can handle
+ to <InlineFile file="app/routes/users+/$username.tsx" /> so we can handle

Feedback from attendee

These are good ideas:

Few small suggestions:

  • I think the left sidebar is a bit too wide, especially when opening all the window, I would like the main content to be wider, so maybe set the left sidebar to a bit smaller, or maybe add the ability to change the width
  • Make the "01. STYLING WEB APPS | 02. ASSET IMPORTS | ๐Ÿ’ช PROBLEM" in above main content (I forgot the name lol) to be a navigation, so we can jump to other or main section
  • For me I kinda need a bit more attention to differentiate between normal text and code, especially in the dark mode

add real app to examples

If you add 'real' app, one form full-stack-foundations 07, It can help with testing and debugging

style glitch in Firefox

style glitch in Firefox
style_glitch

fix in $exerciseNumber_.$stepNumber.$type.tsx

-					<Tabs.List className="border-b border-gray-200">
+					<Tabs.List className="inline-flex border-b border-gray-200">
						{tabs.map(tab => {
							return (
								<Tabs.Trigger
									key={tab}
									value={tab}
									asChild
									className={clsx(
										'radix-state-active:bg-black radix-state-active:hover:bg-gray-700 radix-state-active:text-white radix-state-active:z-10 radix-state-inactive:hover:bg-gray-100 clip-path-button relative px-6 py-4 font-mono text-sm uppercase',
									)}
								>

MDX Component: <DiffLink />

Sometimes I have ๐Ÿงโ€โ™‚๏ธ Kellie the Co-worker do a little work between the previous exercise's solution and the current exercise's problem. I'd like to have a component that creates a link.

I can definitely copy a the link and just use that, but it looks like this: http://localhost:5639/02/01/problem?preview=diff&app1=exercises__sep__02.seed__sep__01.solution.init&app2=exercises__sep__02.seed__sep__02.problem.realistic

And that can change relatively easily (if I ever change the directory name). I'd like something a little more future-proof.

I think I'd like the <DiffLink app1={-1} app2={0} /> which would be "previous app vs current app"

And I'd also like support for something like: <DiffLink app1="02/01.solution" app2="02/02.problem" /> which would be "exercise 2, step 1 solution vs exercise 2 step 2 problem"

So it's just a shortcut.

Make app more responsive

Some folks may try to line up the app next to their editor so we want it to look nice at a narrow viewport.

rocket rental exercises not working inside workshop-app

the fix for this issue epicweb-dev/testing-web-apps#3 in here.

this is the fix in process-manager.server.ts runAppDev, maybe runAppTests need the same fix but i did not test it

	const appProcess = spawn('npm', ['run', 'dev'], {
		cwd: app.fullPath,
		shell: true,
+		stdio: ['inherit', 'pipe', 'pipe'],
		env: {
			...process.env,
			// TODO: support specifying the env
			NODE_ENV: 'development',
			// TODO: support specifying the port
			PORT: String(portNumber),
			APP_SERVER_PORT: String(portNumber),
			// let it pick a random port...
			REMIX_DEV_SERVER_WS_PORT: '',
		},
	})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.