Code Monkey home page Code Monkey logo

arel's Introduction

NOTICE

Now unused. See florimondmanca/www.


Personal

Build Status Angular DigitalOcean

This is the repository for the frontend application powering my personal blog.

For the backend API, see personal-api.

Install

Install Angular CLI:

$ npm install -g @angular/cli

Install the dependencies:

$ npm install

Quickstart

Create an environment file called .env (it will be excluded from version control) at the project root, containing the following variables:

  • API_KEY: a valid API key created via the backend admin site.
  • BACKEND_URL: the URL to the backend root (without trailing slash).

For example:

# .env
API_KEY=myapikey
BACKEND_URL=http://localhost:8000

Generate your development environment file:

$ npm run config -- --env=dev

Start the development server, which will run on http://localhost:4200/:

$ ng serve -c dev

Using server-side rendering

Server side rendering is implemented using Angular Universal.

Server-side rendering allows to send fully-rendered HTML pages to clients, instead of sending them a blank page and letting Angular fill it in the browser. This reduces the "first meaningful paint" time, helps with referencing and allows integration with social media.

To use the server-rendered app, you must first create a build of the app:

$ npm run build:dev

Note: in production, use npm run build instead to create a production-optimized build.

Then start the server-rendered app (an Express server):

$ npm run serve:ssr

Scripts

See package.json for the available NPM scripts.

CI/CD

TravisCI is configured on this repo and generates a production build on every push to a branch.

arel's People

Contributors

bradleykirton avatar florimondmanca avatar kludex avatar notsosmartdev avatar tboerstad 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

arel's Issues

Keep page Y scroll location when reloading

Currently when arel triggers a page reload, the page scrolls back to the top. In tight edit loops where we're comparing changes in the middle of the page, this can become tiresome.

Let's store the client Y scroll position before reloading and restore it after reload. We can probably use localStorage to achieve this.

HotReload should be an ASGI app

HotReload should be an actual ASGI app that we can mount onto an app, instead of having to manually register its WebSocketEndpoint:

import arel
from starlette.applications import Starlette
from starlette.routing import Mount

hotreload = arel.HotReload("./path/to/files")

app = Starlette(
    routes=[Mount("/hot-reload", hotreload, name="hot-reload")],
    on_startup=[hotreload.startup],
    on_shutdown=[hot_reaload.shutdown],
)

Then the WebSocketEndpoint could be provided internally at /, so that the route name stays hot-reload, i.e. whatever is given to Mount.

Wouldn't remove the need to register event handlers (most frameworks don't support lifespan on sub-apps, eg see encode/starlette#649), but at least it's a bit less framework-specific surface.

Not able to register multiple hot reload scripts

Assuming I have two arel.HotReload instances registered (one for a "content" directory, one for the "templates" directory):

{% if settings.DEBUG %}
  {{ content_reload.script(url_for('content-reload')) | safe }}
  {{ templates_reload.script(url_for('templates-reload')) | safe }}
{% endif %}

This triggers the following error once the page loads in the browser:

SyntaxError: redeclaration of const ws

Ideally we should only have to register a single script anyway โ€” but this requires addressing the "watch multiple dirs and maybe do different on_reload actions for each" use case a bit more.

Anyway, logging this here for visibility.

Reloading additional external pages?

Prompted by Kludex/uvicorn-extensions#15 (comment)

Problem description

Currently, arel can be used by injecting a {{ script }} in the user's app HTML.

But this is not workable on HTML the user can't control.

For example, the user may want their FastAPI docs page to reload when their Uvicorn server restarts, as the OpenAPI schema may have changed due to

On the other hand, it's possible they wouldn't want that. Maybe they're busy testing things in the Swagger UI and, while they're doing edits in the their Python source code, they may not want to lose what they've done in the UI (e.g. authentication credentials).

How should we address these use cases?

Suggested solution

TODO

Possible alternatives

  • Replace the manual {{ script }} thing with automatic injection on HTML pages.
    • This could be done by allowing users to register an ASGI middleware that detects HTML responses, and injects the script before the </body> closing tag. When running in DEBUG mode, users would turn this behavior off by not including the middleware.
    • This is somewhat similar to what django-debug-toolbar or fastapi-debug-toolbar do to inject their client-side toolbar JS on all pages -- including Swagger UI for fastapi-debug-toolbar (since that's an HTML page as well).

Callbacks should get passed the changeset

It appears that, in _on_changes, the callbacks and notify are called without passing the changeset.

I'm interested in handlers that know what changed, then do the least amount of work needed. Using the bundled example as a scenario, instead of regenerating the entire set of pages, only updating one.

Starlette DeprecationWarning: run_until_first_complete is deprecated and will be removed in a future version.

We get a warning when running tests:

tests/test_example.py::test_example
  /Users/florimond/Developer/florimondmanca-projects/arel/venv/lib/python3.11/site-packages/starlette/concurrency.py:19: DeprecationWarning: run_until_first_complete is deprecated and will be removed in a future version.
    warnings.warn(

As per encode/starlette#1443, the alternative seems to be to use anyio:

async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None:
    async def run(handler, kwargs):
        await handler(**kwargs)
        tg.cancel_scope.cancel()

    async with anyio.create_task_group() as tg:
        for handler, kwargs in args:
            tg.start_soon(run, handler, kwargs)

We only support asyncio for now (see usage of asyncio.Event()). So as a first step, we could resolve the warning by bringing back what Starlette was doing before anyio...

async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None:
    tasks = [create_task(handler(**kwargs)) for handler, kwargs in args]
    (done, pending) = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
    [task.cancel() for task in pending]
    [task.result() for task in done]

Example app should default to debug=True

The example doesn't work out-of-the-box, as changes aren't reloaded. IMO, this line in examples/server/settings.py should default to True:

DEBUG = config("DEBUG", cast=bool, default=False)

As background, I was working very slowly on writing just this very thing: a reloader more sophisticated/performant than livereload, based on the watchgod changeset approach, in Starlette. But learning asyncio was really slowing me down. Thanks!

Issues with Pytest and Arel Middleware

I currently have big issues with running the middleware version of arel and pytest together, i have some Pydantic settings loaded that block arel from being loaded unless an enviroment variable is set (and it also has a default value). Arel loads either way and i dont know how to fix it.

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.