## Summary
Resolves all 38 SonarCloud **typescript:S9383** findings ("Promises must
be awaited, end with a call to .catch, end with a call to .then with a
rejection handler or be explicitly marked as ignored with the `void`
operator") in `frontend/apps/artcraft/app`, across 19 files. They are:
- startup calls in `index.tsx`, such as `SyncStorytellerApiConfig()` and
`persistLogin()`
- polling in `useActiveJobs`, `useBackgroundLoadingMedia`,
`signals/activeJobs.ts` and `signals/authentication/fetchers.ts`
- listener cleanups (`unlisten*.then(f => f())`) in `TaskQueue` and
`useDesktopGenerationFeed`
- UI handlers that start uploads or renames, such as
`ImageTo3DExperience`, `UploadFilesMedia`, `SceneTitleInput`,
`ProfileDropdown` and `DesktopGenerationGallery`
- async IIFEs in `useDesktopUsername`, `TaskQueue` and
`BaseImageSelector`
This is part 2 of 3 for artcraft's 157 S9383 findings. Part 1 (Tauri
libraries) is #2805. Part 3 (`libs/components`) is #2807.
Several of these files are also changed by open PRs for unrelated
reasons, for example #2519, #2520, #2615 and #2064. Each change here
inserts one word at the start of a statement, so a rebase either way is
trivial.
## Approach
This ports the approach of storytold/artcraft-services#179, which fixes
the same rule in artcraft-services. **#179 is still open and unmerged.**
This PR follows its approach and does not depend on it.
- Each flagged expression is a fire-and-forget promise: a listener
`setup()`, an `unlisten.then(f => f())` cleanup, a loader called from an
effect, an upload kicked off from a handler, or an async IIFE. Prefixing
it with `void` marks the ignored promise explicitly, which is the fix
the rule documents.
- It deliberately does not add `.catch()` everywhere. These call sites
already handle failures inside the async function or surface them
through their own state, and empty handlers would hide errors.
- Async IIFEs become `void (async () => …)()`. `if (cond) call()`
becomes `if (cond) void call()`.
- There is no behaviour change. `void` only discards the promise value,
which was already being discarded.
Each insertion is placed at the exact `textRange` start offset of the
SonarCloud finding, with no other edits.
## Testing
- Each changed file parses with `esbuild <file>`, using the same check
as #179.
- I parsed each changed file with the TypeScript 5.9 compiler API
(`createSourceFile`). That found no parse errors, and every inserted
`void` is either a whole expression statement or an arrow-function body
applied to a call, never part of a larger expression.
- `frontend/.eslintrc.json` has no `no-void` rule.
- I did not run the full Nx type-check, lint or test targets, because
`frontend/node_modules` is not installed in my environment. Please rely
on CI.
- No tests are added. Discarding an already-discarded promise value is
not observable, so no test can fail before this change and pass after
it.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- coderabbit-ai-generated:v1 -->
## Summary by CodeRabbit
* **Chores**
* Updated background tasks across uploads, sign-in, polling, scene
editing, and other app workflows to handle asynchronous operations
consistently.
* Existing workflows and their success and error handling remain
unchanged; no user-facing behavior changes are expected.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Storyteller GGF
Coding Rules and Styles
Short Style Guide TS React and Engine:
No use of lets
No basic for loop operators.
Use the collection operators and array operators.
React Side / No modules over 200 lines. ( loose rule )
Don't do:
if (condition) return;
Do:
if (condition) {
return;
}
No use of any type.
If you can use chat gpt to create the interface.
Branches
-
main- The main branch is the production source of truth.Changes to main will automatically build, but will not auto-deploy to production. You'll have to promote changes to production using the Netlify control panel.
Merge your code to main frequently. If you have to have a long-lived set of changes, ask yourself whether it might be better to feature flag your code off and land it to main rather than fight rebasing against the whole team.
-
studio-staging- The staging auto-deploy branch.You do not ever need to interact with this branch. Changes to
mainwill automatically be pushed tostudio-stagingand auto-deployed to https://studio-staging.studio.storyteller.ai . You can test changes that have landed inmainhere before promoting them to production. -
studio-testing- The testing branch.
Anyone can push their changes to this branch for testing in a production-like environment. Since it is built and hosted on https://studio-testing.studio.storyteller.ai , you won't face CORS issues, same-site cookie issues, or have to use a local development proxy. (This doesn't obviate the need for a development proxy for fast development iteration, but is a fantastic way to test your changes in a "production-like" environment.)
Force push to this branch by using git push -f origin studio-testing
API Docs
Server API docs live here: https://storyteller-docs.netlify.app/
Local Testing & Development
Apple Silicon package installation issues
Installation of some dependencies via npm may fail on M-series macs (like node-canvas) and may require additional setup including python3 and some brew dependencies:
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman python-setuptools
Set up .env and the Proxy Server
Copy & paste the env settings from .env-local-proxy to .env, (if the file .env do not exist, simply create one at the root of this project's folder beside the other env settings files).
The settings from .env-local-proxy directs all requests to localhost:3000, this will relieve us from having to deal with CORS between various services.
Then, start the proxy server in the folder /proxy. Before running the proxy for the first time, run:
npm i
To start the proxy run:
npm run dev
If the proxy fails, make sure your node version is 18.18. If you need to change the node version
run npm rebuild once before re-running npm run dev
Run the Code Locally
To setup and run this project's code locally:
npm install
npm run dev
PostHog
PostHog is installed and working. To create a feature flag go to https://us.posthog.com/project/75284/feature_flags Add the feature flag for all users.
To check the feature flag in the app use code similar to this
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureflag";
import { FeatureFlags } from "~/enums";
const Component = () => {
const flag = usePosthogFeatureFlag(FeaturesFlags.FLAG_NAME);
// if flag is true, the feature shoud be executed & showed;
// if flag is false, the feature should be disabled & hid;
// for example
return(
<>
{flag && <ComponentThatDependsOnTheFlag />}
</>
);
};
Other Documentation
Here is the Swagger documentation for the backend endpoints
This project uses Remix for routing and Tailwind for styling:
On Netlify, we use functions: