@octanejs/vite-plugin 0.1.52 → 0.1.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # `@octanejs/vite-plugin`
2
+
3
+ Vite integration for Octane: `.tsrx` and eligible `.tsx` compilation for a
4
+ client-only SPA, plus optional routing, streaming SSR, hydration, production
5
+ client/server builds, and preview when an `octane.config.ts` declares routes.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add octane @octanejs/vite-plugin
11
+ pnpm add -D vite
12
+ ```
13
+
14
+ ```ts
15
+ // vite.config.ts
16
+ import { defineConfig } from 'vite';
17
+ import { octane } from '@octanejs/vite-plugin';
18
+
19
+ export default defineConfig({
20
+ plugins: [octane()],
21
+ });
22
+ ```
23
+
24
+ Without `octane.config.ts`, the plugin compiles Octane source and leaves Vite's
25
+ normal client-only SPA behavior intact, including its `import.meta.hot` HMR
26
+ dialect. Add an Octane config with routes to activate the full app layer. See
27
+ the [build tools guide](https://octanejs.dev/docs/build-tools) for the app
28
+ layer, adapters, and options.
29
+
30
+ ## Scoped CSS
31
+
32
+ Scoped `<style>` blocks compile to `injectStyle(hash, css)` calls — one per
33
+ style scope, in lexical order — emitted as module-level statements on the
34
+ client and inside the component body per request on the server, where the
35
+ render collects them into the response's `<style data-octane>` tags. A theme
36
+ (`export const theme = <style>…</style>`) is an ordinary module value, so
37
+ importing it injects its sheet ahead of the importer's own scopes. There is no
38
+ virtual CSS module and no CSS HMR path: editing a block re-evaluates the module
39
+ like any other source change. The plugin needs no CSS loader or extra
40
+ configuration for this.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/vite-plugin",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@ripple-ts/adapter": "^0.3.125",
50
- "@octanejs/app-core": "0.0.48"
50
+ "@octanejs/app-core": "0.0.50"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "octane": "^0.1.51 || ^0.2.0",
@@ -56,8 +56,7 @@
56
56
  "devDependencies": {
57
57
  "@types/node": "^24.13.3",
58
58
  "playwright": "^1.61.1",
59
- "type-fest": "^5.8.0",
60
59
  "vite": "^8.1.5",
61
- "octane": "0.2.0"
60
+ "octane": "0.2.7"
62
61
  }
63
62
  }
package/src/index.js CHANGED
@@ -221,7 +221,7 @@ function collect_hydrate_module_paths(config) {
221
221
  * it). An explicit `profile` (true or false) always takes precedence over
222
222
  * `devtools`.
223
223
  *
224
- * @param {{ hmr?: boolean, profile?: boolean, devtools?: boolean, strong?: boolean, nativeReads?: boolean, exclude?: string[], requireDirective?: boolean, renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions, cssModuleConstants?: import('octane/compiler/vite').OctaneVitePluginOptions['cssModuleConstants'] }} [inlineOptions]
224
+ * @param {{ hmr?: boolean, profile?: boolean, devtools?: boolean, strong?: boolean, textTypes?: import('octane/compiler/vite').OctaneVitePluginOptions['textTypes'], exclude?: string[], requireDirective?: boolean, renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions, cssModuleConstants?: import('octane/compiler/vite').OctaneVitePluginOptions['cssModuleConstants'] }} [inlineOptions]
225
225
  * @returns {Plugin[]}
226
226
  */
227
227
  export function octane(inlineOptions = {}) {
@@ -881,7 +881,7 @@ export function octane(inlineOptions = {}) {
881
881
  * hmr?: boolean,
882
882
  * profile?: boolean | 'auto',
883
883
  * strong?: boolean,
884
- * nativeReads?: boolean,
884
+ * textTypes?: import('octane/compiler/vite').OctaneVitePluginOptions['textTypes'],
885
885
  * exclude?: string[],
886
886
  * requireDirective?: boolean,
887
887
  * renderers?: import('@octanejs/app-core').ExperimentalRendererConfigOptions,
@@ -895,8 +895,7 @@ export function octane(inlineOptions = {}) {
895
895
  if (inlineOptions.profile !== undefined) compilerOptions.profile = inlineOptions.profile;
896
896
  else if (inlineOptions.devtools === true) compilerOptions.profile = 'auto';
897
897
  if (inlineOptions.strong !== undefined) compilerOptions.strong = inlineOptions.strong;
898
- if (inlineOptions.nativeReads !== undefined)
899
- compilerOptions.nativeReads = inlineOptions.nativeReads;
898
+ if (inlineOptions.textTypes !== undefined) compilerOptions.textTypes = inlineOptions.textTypes;
900
899
  if (inlineOptions.exclude !== undefined) compilerOptions.exclude = inlineOptions.exclude;
901
900
  if (inlineOptions.requireDirective !== undefined) {
902
901
  compilerOptions.requireDirective = inlineOptions.requireDirective;
@@ -912,11 +911,7 @@ export function octane(inlineOptions = {}) {
912
911
  const projectRoot = userConfig.root ? path.resolve(userConfig.root) : process.cwd();
913
912
  // Both inline compiler options override app config independently. Preserve
914
913
  // the synchronous path when neither needs to read octane.config.ts.
915
- if (
916
- inlineOptions.renderers !== undefined &&
917
- inlineOptions.strong !== undefined &&
918
- inlineOptions.nativeReads !== undefined
919
- ) {
914
+ if (inlineOptions.renderers !== undefined && inlineOptions.strong !== undefined) {
920
915
  compilerConfigWatchFiles.clear();
921
916
  return compilerConfigHook.call(this, userConfig, env);
922
917
  }
@@ -925,7 +920,6 @@ export function octane(inlineOptions = {}) {
925
920
  if (!octaneConfigExists(projectRoot)) {
926
921
  if (inlineOptions.renderers === undefined) delete compilerOptions.renderers;
927
922
  if (inlineOptions.strong === undefined) delete compilerOptions.strong;
928
- if (inlineOptions.nativeReads === undefined) delete compilerOptions.nativeReads;
929
923
  compilerConfigWatchFiles.clear();
930
924
  // A new app config can introduce Strong mode or renderer rules.
931
925
  compilerConfigWatchFiles.add(path.resolve(configPath));
@@ -940,9 +934,6 @@ export function octane(inlineOptions = {}) {
940
934
  if (inlineOptions.strong === undefined) {
941
935
  compilerOptions.strong = config.config.compiler.strong;
942
936
  }
943
- if (inlineOptions.nativeReads === undefined) {
944
- compilerOptions.nativeReads = config.config.compiler.nativeReads;
945
- }
946
937
  compilerConfigWatchFiles.clear();
947
938
  for (const file of [...config.dependencies, ...config.missingDependencies]) {
948
939
  compilerConfigWatchFiles.add(path.resolve(file));
@@ -133,7 +133,8 @@ function viteConfigModuleRunner(vite) {
133
133
  function visit(module) {
134
134
  if (seen.has(module)) return;
135
135
  seen.add(module);
136
- if (module.file) dependencies.add(module.file);
136
+ // Virtual module IDs are not filesystem paths and cannot be watched.
137
+ if (module.file && !module.file.includes('\0')) dependencies.add(module.file);
137
138
  for (const imported of module.importedModules) visit(imported);
138
139
  }
139
140
  for (const root of roots) visit(root);
package/types/index.d.ts CHANGED
@@ -17,8 +17,8 @@ export interface OctanePluginOptions {
17
17
  profile?: boolean;
18
18
  /** Assert Strong mode's pure immutable-snapshot render contract for app code. */
19
19
  strong?: boolean;
20
- /** Experimental native signal reads in DOM client/server render scopes. */
21
- nativeReads?: boolean;
20
+ /** TypeScript-backed child-text inference in one-shot production builds. */
21
+ textTypes?: OctaneVitePluginOptions['textTypes'];
22
22
  /**
23
23
  * Path fragments the compiler's plain `.ts`/`.js` hook-slotting pass must
24
24
  * skip. Prefer package manifest `octane.hookSlots.manual` declarations.