Coder Social home page Coder Social logo

run's People

Contributors

angusmorton avatar artblue avatar mlrawlings avatar rturnq avatar tigt avatar vwong 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  avatar  avatar  avatar

run's Issues

Bug: <script> tags with relative path in `src` get the file contents placed in `src` on build

What's happening

A script tag with a relativesrc path like <script src="./test.js"></script>

gets compiled into <script src="[CONTENTS OF test.js]"></script>

NOTE: That does not happen with absolute paths: /js/script.js or full URLs

Expected Behavior

Marko does nothing and the script tag remains "as is". I was caught totally by surprise that Marko/Run was doing anything at all with something I considered "plain html".

Ok, nothing in Marko is plain HTML... but usually boundaries and side effects are clear. In this case, I don't know what's going on here.

How to reproduce:

  1. Create a new Run project

  2. Create a src/routes/test.js file

    export default "the script content";
  3. Add <script src="./test.js"></script> to +layout.marko

    image
  4. Build

This is easier to see when using the static adapter...

image

But it happens with the default adapter too

image

Optional Routes

Allow specifying routes which optionally match a segment.

Questions

What should the directory name syntax be?

  • URLPattern uses a trailing "?" which would be invalid on Windows
  • Remix uses wrapping parentheses: (optional)
  • SvelteKit uses double brackets: [[optional]]

Should we support optional static segments?

How do I change the dev server's port?

Marko runs on port 3000 by default, but (for reasons) my work machine has another service running on that port. Is there a config file that I've not yet created?

I went and looked at the Vite docs. I tried setting it via Vite config, but Marko then errored with Unable to resolve @marko/run options.

I've managed to get it working by running npm run dev -- --port 3123, but I don't want to have to type that every time.

"set-cookie" headers split at commas, breaking when "expires" is present

Specifying the "expires" attribute when setting a cookie, emits two "set-cookie" headers instead of one single header with the designated expiry. More specifically, a header like this:

set-cookie: flavor=chocolate%20chip; Expires=Wed, 23 Feb 2022 17:17:53 GMT

Gets converted into this:

set-cookie: flavor=chocolate%20chip; Expires=Wed
set-cookie: 23 Feb 2022 17:17:53 GMT

It looks like the culprit is https://github.com/marko-js/run/blob/main/packages/run/src/adapter/middleware.ts#L185

Improve asset names

The imported virtual paths for routable files are like /__marko-run__route__notes__$__comments.marko which causes the assets build by Rollup to be something like __marko-run__route__notes__$__comments.marko-8411b555.js.

We should at the very least strip off the __marko-run__route__ portion and potentially find a way to simplify names for deep paths.

Test file name shouldn't be used when generating types

@marko/[email protected]
@marko@5.26.1

Create a +middleware.test.ts file next to +middleware.ts.
After that, the generated .marko-run/routes.d.ts is changed like this:

- declare module "../src/routes/+middleware" {
+ declare module "../src/routes/+middleware.test" {
  namespace MarkoRun {
    export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
    export type Route = Run.Routes["/path"];
    export type Context = Run.MultiRouteContext<Route>;
    export type Handler = Run.HandlerLike<Route>;
    export const route: Run.HandlerTypeFn<Route>;
  }
}

The module name shouldn't change to .../+middleware.test

`run-adapter-static` also creates dynamic directories names as static folders

https://github.com/Jack5079/marko-slug-bug

<!-- +page.marko -->
<a href="/path">path</a>
<!-- $+page.marko -->
<h1>here be $</h1>

Results in

dist
├── $
│   └── index.html
├── 404
│   └── index.html
├── path
│   └── index.html
└── index.html

But it should be:

dist
├── 404
│   └── index.html
├── path
│   └── index.html
└── index.html

pnpm support

As of "@marko/run": "^0.1.6"
on build or dev commands

Errors

When using the default example

https://github.com/marko-js/run/tree/main/examples/netlify

{
  "name": "netlify-example",
  "version": "0.0.1",
  "type": "module",
  "scripts": {
    "build": "marko-run build",
    "dev": "marko-run",
    "start": "marko-run preview"
  },
  "devDependencies": {
    "@marko/compiler": "^5.22.6",
    "@marko/run": "^0.1.2",
    "@marko/run-adapter-netlify": "^0.1.0",
    "@marko/vite": "^2.3.7",
    "@types/compression": "^1.7.2",
    "@types/express": "^4.17.14",
    "@types/mocha": "^9.1.1",
    "@types/node": "^18.7.6",
    "prettier": "^2.7.1",
    "typescript": "^4.7.4",
    "vite": "^4.1.4"
  },
  "dependencies": {
    "marko": "^5.22.4"
  }
}
> marko-run build

[vite]: Rollup failed to resolve import ".pnpm/@[email protected]_w2m7nasiukek3x36vgnrkkf62e/node_modules/@marko/vite/dist/components/vite.marko" from "marko-run-netlify/__marko-run__special__500.marko?marko-server-entry".        
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
marko-run-netlify/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:46525
                throw new Error(`[vite]: Rollup failed to resolve import "${exporter}" from "${id}".\n` +
                      ^

Error: [vite]: Rollup failed to resolve import ".pnpm/@[email protected]_w2m7nasiukek3x36vgnrkkf62e/node_modules/@marko/vite/dist/components/vite.marko" from "marko-run-netlify/__marko-run__special__500.marko?marko-server-entry". 
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
    at viteWarn (marko-run-netlify/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:46525:23)
    at onRollupWarning (marko-run-netlify/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:46549:9)
    at onwarn (marko-run-netlify/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:46296:13)
    at Object.onwarn (marko-run-netlify/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:25280:13)
    at ModuleLoader.handleInvalidResolvedId (marko-run-netlify/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:23915:26)
    at marko-run-netlify/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:23875:26 {
  watchFiles: [
	....
  ]

When running `npm init marko -- -t basic` then adding vite
{
  "name": "marko-meta",
  "description": "The default Marko starter app",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "marko": "^5"
  },
  "devDependencies": {
    "@marko/run": "^0.1.6",
    "@marko/run-adapter-netlify": "^0.1.3",
    "vite": "^4.3.1"
  },
  "private": true,
  "scripts": {
    "build": "marko-run build",
    "dev": "marko-run",
    "start": "marko-run preview"
  }
}
marko-run

10:43:01 PM [vite] Error when evaluating SSR module /node_modules/.pnpm/[email protected]/node_modules/undici/index.js:
|- ReferenceError: require is not defined
    at eval (/node_modules/.pnpm/[email protected]/node_modules/undici/index.js:5:16)
    at instantiateModule (marko-meta/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:54351:15)

10:43:02 PM [vite] Error when evaluating SSR module @marko/run/adapter/middleware: failed to import "/node_modules/.pnpm/[email protected]/node_modules/undici/index.js"
|- ReferenceError: require is not defined
    at eval (/node_modules/.pnpm/[email protected]/node_modules/undici/index.js:5:16)
    at instantiateModule (marko-meta/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:54351:15)

node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

ReferenceError: require is not defined
    at eval (/node_modules/.pnpm/[email protected]/node_modules/undici/index.js:5:16)
    at instantiateModule (marko-meta/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-24daf00c.js:54351:15)

Node.js v18.9.0
 ELIFECYCLE  Command failed with exit code 1.

Handling metadata on special files 404/500 pages

I use the +layout.marko file for all pages with routes. Given that the +404.marko and +500.marko files are living as standalone files in the root of the folder I'm not able to pull any metadata into these pages as I can with normal routes.

My +layout.marko looks like this

<!DOCTYPE html>
<html dir='ltr' lang=($global.meta.pageLanguage)>
  <head>
    <meta charset='UTF-8'>
    ...
    <title>${$global.meta.pageTitle}</title>
  </head>
  <body>
    <${input.renderBody}/>
  </body>
</html>

Is there something I oversee?
From my point of view it would be nice to see the 404 and 500 pages live in special folders named _404 and _500 where files like +page.marko and +meta.* find a place.

Netlify Adapter: "This edge function has crashed" on certain pages receiving a lot of load

image

Deploying to Netlify using the Netlify adapter. This error appears on a page that has a +middleware to fetch data from an external API. The error only appears when I visit the page many times in quick succession. I can get this error consistently by refreshing the page many times in a row.

The confusing part is the +middleware in question is wrapped in a try/catch, and the catch is simply returning a response with a 500 error code (which is what I want to happen). The Netlify logs do not point to any specific line or anything that is causing the error so I am just assuming the error is originating from this +middleware. Below is the error that I see in the Netlify logs.

image

Unable to set multiple Set-Cookie headers

@marko/[email protected]
@marko@5.26.4

Details

In handler or middleware, I want to be able to append many Set-Cookie headers to the response:

  response.headers.append('Set-Cookie', 'alpha=alpha');
  response.headers.append('Set-Cookie', 'beta=beta');
  response.headers.append('Set-Cookie', 'charlie=charlie');

Expected Behavior

There are multiple Set-Cookie entries for all 3 cookies in the response header.

Actual Behavior

Only the last appended cookie shows up in the response headers ("charlie" in this example):

$ curl -v http://localhost:3000
*   Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< content-type: text/html;charset=UTF-8
< middleware: test1, test2
< set-cookie: charlie=charlie
< Date: Mon, 19 Jun 2023 07:03:27 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Transfer-Encoding: chunked

Strangely if I set all cookies in 1 Set-Cookie like this:

  response.headers.append('Set-Cookie', 'alpha=alpha,beta=beta,charlie=charlie');

Then the response headers are correct:

curl -v http://localhost:3000
*   Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< content-type: text/html;charset=UTF-8
< middleware: test1, test2
< set-cookie: alpha=alpha
< set-cookie: beta=beta
< set-cookie: charlie=charlie
< Date: Mon, 19 Jun 2023 07:05:17 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Transfer-Encoding: chunked
Additional Info

Steps to Reproduce

Setup a Marko Run project. Add this middleware:

import { NextFunction } from "@marko/run";

export default async function(context: MarkoRun.Context, next: NextFunction) {

  const response = await next();

  response.headers.append('Set-Cookie', 'alpha=alpha');
  response.headers.append('Set-Cookie', 'beta=beta');
  response.headers.append('Set-Cookie', 'charlie=charlie');

  response.headers.append('Middleware', 'test1')
  response.headers.append('Middleware', 'test2')
  console.log('Set-Cookie: ', response.headers.get('Set-Cookie')) // output: "Set-Cookie:  alpha=alpha, beta=beta, charlie=charlie"

  return response;
}

What's the proper way to access database/api?

Let's say I want to fetch products from the database.

that's the old way:

import express from "express";
import markoPlugin from "@marko/express";
import template from "./template.marko";

const app = express();
app.use(markoPlugin()); // Enables `res.marko(template, input)`

app.get("/", function (req, res) {
  const products = req.db.find(...)

  res.marko(template, {
    products
  });
});

app.listen(8080);

What's the proper way to do the same in marko/run?

I tried something like this in +handler.js

export const GET: MarkoRun.Handler = ({ request, platform }, next) => {
    platform.response.locals = {
        data: Math.random()
    }

    next()
};

and then in +page.marko
<h1>${$global.platform.response.locals.data}</h1>
but i'm not sure it's the best way.

routes.d.ts file path changes when a project is rebuilt between Windows and Mac OS

Details

  • This issue occurred as some developers on a project using Marko run are using Windows while others are running Mac OS
  • When a developer builds the project on Windows then commits and pushes the changes, it commits the file path for the src folder using Windows file path format
  • Then when the project is pulled down and built on a Mac, it triggers a change in the routes.d.ts file that needs to be committed
  • The file shouldn't be added to the .gitignore file, so this is an issue each time changes are committed and pulled down between developers on different devices

Expected Behavior

The expected behavior is that there shouldn't be a change on line 18 of the routes.d.ts file that requires a commit after running the build command due to a change in the src path when the project is regenerated on Mac OS or Windows.

Actual Behavior

  • If the project changes were committed on a computer running Windows, then the project is run on Mac OS, when the build command is run it will change the file path of the \src\ folder to /src/ on line 18 on the routes.d.ts file requiring the changes be committed.
  • Line 18 containing the file path issue: declare module "..\src\routes/" {

Windows file path:
windows-file-path
Mac OS file path:
mac-file-path

Possible Fix

Currently unclear on the possible fix, but we were looking at pathPrefix in the renderRouteTypeInfo function within run/src/vite/codegen/index.ts as a potential cause of this issue

Your Environment

  • Mac OS Ventura and Windows 10
"packageManager": "[email protected]",
 "dependencies": {
 "@manypkg/cli": "^0.20.0",
 "turbo": "^1.9.3"
 },

"dependencies": {
 "marko": "^5.25.11"
 },

 "devDependencies": {
 "@marko/run": "^0.1.9",

Steps to Reproduce

  1. Run the marko-run build command on Windows, commit and push changes
  2. Pull the repo down on Mac OS and run the build command
  3. The routes.d.ts file should show changes to the file path that need to be commited

Stack Trace

N/A

README mentions adding a tsconfig.json, but doesn't say what to put in it

If I add a tsconfig.json, I need to put roughly the following in it:

{
  "compilerOptions": {
    "strict": true,
    "lib": ["DOM", "DOM.Iterable", "ES6"],
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "exclude": ["node_modules", "dist"],
  "include": [".marko-run/routes.d.ts", "src"]
}

If I omit "lib", I'll get TS errors telling me that Promise isn't defined. (You can use something more aggressive than ES2019 if you're targeting modern browsers, but ES6 happens to be the minimum for Promise.)

If I omit either "esModuleInterop" or "resolveJsonModule", I see type errors in the example project, because the file generated in .marko-run/routes.d.ts isn't parsed by typescript, so none of my per-route types seem to be visible in VS Code.

I'm going to suggest adding an example tsconfig.json file?

edit: I thought these were needed but they actually aren't:

    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",

Error: Could not resolve "@marko/runtime-tags/debug/dom"

Version: v0.4.4

Details

npm run dev results in the following Error

✘ [ERROR] Could not resolve "@marko/runtime-tags/debug/dom"
node_modules/marko/src/runtime/helpers/tags-compat/dom-debug.mjs:1:23:
      1 │ import { compat } from "@marko/runtime-tags/debug/dom";
        ╵                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Attempting to visit local server will then produce:

[Error: ENOENT: no such file or directory, open '.../node_modules/@marko/run/.cache/explorer/data.json'
Rendered by getRoutes():
    at _marko_template$5._._marko_renderer.t (file:///.../node_modules/@marko/run-explorer/.app/index.mjs:506:3)
    at file:///.../node_modules/@marko/run-explorer/.app/index.mjs:694:5
    at _marko_template$6._._marko_renderer.t (file:///.../node_modules/@marko/run-explorer/.app/index.mjs:377:3)] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/.../node_modules/@marko/run/.cache/explorer/data.json'
}

Realize this is an issue further up the chain, but started here, so heads up.

Screenshots

Screenshot 2024-03-08 at 1 15 59 PM

Incorrect type generation with optional route parameters

In marko/[email protected], I have a route aaa.$aId.(,bbb.$bId).(,ccc.$cId)+page.marko in order to support the URL structure:

/aaa/$aid/ccc/$cid
/aaa/$aid/bbb/$bid/ccc/$cid
/aaa/$aid/bbb/$bid
/aaa/$aid

This results in 4 permutations generated in .marko-run/routes.d.ts below, which confuses the typechecking of $global.params. Deleting the 3 shorter permutations calms Typescript down.

declare module "../src/routes/aaa.$aid.(,bbb.$bid).(,ccc.$cid)+page.marko" {
  namespace MarkoRun {
    export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
    export type Route = Run.Routes["/aaa/:aid"];
    export type Context = Run.MultiRouteContext<Route> & Marko.Global;
    export type Handler = Run.HandlerLike<Route>;
    export const route: Run.HandlerTypeFn<Route>;
  }
}

declare module "../src/routes/aaa.$aid.(,bbb.$bid).(,ccc.$cid)+page.marko" {
  namespace MarkoRun {
    export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
    export type Route = Run.Routes["/aaa/:aid/bbb/:bid"];
    export type Context = Run.MultiRouteContext<Route> & Marko.Global;
    export type Handler = Run.HandlerLike<Route>;
    export const route: Run.HandlerTypeFn<Route>;
  }
}

declare module "../src/routes/aaa.$aid.(,bbb.$bid).(,ccc.$cid)+page.marko" {
  namespace MarkoRun {
    export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
    export type Route = Run.Routes["/aaa/:aid/bbb/:bid/ccc/:cid"];
    export type Context = Run.MultiRouteContext<Route> & Marko.Global;
    export type Handler = Run.HandlerLike<Route>;
    export const route: Run.HandlerTypeFn<Route>;
  }
}

declare module "../src/routes/aaa.$aid.(,bbb.$bid).(,ccc.$cid)+page.marko" {
  namespace MarkoRun {
    export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
    export type Route = Run.Routes["/aaa/:aid/ccc/:cid"];
    export type Context = Run.MultiRouteContext<Route> & Marko.Global;
    export type Handler = Run.HandlerLike<Route>;
    export const route: Run.HandlerTypeFn<Route>;
  }
}

Declaration merging breaks all Marko Run types

Versions:

  • @marko/run: 0.1.16
  • marko: 5.26.4"
  • typescript: 5.1.3

Simply create an empty .d.ts file like this:

declare module "@marko/run" {
}

Then Marko types are broken everywhere:

// In handler:
import { NextFunction } from "@marko/run"; // Module '"@marko/run"' has no exported member 'NextFunction'.

// in Marko file:
$ const foo = $global.url.searchParams; // '$global.url' is of type 'unknown'.

Generated types are broken, too:

image

Cascading meta to a sub-tree of routes

Currently meta files +meta.json needs to exist per +page.marko. We can't cascade the same meta file for an entire sub-tree of routes at once. Such a capability could be quite useful to set default meta, and only overriding/augmenting where it makes sense. Perhaps something like https://www.11ty.dev/docs/data-cascade/

Can we have such a feature?

Platform type should allow for extension

As discussed on Discord, wanted to document it here too

Currently you can extend the Context type as such:

declare module "@marko/run" {
  interface ContextExtensions {
    platform: WHATEVER
  }
}

When considering adding support for Cloudflare, it would be very helpful to be able to extend the Platform type in a similar way (ie maybe through a PlatformExtensions interface). Other adapters might also benefit, but particularly for Cloudflare this would allow for the end-user to specify their service binding types within their app code (as this would not be known ahead of time to the adapter code)

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.