{"_id":"@doodesch/sideload-vite","_rev":"2-e5e7d07f1a4137b18eb4390d00399383","name":"@doodesch/sideload-vite","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@doodesch/sideload-vite","version":"1.0.0","keywords":["sideload","schedule-i","melonloader","vite-plugin","modding"],"author":{"name":"DooDesch"},"license":"MIT","_id":"@doodesch/sideload-vite@1.0.0","maintainers":[{"name":"doodesch","email":"doodesch@gmail.com"}],"homepage":"https://github.com/DooDesch-Mods/ScheduleOne-Sideload#readme","bugs":{"url":"https://support.doodesch.de/sideload"},"dist":{"shasum":"b4251b5092ce0a6206fc153d44160c6e6f7222b6","tarball":"https://registry.npmjs.org/@doodesch/sideload-vite/-/sideload-vite-1.0.0.tgz","fileCount":5,"integrity":"sha512-UO3xU/nLvGYto/z7fo2e7YI31zAs+CVa+LKfLAfWTBawzLl4u8k9q4rQWwCCWb0LzPe9V9qBlKxZc3/sPhFTSw==","signatures":[{"sig":"MEUCIC2WdgCbssJAiz+lxpxovLHgzXRY1/gVn2OIiLEG24iwAiEA/H/KQazCrQXJ/zrjHcs07AhWxnPnJ/uDtkThwDwHSpc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44758},"main":"index.js","type":"module","exports":{".":"./index.js","./types":"./types/sideload.d.ts","./lowering":"./lowering.js"},"gitHead":"f6d20159dc8cb61233813d73a9bd67a1b26f0174","scripts":{"gen":"node gen-types.mjs","check":"node gen-types.mjs --check && tsc -p example && node example/verify.mjs","types":"tsc -p example","example":"cd example && vite build"},"_npmUser":{"name":"doodesch","email":"doodesch@gmail.com"},"repository":{"url":"git+https://github.com/DooDesch-Mods/ScheduleOne-Sideload.git","type":"git","directory":"tools/sideload-vite"},"_npmVersion":"11.4.2","description":"Build a Sideload app with Vite: React or plain TypeScript in, one bundle the engine reads out.","directories":{},"_nodeVersion":"24.3.0","dependencies":{"lightningcss":"1.33.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","typescript":"^5.6.0"},"peerDependencies":{"vite":">=5"},"_npmOperationalInternal":{"tmp":"tmp/sideload-vite_1.0.0_1786322237522_0.5325443487268418","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@doodesch/sideload-vite","version":"1.0.1","type":"module","description":"Build a Sideload app with Vite: React or plain TypeScript in, one bundle the engine reads out.","license":"MIT","main":"index.js","exports":{".":"./index.js","./lowering":"./lowering.js","./types":"./types/sideload.d.ts"},"scripts":{"gen":"node gen-types.mjs","check":"tsc -p example && node example/verify.mjs","example":"cd example && vite build","types":"tsc -p example","types:check":"node gen-types.mjs --check"},"peerDependencies":{"vite":">=5"},"dependencies":{"lightningcss":"1.33.0"},"devDependencies":{"typescript":"^5.6.0","vite":"^6.0.0"},"keywords":["sideload","schedule-i","melonloader","vite-plugin","modding"],"homepage":"https://github.com/DooDesch-Mods/ScheduleOne-Sideload#readme","bugs":{"url":"https://support.doodesch.de/sideload"},"repository":{"type":"git","url":"git+https://github.com/DooDesch-Mods/ScheduleOne-Sideload.git","directory":"tools/sideload-vite"},"author":{"name":"DooDesch"},"publishConfig":{"access":"public"},"gitHead":"4ecceb93cfae9cadbf9a75773f413f312cde24ea","_id":"@doodesch/sideload-vite@1.0.1","_nodeVersion":"22.23.1","_npmVersion":"12.0.2","dist":{"integrity":"sha512-fkBNhQQ2LYijelP/c4EKSfpT+kZu2xYGh/vI3ahRKXQrqeXH0Rw8PoWv1odfS9vgcx/HoMGRu3MLWF3rw2rJNQ==","shasum":"39acf126064d01c1e2c0e67d89bbdcdd215354e7","tarball":"https://registry.npmjs.org/@doodesch/sideload-vite/-/sideload-vite-1.0.1.tgz","fileCount":5,"unpackedSize":43884,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@doodesch%2fsideload-vite@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCoz52SRc4YJ9N2CQnGoe381zKbv0Nwtr0N7ru6y/aXywIgSdxmqszxzwwWswQPN8zm1q4GueJUFvHiyJ+H7R6YLxY="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:38f3b4b6-e8db-473f-ac78-618d7588855c"}},"directories":{},"maintainers":[{"name":"doodesch","email":"doodesch@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sideload-vite_1.0.1_1786324048980_0.3654498994058195"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-10T00:37:17.250Z","modified":"2026-08-10T01:07:29.488Z","1.0.0":"2026-08-10T00:37:17.661Z","1.0.1":"2026-08-10T01:07:29.127Z"},"bugs":{"url":"https://support.doodesch.de/sideload"},"author":{"name":"DooDesch"},"license":"MIT","homepage":"https://github.com/DooDesch-Mods/ScheduleOne-Sideload#readme","keywords":["sideload","schedule-i","melonloader","vite-plugin","modding"],"repository":{"type":"git","url":"git+https://github.com/DooDesch-Mods/ScheduleOne-Sideload.git","directory":"tools/sideload-vite"},"description":"Build a Sideload app with Vite: React or plain TypeScript in, one bundle the engine reads out.","maintainers":[{"name":"doodesch","email":"doodesch@gmail.com"}],"readme":"# @doodesch/sideload-vite\n\n```\nnpm install -D @doodesch/sideload-vite\n```\n\n`examples/showcase` in this repository deliberately does NOT do that: it reaches the plugin through\n`file:../../tools/sideload-vite`, so it builds against the code in the tree rather than the last release. That\none costs an extra `npm install` inside this folder, because Node resolves this package's own `lightningcss`\nfrom here rather than from the consumer's tree.\n\n\nBuild a Sideload app with Vite. React or plain TypeScript in, one bundle the engine reads out.\n\n```js\nimport { defineConfig } from 'vite';\nimport { sideload } from '@doodesch/sideload-vite';\n\nexport default defineConfig({\n  plugins: [sideload({ appId: 'myapp', deploy: 'F:/games/Schedule I/Mods' })],\n});\n```\n\n```\nvite build --watch\n```\n\nThat is the loop: save a `.ts` file, and about 250 ms later the page has rebuilt in the running game. No\ngame restart, no mod rebuild.\n\n## What it decides for you\n\nSideload loads a **bundle**, not a web page: one `index.html` fragment, one `app.css`, one `app.js`, side\nby side under fixed names. A default Vite build produces none of that, and every difference fails\nsilently - a page that simply does not run, with nothing in the log.\n\n| Vite's default | Why it breaks here | What the plugin does |\n|---|---|---|\n| `<script type=\"module\">` | there is no module loader | `format: 'iife'`, plain `<script src>` |\n| hashed filenames | nothing resolves `app.a1b2c3.js` | `app.js`, `app.css` |\n| a full HTML document | the engine builds the head itself | emits the body's contents |\n| CSS split per chunk | files nothing references | one stylesheet |\n| `modulepreload` links | a request the engine never makes | removed |\n| minified output | every script error's `file:line` becomes useless | off |\n| assets inlined as data URIs | inflates `app.js` for no gain | files, resolved against the bundle |\n\n## What it rewrites\n\nEverything a web toolchain says that the engine cannot read, in the spelling it can. This is the same\npass the Tailwind preset uses, and it is what takes a Tailwind v4 build from **48 % to 87.6 %** of its\ndeclarations arriving.\n\nLogical properties become physical, `oklch()` becomes a colour the engine parses, media range syntax\nbecomes `min-width`, nesting is flattened, `display: flex` says its direction out loud (it starts a row\nin CSS and a column here), and Tailwind's five-slot `box-shadow` chain collapses to the one layer that\ngets drawn.\n\n`lower: 'prune'` additionally deletes declarations the engine provably cannot render. It changes no\npixel - but it also removes the engine's report about them, so it is off by default. `lower: false`\nleaves the stylesheet alone.\n\n## TypeScript\n\nNothing to set up: Vite compiles it. What matters is `types/sideload.d.ts`, which types the page API from\n`Sideload/Script/DomApi.cs` - so the editor knows `document` here has six members and an element is not a\nbrowser `Element`.\n\n```ts\n/// <reference types=\"@doodesch/sideload-vite/types\" />\n\ndocument.getElementById('go')?.addEventListener('click', () => {\n  const said: string = s1.call('app.hello');\n});\n\ndocument.head            // Property 'head' does not exist\nel.closest('.card')      // Property 'closest' does not exist\nwindow.alert('x')        // Cannot find name 'window'\n```\n\nThose last three are the point. Each one works perfectly in a browser and does nothing at all in the\ngame, with no error on either side - so the compiler is the only place they can be caught early.\n\nThe declarations are generated, never hand-edited:\n\n```\nnode gen-types.mjs           rewrite them\nnode gen-types.mjs --check   exit 2 if they are stale\n```\n\n## Options\n\n| Option | Default | What it is |\n|---|---|---|\n| `appId` | required | The id Sideload registers, and the folder name under `Mods/`. |\n| `deploy` | none | A `Mods/` folder to copy the bundle into after every build. |\n| `lower` | `'rewrite'` | `'lightning'`, `'rewrite'`, `'prune'`, or `false`. |\n| `gate` | none | Path to `Workspace/Tests/Sideload.Tests` - fails the build on new unusable CSS. |\n| `baseline` | none | The losses already accepted, for the gate. |\n| `target` | `'es2020'` | esbuild target. The engine reads ES2015 through ES2024 and transpiles nothing. |\n\n### The gate\n\n```js\nsideload({\n  appId: 'myapp',\n  gate: '../../Workspace/Tests/Sideload.Tests',\n  baseline: './css.baseline',\n})\n```\n\nIt parses and cascades with the **engine's own code**, so it cannot drift from what the game does. Exit 2\nmeans it named something the baseline does not already accept, and the build stops.\n\nRun it once with `--update-baseline` before turning it on. Every app loses something today, and a check\nthat fails on its first run gets removed rather than obeyed. The baseline is the file you then delete\nlines from.\n\n## Does it still work\n\n```\nnpm install\nnpm run check      # the types are current, and the example builds to the right shape\n```\n\n`example/verify.mjs` builds the example app and asserts the shape of what came out - no hashed name, no\nmodule script, the lowering applied - and then hands the result to the engine's own reporter and requires\nit to say nothing. Nineteen checks; every one of them is a bug that is silent without it.\n","readmeFilename":"README.md"}